динамическая индикация
Семисегментный индикатор и динамическая индикация на AVR микроконтроллере ATmega8
В разных конструкциях бывает оправдано использовать семисегментные светодиодные индикаторы, дешево и сердито по сравнению с символьными ЖКИ. Светодиодный индикатор представляет собой восемь светодиодов (7 для представления цифры и 1 для точки) расположенные в виде слегка наклоненной цифры:
В разных конструкциях бывает оправдано использовать семисегментные светодиодные индикаторы, дешево и сердито по сравнению с символьными ЖКИ. Светодиодный индикатор представляет собой восемь светодиодов (7 для представления цифры и 1 для точки) расположенные в виде слегка наклоненной цифры:
Светодиоды внутри имеют общий анод (ОА) или общий катод (ОК). То есть, для управления одной цифрой нужно 8 выводов микроконтроллера. А что же делать, когда нужно управлять, например, четырьмя цифрами? Использовать микроконтроллер с 4*8=32 выводами? Не экономично.
Для такого случая придумали динамическую индикацию. Для этого соединяем выводы, которые отвечают за включение сегментов в общую шину, а общими анодами (катодами) будем управлять через транзисторы. В отдельный момент времени горит только одна цифра. Таким образом быстро перебирая цифры на дисплее (как кадры в фильме) мы получим эффект постоянно горящего изображения. В замедленном варианте, как это происходит, можно посмотреть на картинке:
А вот ускоренная в 25 раз картинка, уже начинают вырисовываться контуры «12.34»:
Используя принцип динамической индикации мы сможем управлять четырьмя цифрами при помощи 8+4=12 выводов. Использование же 2-х сдвиговых регистров HC595 может сократить это число до 4. Рассмотрим схему подключения к микроконтроллеру:
Управлять же индикатором будем с помощью микроконтроллера ATmega8. Резисторы R5-R13 – ограничительные на 470 Ом. R1-R4 – по 1кОм. Транзисторы Q1-Q4 – любые PNP типа, я использовал BC807 в планарном исполнении. Конденсаторы С5,С7 – электролиты по 100 и 200мкф соответственно, С4,С6 – керамика по 0,1мкф. Так как индикатор с общим анодом, то соответственно включение разряда/сегмента производиться низким уровнем.
Для индикаторов с общим катодом схема аналогична, только транзисторы следует взять NPN структуры, и управляться индикатор будет высоким уровнем.
Продемонстрируем сказанное, напишем программу, которая будет перебирать числа от 0 до 9999 и выводить их на семисегментный индикатор.
#include <avr/io.h> #include <avr/interrupt.h> // 0 1 2 3 4 5 6 7 8 9 const unsigned char codes[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; unsigned char data[4]={0x00,0x00,0x00,0x00}; unsigned char counter=0; void pause (unsigned int a) { unsigned int i; for (i=a;i>0;i--); } void init_timer (void) { TIMSK=(1<<TOIE0); //Enable timer overflow interrupt TCCR0=(0<<CS00)|(1<<CS01)|(0<<CS02); //Prescaller = /1 } void convert_data (unsigned int x) {unsigned int temp,res; temp=x; res=temp/1000; //Calculate 1000-s data[3]=codes[res]; temp=temp-res*1000; res=temp/100; //Calculate 100-s data[2]=codes[res]; temp=temp-res*100; res=temp/10; //Calculaate 10-s data[1]=codes[res]; temp=temp-res*10; data[0]=codes[temp]; //Calculate 1-s } ISR (TIMER0_OVF_vect) {PORTD=0xff; PORTB=~_BV(counter); //Enable digit PORTD=~data[counter]; //Write code counter=(counter+1)%4; //Increment digit counter TCNT0=0x00; //Clear timer } int main(void) { unsigned int x=0; DDRD=0xff; PORTD=0x00; DDRB=0x0f; PORTB=0x0f; pause(1000); //Settle pause init_timer(); //Init timer sei(); //Interrupt enable while(1) {convert_data(x); //Conver data to codes if (x<9999) x=x+1; //Increment data else x=0; pause(30000); } return 1; }
Код очень простой. В массиве codes находятся коды, которые следует выводить на порт, чтобы получить желаемую цифру. Смена активной цифры производиться по прерыванию от переполнения таймера 0. А функция convert_data(int x) раскладывает число х по разрядам, и записывает соответствующие коды в массив data, данные из которого выводятся непосредственно на индикатор, при срабатывание прерывания.
Что из этого вышло, можно глянуть на рисунках:


Исходный код можно скачать в виде проекта под AVR Studio 4
Также, может кому пригодиться, платка для моего табло в формате .lay для программы Sprint Layout 5
