Динамическая индикация - это метод отображения целостной картины через быстрое последовательное отображение отдельных элементов этой картины. (Благодаря инерционности человеческого зрения человек не видет что на самом деле в любой момент времени горит только часть изображения)
В этой статье будет использован: Светодиодные индикаторы (4 разряда): CPD-03641SR1 Светодиодный индикатор 30×14 мм, красный, 4 разряда, общий анод cpd-03641sr1a
Из рисунка видно, что для индикации какого либо символа необходимо подать 5V на ножку для определенного знакового места плюс выставить нули на ножках (A,B,C…) , чтобы зажечь соответствующие части числа.
Так вот схема подключения:
1) Резисторы номиналом 220ОМ для защиты от перегорания. 2)Точки не подключены т.к не будут использованы в этой статье
Общие принципы работы: 1) Мы настроем таймер счетчик на прерывание через один и тот же временной промежуток для посимвольной индикации. 2) Создадим глобальные переменные для хранения каждого из разрядов выводимого числа 3) Напишем несколько функций необходимых для работы
//Начнем с подключаемых заголовочных файлов
#define F_CPU 1000000UL //определяем тактовую частоту как 1Мгц #include <avr/io.h> //основной заголовочный файл #include <util/delay.h> //место хранения _delay_us() #include <avr/interrupt.h> //заголовочный файл для работы с прерываниями
//функция для инициализации ножек подключенных к индикатору void Port_init (void) { //определяем порт DиB на вывод информации DDRB=0xFF; PORTB=0×00;
DDRD=0xFF; PORTD=0×00; }
//функция принимает значение цифры которую необходимо вывести. Другими словами принимая в качестве аргумента число 1 эта функция выведет на порте B комбинацию необходимую для того чтобы на индикаторе появилась эта цифра. void segment (char N) { switch (N) { case 0: PORTB&=~63; break; // число 0 case 1: PORTB&=~6; break; // число 1 case 2: PORTB&=~91; break; // число 2 case 3: PORTB&=~79; break; // число 3 case 4: PORTB&=~102; break; // число 4 case 5: PORTB&=~109; break; // число 5 case 6: PORTB&=~125; break; // число 6 case 7: PORTB&=~7; break; // число 7 case 8: PORTB&=~127; break; // число 8 case 9: PORTB&=~111; break; // число 9 case 10: PORTB&=~64; break; // число 10 это - case 11: PORTB&=~0; break; // пустое место }; }
//создаем глобальные переменные для хранения разрядов выводимого числа char A1=0; char A2=0; char A3=0; char A4=0;
//Эта функция принимает как аргумент число которое необходимо вывести. Эта функция меняет глобальные переменные разрядов чисел в соответствии с аргументом функции void print_led (int chislo) { A1=chislo%10; // 1ый разряд A2=(chislo%100)/10; // 2ой разряд A3=(chislo%1000)/100; // 3ий разряд A4=(chislo%10000)/1000; // 4ий разряд }
// инициализируем 1ый 16 битный таймер счетчик на прерывание по совпадению void timer_init (void) { TCCR1B |= (1<<WGM12);// устанавливаем режим СТС (сброс по совпадению TIMSK |= (1<<OCIE1A);// устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L) OCR1AH = 0b00000111;// определяем число сравнения. Определяем как часто делать прерывания OCR1AL = 0b00000000; TCCR1B |=(1<<CS10);//запуск таймера }
//переменная будет отвечать чтобы каждое следующее прерывание обрабатывало следующий разряд числа char N=0;
// програма прерывания по совпадению 16ти разрядного счетчика ISR (TIMER1_COMPA_vect) { //определяем какой разряд на очереди. очищаем порт. переходим на следующее знако место. рисуем цифру. if(N==0) { PORTB|=127; PORTD=8; segment(A1); } if(N==1) { PORTB|=127; PORTD=4; segment(A2); } if(N==2) { PORTB|=127; PORTD=2; segment(A3); } if(N==3) { PORTB|=127; PORTD=1; segment(A4); }
N+=1; if(N==4)N=0; }
//главная функция int main(void) { //инициализируем порт DиB Port_init(); //инициализируем и запускаем таймер timer_init();
//глобальное разрешение прерываний если эту функцию не вызвать прерывания не будут работать sei();
//вот суть примера. Создаем число и выводим его на наш индикатор каждую сек оно увелич на ед до 9000 и заново for(i=0;i<9000;i++) { print_led(i); _delay_ms(1000); if(i==9000)i=0; } }
|