Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Семисигментная индикация часов на ATmega

Пн дек 25, 2017 09:09:33

Здравствуйте. Возник вопрос по семисегментной индикации часов на ATmega16. Вроде бы запустил таймер но почему то в протеусе выводятся только нули на всех 6 индикаторх.

#define F_CPU 8000000L
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

//----------
unsigned char sec=0, min=0, hure=0;
unsigned char R1=0,R2=0,R3=0,R4=0,R5=0,R6=0;
unsigned char n_count=0;
//----------
void segchar (unsigned char seg)
{
switch(seg)
{
case 1: PORTD = 0b11111001; break;
case 2: PORTD = 0b10100100; break;
case 3: PORTD = 0b10110000; break;
case 4: PORTD = 0b10011001; break;
case 5: PORTD = 0b10010010; break;
case 6: PORTD = 0b10000010; break;
case 7: PORTD = 0b11111000; break;
case 8: PORTD = 0b10000000; break;
case 9: PORTD = 0b10010000; break;
case 0: PORTD = 0b11000000; break;
}
}
//----------
void timer_ini(void)
{
TCCR1B |= (1<<WGM12); // устанавливаем режим СТС (сброс по совпадению)
TIMSK |= (1<<OCIE1A); //устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)
OCR1AH = 0b01111010; //записываем в регистр число для сравнения
OCR1AL = 0b00010010;
TCCR1B |= (1<<CS12)&(1<<CS11)&(0<<CS10);//установим делитель.
}
//----------
ISR (TIMER1_COMPA_vect)
{
sec++;
if (sec>59)
{
min++;
sec=0;
}
if (min>59)
{
hure++;
min=0;
}
if (hure>24)
{
hure=0;
min=0;
sec=0;
}

}
//----------
void timer_led(void)
{
TCCR0|=0b000000011;
TIMSK |=(1<<TOIE0);
}
//----------
ISR (TIMER0_OVF_vect)
{
if (n_count==0){PORTB&=~(1<<PORTB0);PORTB|=(1<<PORTB1);PORTB|=(1<<PORTB2);PORTB|=(1<<PORTB3);PORTB|=(1<<PORTB4);PORTB|=(1<<PORTB5); segchar(R1);}
if (n_count==1){PORTB&=~(1<<PORTB1);PORTB|=(1<<PORTB0);PORTB|=(1<<PORTB2);PORTB|=(1<<PORTB3);PORTB|=(1<<PORTB4);PORTB|=(1<<PORTB5); segchar(R2);}
if (n_count==2){PORTB&=~(1<<PORTB2);PORTB|=(1<<PORTB1);PORTB|=(1<<PORTB0);PORTB|=(1<<PORTB3);PORTB|=(1<<PORTB4);PORTB|=(1<<PORTB5); segchar(R3);}
if (n_count==3){PORTB&=~(1<<PORTB3);PORTB|=(1<<PORTB1);PORTB|=(1<<PORTB2);PORTB|=(1<<PORTB0);PORTB|=(1<<PORTB4);PORTB|=(1<<PORTB5); segchar(R4);}
if (n_count==4){PORTB&=~(1<<PORTB4);PORTB|=(1<<PORTB1);PORTB|=(1<<PORTB2);PORTB|=(1<<PORTB3);PORTB|=(1<<PORTB0);PORTB|=(1<<PORTB5); segchar(R5);}
if (n_count==5){PORTB&=~(1<<PORTB5);PORTB|=(1<<PORTB1);PORTB|=(1<<PORTB2);PORTB|=(1<<PORTB3);PORTB|=(1<<PORTB4);PORTB|=(1<<PORTB0); segchar(R6);}
n_count++;
if (n_count>5) n_count=0;
}
//----------
void ledprint(unsigned char number)
{
R1=number%10;
R2=number/10;
R3=number%10;
R4=number/10;
R5=number%10;
R6=number/10;
}
//----------
int main(void)
{
timer_ini();
timer_led();
DDRD = 0b11111111;
DDRB = 0b00111111;
PORTD = 0b11111111;
PORTB = 0b00000001;
sei();
while(1)
{
ledprint(sec);
ledprint(min);
ledprint(hure);
}
}

Re: Семисигментная индикация часов на ATmega

Пн дек 25, 2017 10:07:04

а как ледпринт различает что вы в неё засунули?

Добавлено after 2 minutes 12 seconds:
if (hure>24) у вас в сутках 25 часов? (0-24).

Добавлено after 2 minutes 5 seconds:
case 6: PORTD = 0b10000010; опять же присутствуют "магические числа" (ARV объяснит).

Добавлено after 5 minutes 25 seconds:
if (n_count==0){PORTB&=~(1<<PORTB0);PORTB|=(1<<PORTB1);PORTB|=(1<<PORTB2);PORTB|=(1<<PORTB3);PORTB|=(1<<PORTB4);PORTB|=(1<<PORTB5); segchar(R1);} зачем так сложно
PORTB|=0b001111111; segchar(R[n]); PORTB&=~(1<<n); вместо всех ИФов
ну ещё R1-R6 в массив оформить...

Добавлено after 3 minutes 24 seconds:
ПС: магические числа и жесткие прописки делают код трудноисправимым, но т.к. их опасность не видна в малых проектах, то к такому стилю программист легко привыкает, а потом придётся переучиваться.

Добавлено after 26 minutes 33 seconds:
чтобы рисовать цифры без магических чисел создаю и прикрепляю к проекту файлик:

и таскаю его из проекта в проект, меняя номера ног и названия портов.
Ответить