1 секунда на таймере T0

Обсуждаем контроллеры компании Atmel.
Ответить
Первый раз сказал Мяу!
Сообщения: 33
Зарегистрирован: Вт апр 23, 2013 16:46:07

Сообщение cas2010 »

ПРивет всем.
Мастера и новички, пожалуйста скажите как мне на таймере 0, прибавлять по единичке в переменую в секунду?
я сделал так: установил таймер на предделитель на 1024, потом прибавляю в самом прерывании.
У меня прибавление происходит не в секунду, а на много быстрее.

Частота контроллера 8 Мгц

Код: Выделить всё

#include <mega8.h>
#include <delay.h>
#include <stdio.h>
#include <lcd.h>
#asm
.equ __lcd_port=0x12
#endasm
int i;
char buffer[60];
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
i++;
if(i==60){
         i=0;
          };
          
}
void main(void)
{
TCCR0=0x05;
TCNT0=0x00;
TIMSK=0x01;
lcd_init(16);

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

while (1)
      {
       sprintf(buffer,"%d",i);
       lcd_gotoxy(0,0);
       lcd_puts(buffer);
      }
}
Последний раз редактировалось cas2010 Сб апр 27, 2013 22:22:13, всего редактировалось 4 раза.
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.

Сообщение da-nie »

А какой коэффициент делителя частоты вы установили?
И что такое "установил таймер на 7813 тактов"?
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Контактная информация:
Реклама
Первый раз сказал Мяу!
Сообщения: 33
Зарегистрирован: Вт апр 23, 2013 16:46:07

Сообщение cas2010 »

da-nie писал(а):А какой коэффициент делителя частоты вы установили?
И что такое "установил таймер на 7813 тактов"?
простите меня я в этом новичек... но вроде там написано, мне нужно помочь в настройке таймера
Последний раз редактировалось cas2010 Сб апр 27, 2013 22:23:09, всего редактировалось 1 раз.
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.

Сообщение da-nie »

Таймер же считает не такты процессора. На него приходят такты поделённые на некое число. Вот это число вам нужно будет задать.
Как? А вот как:

Изображение

Изображение

Например так:

Код: Выделить всё

TCCR0=((0<<CS02)|(1<<CS01)|(1<<CS00));//выбран режим деления тактовых импульсов на 64
TCNT0=0;//начальное значение таймера
TIMSK=(1<<TOIE0);//прерывание по переполнению таймера (таймер T0 восьмибитный и считает на увеличение до 0xff)
Вложения
p2.JPG
(63.55 КБ) 1058 скачиваний
p1.JPG
(24.54 КБ) 995 скачиваний
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.

Сообщение da-nie »

Впрочем, у вас и так задано деление на 1024. Таймер у вас работает на увеличение до 255, итого он делает на вашей частоте 8 Мгц 8000000/(1024*256)=30.5175 переполнений в секунду. Всё верно. Должно работать.
Кстати, а в вашем компиляторе не нужно в прерывании сбрасывать флаг данного прерывания?
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Контактная информация:
Реклама
Первый раз сказал Мяу!
Сообщения: 33
Зарегистрирован: Вт апр 23, 2013 16:46:07

Сообщение cas2010 »

da-nie писал(а):Впрочем, у вас и так задано деление на 1024. Таймер у вас работает на увеличение до 255, итого он делает на вашей частоте 8 Мгц 8000000/(1024*256)=30.5175 переполнений в секунду. Всё верно. Должно работать.
Кстати, а в вашем компиляторе не нужно в прерывании сбрасывать флаг данного прерывания?
А как сделать чтобы он переполнился 1 раз в секунду?
Работать то оно работает, но счет идет не в секундах а как будто в миллисекундах, а мне надо чтобы он переменную " i " увеличивал в секунду 1 раз. При том это надо сделать именно на таймере Т0
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.

Сообщение da-nie »

Так вам надо чтобы переменная 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);
      }
}
Всё. :)
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 33
Зарегистрирован: Вт апр 23, 2013 16:46:07

Сообщение cas2010 »

da-nie - большое спасибо. Очень и очень благодарю.
Ответить

Вернуться в «AVR»