Помогите разобратьс...
 
Уведомления
Очистить все

Помогите разобраться...

1 Посты
1 Пользователи
0 Likes
10.6 Тыс. Просмотры
Zanli
(@zanli)
New Member
Присоединился: 10 лет назад
Сообщения: 1
Topic starter  

Всем доброго дня суток!
Решил сделать таймер на ATmega8, так как он у меня уже есть. Нашел статью с таким таймером, во время тестов на протеусе лед индикатор моргает, и не могу найти решение, может вы поможете:

#include <mega8.h>
#include <delay.h>
struct Stime
{
unsigned char second;
unsigned char minute;
unsigned char hour;
} time[3];
void TimerEvent()
{
PORTB.4=1;
}
unsigned char Zminute=0,Zhour=0;
unsigned char chislo[4]; //определяем массив из двух элементов типа char беззнаковый(unsigned)
unsigned char numder[]= //определяем массив, в котором индексу будут соответствовать бити на порте D
{
0b11111100, //цифра 0
0b01100000, //цифра 1
0b11011010, //цифра 2
0b11110010, //цифра 3
0b01100110, //цифра 4
0b10110110, //цифра 5
0b10111110, //цифра 6
0b11100000, //цифра 7
0b11111110, //цифра 8
0b11110110, //цифра 9
};
void out(unsigned char hour,unsigned char minute)
{
/*сначала нам нужно определить, из скольких десятков и единиц состоит выводимое число.
Например, передали мы "45", нам надо его разложить на 4 и 5, чтобы на первый разряд семисегментника
вывести цифру 4, а на второй - 5 */
chislo[1]=hour%10; //оператор % дает остаток от целочисленного деления, например 34%10 будет 4
chislo[0]=hour/10; // узнаем, сколько десятков в числе

chislo[3]=minute%10;
chislo[2]=minute/10;
}
unsigned char i=0; // переменная для определения, на какой разряд семисегментника выводить число
// прерывания по переполнению timer0
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
PORTD=numder[ chislo ];
if (i==1) PORTD.0=1; else PORTD.0=0; //включаем/выключаем точку
PORTB = ( (PORTB & 0b11110000) | ( (~(1 <<i)) & 0b00001111 ) ); //включаем определённый разряд семисегментника
if (++i>3) i=0;
}
/* прерывания таймера2 вызывается 1 раз в секунду, потому что таймер2 тактирует от часового кварца на 32768 герц
и в таймере установлен предделитель частоты 128, ето значит что 128 тактов считаются как один тоэсть
кварц в нас 32768
таймер в нас 8 битный максимальноэ число 255
мы выбераем пределитель 128
получается 32768/128=255, это значит что за секунду пременная щета таймера (TCNT2) дойдет до 255 и таймер згенерирует прерывания
по переполнению переменной
*/
unsigned char outMenu=0;
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
if (time[0].second++==60)
{
time[0].second=0;
if (time[0].minute++==60)
{
time[0].minute=0;
if (time[0].hour++==24)
{
time[0].hour=0;

}
}
out(time[outMenu].hour,time[outMenu].minute);
if ( (time[0].minute==Zminute) && (time[0].hour==Zhour) ) TimerEvent(); //если минуты и секунды равны заданым вызываем функцию TimerEvent
}
}

void main(void)
{
PORTB=0x00;
DDRB=0x1F;

PORTD=0x00;
DDRD=0b11111111;

TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 0,977 kHz
TCCR0=0x04;
TCNT0=0x00;
// Timer/Counter 2 initialization
// Clock source: TOSC1 pin
// Clock value: PCK2/128
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x08;
TCCR2=0x05;
TCNT2=0x00;
OCR2=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x41;

// Global enable interrupts
#asm("sei")

while (1)
{
if (!(PINC & 0b00000001) && outMenu>0 ) // проверяем нажата ли кнопка 1
{
if (regim=true) time[outMenu].hour++; else time[outMenu].minute++;
}
if (!(PINC & 0b00000010)) // проверяем нажата ли кнопка 2
{
if (++outMenu>2) outMenu=0;
}
if (!(PINC & 0b00000100) && outMenu>0 ) // проверяем нажата ли кнопка 3
{
if (regim=true) time[outMenu].hour--; else time[outMenu].minute--;
}
delay_ms(200);

out(time[outMenu].hour,time[outMenu].minute);
};

}


Цитата