Предположим вы пишите программу, которая должна выводить числа. Например: часы, секундомер, термометр и т.п. Для вывода информации можно воспользоваться жк дисплеем, но по ряду причин, это может быть не всегда удобно, красиво или дорого. Поэтому применяют семисегментный индикатор, который является набором из 7 светодиодов.
Для примера рассмотрим индикатор SA56, каждая черточка это светодиод. Кроме того их можно по разному объединить. В данном случае обратите внимание общий анод, т.е. «+» Если на ножки 7, 6, 4… подавать землю, то соответственно будут зажигаться соответствующие сегменты a, b, c…
Теперь разберемся, как все это дело прикрутить к микроконтроллеру.
Для собственного удобства, отметим каждый светодиод по порядку от 0 до 6. И подсоединим их в соответствии с их номерами, к порту В например.
Так как мы рассматриваем далее вариант с общим анодом, то и прошивка будет ориентирована на этот вариант, т.е. чтобы зажечь сегмент мы должны подать логический ноль в порт, чтобы выключить нужно подать логическую единицу. Чтобы переделать прошивку под общий катод, нужно инвертировать состояние выхода порта.
Итак, исходные данные: 7сегментник с общим анодом (общий «+»), нужно вывести все цифры подряд от 0 до 9, такой счетчик
Начнем с 0. Смотрим на картинку с обозначенными номерами светодиодов, получается чтобы высветить 0 нужно зажечь все светодиоды, кроме 6.
Так как у нас номера светодиодов соответствуют номерам порта, то нам нужно включить ножки с 0 по 5 включительно. Чтобы их включить достаточно вывести в порт значение PORTB=0b00111111;
Вроде все верно, но не забываем что у нас общий «+», поэтому, чтобы светодиод загорелся, нам нужно в порт выводить 0 (землю). Поэтому инвертируем данное число и получим PORTB=0b11000000;
Аналогично 1: светодиоды 1 и 2, т.е. окончательно в порт нужно вывести PORTB=0b11111001;
Думаю дальше разберетесь самостоятельно. Для тех кто не понял что означает запись PORTB=0b00111111; рекомендую ознакомиться со статьей про конфигурацию портов
Теперь попробуем собрать полученную информацию в одну кучу и написать прошивку, которая считает от 0 до 9 и выводит полученную информацию на индикатор.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include <mega8.h> #include <delay.h> void main(void) { int number = 0; PORTB=0x00; DDRB=0xFF; while (1) { switch(number) { case 0:{PORTB=0xC0; break;} case 1:{PORTB=0xF9; break;} case 2:{PORTB=0xA4; break;} case 3:{PORTB=0xB0; break;} case 4:{PORTB=0x99; break;} case 5:{PORTB=0x92; break;} case 6:{PORTB=0x82; break;} case 7:{PORTB=0xF8; break;} case 8:{PORTB=0x80; break;} case 9:{PORTB=0x90; break;} } delay_ms(1000); number++; if (number==10) number=0; }; } |
В прошивке сложного ничего нет, используется оператор switch который в зависимости от того, какое число в переменной number зажигает нужные светодиоды.
Для симуляции на схеме не показаны резисторы, в реальной схеме необходимо ограничивать ток светодиода, поэтому на каждую ножку нужно повесить резистор.
Статическую индикацию удобнее было рассматривать со сдвиговыми регистрами. Ибо на практике такая схема не применяется толком…
здраствуте помогите решить проблемку… как вывести переменное M у которого число варьируется от 0001 до 9999 на 7сегментный индикатор? с индикацией времени проблем нет. а вот целое число на 4 отдельных сигмента не знаю как вывести
int y = 9875;
char x_1000 = y/1000;
char x_100 = (y%1000)/100;
char x_10 = (y%100)/10;
char x_1 = (y%10);
#include
#include
#include
static flash unsigned char digit[]={
(0b00111111), //0
(0b00000110), //1
(0b01011011), //2
(0b01001111), //3
(0b01100110), //4
(0b01101101), //5
(0b01111101), //6
(0b00000111), //7
(0b01111111), //8
(0b01101111), //9
};
unsigned long i = 0, freq=0;
unsigned char
x_1000=freq/1000,
x_100=(freq%1000)/100,
x_10=(freq%100/10),
x_1= (freq%10);
interrupt [EXT_INT0] void ext_int0_isr(void)
{
i++;
}
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
freq=1234;
i=0;
TCNT1H=0x00;
TCNT1L=0x00;
}
void main(void)
{
PORTB=0x00;
DDRB=0xFF;
PORTD=0x11110000;
DDRD=0x00001111;
TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x1E;
OCR1AL=0x85;
OCR1BH=0x00;
OCR1BL=0x00;
GICR|=0x40;
MCUCR=0x03;
GIFR=0x40;
TIMSK=0x10;
// Global enable interrupts
#asm(«sei»)
while (1) //здесь включаю поочередно сегмент и его число
{
PORTD.7=1;
PORTB=digit[x_1000];
delay_ms(2);
PORTD.7=0;
PORTD.6=1;
PORTB=digit[x_100];
delay_ms(2);
PORTD.6=0;
PORTD.5=1;
PORTB=digit[x_10];
delay_ms(2);
PORTD.5=0;
PORTD.4=1;
PORTB=digit[x_1];
delay_ms(2);
PORTD.4=0;
};
}
вот как то так я набросал.. помогите реализовать эту идею как то.
и что не получается?
ругается на x_1000=freq/1000 и тп строки.- «возможно должны быть константы». не знаю чего он хочет. в чем моя логика и его логика не совпадает
потому что вычислять выражения надо в основном цикле
Спасибо большое за сайт очень полездный