Пятница, 17.05.2024, 07:00
Главная
Приветствую Вас, Гость
Статистика



Онлайн лист

Онлайн всего: 1
Гостей: 1
Пользователей: 0



Реклама



Главная » Статьи » Микроконтроллеры

Наверх


Atmega16 бегущий огонек
Дело было вечером. Захотелось мне поиграться со светодиодами. В результате решил поделится, с теми кто пока еще не знает, как управлять светодиодами микроконтроллером.

И так что нам нужно, микроконтроллер ( я использовал Atmega16), светодиоды ( в моем случае в SMD корпусах) и резисторы. Все эти детали собираем по схеме:

Схема бегущего огонька на микроконтроллере

Схема собрана, так как я собирал все по быстренькому и лазерного принтера у меня нет, расчертил плату под светодиоды маркером и вытравил и все спаял. Можно собирать на макетке, можно сделать нормальную плату, дела вкуса и предпочтений и сейчас это не критично.

Что из себя представляет "бегущий огонек" - зажигание и затухание светодиодов в определенной последовательности. Сделать это можно разными способами.
Самый простой способ, который первым приходит в голову:


 PORTA.0 = 1; // включаем светодиод, подключенный к ножке PA0 
pause; // ждем заданные промежуток времени
PORTA.0 = 0; // выключаем светодиод
pause; // снова ждем, прежде чем включить следующий


Повторяем это для каждого светодиода.
Полный код программы для нашей схемы будет иметь следующий вид:


#include <mega16.h> 
#include <delay.h>
#define pause delay_ms(80) // задержку подменяем своей командой чтобы было проще менять ее длину

void avr_init(void)
{
PORTA=0x00;
DDRA=0xFF;
PORTB=0x00;
DDRB=0x00;
PORTC=0x00;
DDRC=0xFF;
PORTD=0x00;
DDRD=0xFF;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
MCUCR=0x00;
MCUCSR=0x00;
TIMSK=0x00;
ACSR=0x80;
SFIOR=0x00;
}
void main(void)
{
avr_init();

while (1)
{
PORTA.0 = 1;
pause;
PORTA.0 = 0;
pause;
PORTA.1 = 1;
pause;
PORTA.1 = 0;
pause;
PORTA.2 = 1;
pause;
PORTA.2 = 0;
pause;
PORTA.3 = 1;
pause;
PORTA.3 = 0;
pause;
PORTA.4 = 1;
pause;
PORTA.4 = 0;
pause;
PORTA.5 = 1;
pause;
PORTA.5 = 0;
pause;
PORTA.6 = 1;
pause;
PORTA.6 = 0;
pause;
PORTA.7 = 1;
pause;
PORTA.7 = 0;
pause;
PORTC.0 = 1;
pause;
PORTC.0 = 0;
pause;
PORTC.1 = 1;
pause;
PORTC.1 = 0;
pause;
PORTC.2 = 1;
pause;
PORTC.2 = 0;
pause;
PORTC.3 = 1;
pause;
PORTC.3 = 0;
pause;
};
}















Результатом выполнения этого кода будет бегущий огонек, который добежав до конца, начнет бежать сначала:



Тот же эффект можно получить и более коротким кодом.
Для этого введем переменную unsigned char i;
И код в основном цикле программы заменим на:


 
i=0b00000001;

while(i!=0) { // цикл будет выполнятся до тех пор пока i не равен 0
PORTA = i; //выводим порт значение переменной i
pause; //делаем задержку
i=i<<1; // сдвигаем все разряды переменной i на один разряд влево
};
PORTA=0; // Так как светодиоды на 2-ух портах, то при переходе на порт С обнуляем значение порта А
i=0b00000001;
while(i!=0b00010000) { // здесь уже сравниваем не с нулем, потому что используются только 4 ноги из 8
PORTC = i;
pause;
i=i<<1;
};
PORTC=0;














Небольшое пояснение к коду.
Здесь мы не стали в ручную присваивать состояние каждой ножки по отдельности, а начали работать сразу с портом целиком. Причем чтобы добиться эффекта бегущего огня, мы просто зажгли один пин порта и спомощью сдвига меняли его номер.
По коду:
выражение "!=” на языке Си означает - неравно
<< - оператор сдвига разрядов влево, число после него означает на какое количество разрядов надо сделать сдвиг.
На практике получаем вот что:
имеем некую переменную i=0b00000001;
применяем к ней оператор сдвига на один разряд влево i=i<<1;
и результатом получим i=0b00000010;
применим еще раз сдвиг i=i<<1; и получим i=0b00000100;

Таким образом наша единичка перемещается, используя цикл мы прогоняем эту единичку по всему порту и получаем наш бегущий огонек, написав минимум кода.

Бегуший огонек 2



Теперь, разобравшись с тем как получить эффект бегущего огонька причем разными способами можно немного поиграться и получить разные варианты "бега".

В предыдущем примере огонек, добегая до конца, исчезал и появлялся в начале. Сейчас совсем немного усложним этот вариант: сделаем так чтобы огонек добегая до конца начинал бежать обратно. Для этого добавим к нашему циклу бега, такой же цикл только с операторами сдвига уже в другую сторону:


i=0b00000001; 

while(i!=0) {
PORTA = i;
pause;
i=i<<1;
};
PORTA=0;
i=0b00000001;

while(i!=0b00010000) {
PORTC = i;
pause;
i=i<<1;
};

while(i!=0) {
PORTC = i;
pause;
i=i>>1;
};
PORTC=0;
i=0b10000000;

while(i!=0) {
PORTA = i;
pause;
i=i>>1;
};





Заполнение светодиодной шкалы



В этом варианте вместо бега одиночного светодиода, светодиоды буду загораться по очереди не гаснуть, будет эффект заполнения.
Для этого придется немного изменить код, потому что теперь нужно не просто деть сдвиг на порту, но еще и плюсовать его к предыдущему состоянию. на самом деле все очень просто, нам понадобится еще одна переменная и простенький код, который приведен ниже:


 
unsigned char j; введем дополнительную переменную
i=0b00000001;
j=i;
while(i!=0) {
PORTA = j;
pause;
i=i<<1;
j=j+i;
};
i=0b00000001;
j=i;
while(i!=0b00010000) {
PORTC = j;
pause;
i=i<<1;
j=j+i;
};
PORTA=0;
PORTC=0;








Немного фантазии и можно придумать другие эффекты со светодиодом.

Скачать прошивку и модель в Proteuse



Нравится
Категория: Микроконтроллеры | Добавил: Naprisar (23.08.2012)
Просмотров: 11320 | Комментарии: 3 | Теги: ATmega16, микроконтроллер, бегущие огни, светодиод
Всего комментариев: 3
3 Naprisar  
0
Тут надо исходить из того, какие светодиоды. Выход atmegи может обеспечить 5В и 20 мА тока. В примере на видео я использовал 220 Ом.

2 Naprisar  
0
Скинул на почту

1 Naprisar  
0
оставь кооринаты  куда скинуть

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Наверх