Так вам надо чтобы переменная I увеличивалась раз в секунду? Я думал, у вас переменная I это внутренний счётчик, который достигает 60 когда проходит 1 секунда (а поскольку, в секунду 30 раз срабатывает прерывание, то я и решил, что у вас просто число 60 ошибка - должно быть 30).
Но раз так, тогда смотрите.
1) При текущих настройках у вас прерывание приходит 30.5175 раз в секунду. Число плохое, не круглое. 8000000/1024=7812.5 Тоже не целое. Значит, такой делитель не подходит. Поищем другой. 8000000/256=31250=5*5*5*5*5*5*2 - подходит. Значит, TCCR0=((1<<CS02)|(0<<CS01)|(0<<CS00));//выбран режим деления тактовых импульсов на 256.
Теперь подбираем начальное значение таймера. Самый большой интервал таймера будет при 250=5*5*5*2 (большее число в байт не влезет). Значит, TCNT0=256-250=6
2) Сейчас с такими настройками у нас прерывание вызывается 125 раз в секунду. Значит, нужна переменная счётчик внутреннего цикла таймера.
Итого, ваша программа будет иметь вид:
Код: Выделить всё
#include <mega8.h>
#include <delay.h>
#include <stdio.h>
#include <lcd.h>
#asm
.equ __lcd_port=0x12
#endasm
volatile unsigned char T0Counter=0;//модификатор volatile нужен, если будете вне где-то эту переменную использовать. Говорит компилятору не оптимизировать к ней доступ (не кэшировать её значение, которое может измениться внезапно в прерывании).
volatile int i;
char buffer[60];
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=6;//задаём начальное значение таймера
T0Counter++;
if (T0Counter==125)//прошла секунда
{
T0Counter=0;
i++;
if(i==60) i=0;//прошла минута
}
}
void main(void)
{
TCCR0=((1<<CS02)|(0<<CS01)|(0<<CS00));//не знаю, поддерживает ли ваш компилятор эти макросы. Если нет, посмотрите таблицу из книжки, что я привёл
TCNT0=6;
TIMSK=0x01;
lcd_init(16);
// Global enable interrupts
#asm("sei")
while (1)
{
sprintf(buffer,"%d",i);
lcd_gotoxy(0,0);
lcd_puts(buffer);
}
}
Всё.
