Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: неправильно считает дефайн и таймер
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
the_victor
вобщем есть такие фрагменты кода из проекта, которые еще работает только частично.
#define F_CPU 8000000 //тактовая частота
#define TIC0 ((unsigned char)(F_CPU/(1024*255))) //столько раз в секунду переполняется таймер 0
#define SCROLL_TIME ((unsigned char)(0,5*TIC0))

SIGNAL(TIMER0_OVF_vect)
{
tics.led_scroll++;
}

main()
{
//тактовая для таймера0 = F_CPU/1024
//разрешаем прерывание по переполнению таймера0
TCCR0=(1<<CS02) | (1<<CS00);
TIMSK|=(1<<TOIE0);

if ( tics.led_scroll == SCROLL_TIME )
{
tics.led_scroll = 0;
и тд прокрутка бегущей строки.
}
}

в общнм проблема: по логике вещей таймер переполняется 8000000(такт частота) / ( 1024(делитель)*256(разрядность счетной переменной) ). если ето сделать через дефайн, то работает, прокручивается на глаз где-то за пол секунды. если посчитать на калькуляторе то получим значение 30. но компилятор вычисяляет значение 124(выводил на индикатор). при том если поставить в условие 30, то прокрутка становится очень быстрой. то есть таймер срабатывает в несколько раз чаще чем должен и при этом дефайн вычисляется во столько же раз больше. ето не поддается моему пониманию.
я думаю что как то неверно преобразуются типы. но все равно ничего не понимаю.
если в формуле дефайна делить на 255 то работает, а если на 256 (что точнее), то программа даже не заходит в прокрутку, бегущая строка замирает. все типы uint8_t.
warning: integer overflow in expression в условии сравнения. WinAVR-20070525
в архиве все что я накодил. бегущая строка работают, кнопки не не так как должны(срабатывает длинное нажатие, но это все из за этих глючных дефайнов). в принципе можно смириться, но охото понять почему так, и для длительной задерки 5сек для кнопки не охото вводить 16бит пременную.
AlexMad
Для начала надо указать компилятору, что константа большая
#define F_CPU 8000000UL //тактовая частота
буквами UL после самой константы
mdmitry
Цитата(the_victor @ Dec 13 2007, 18:32) *
вобщем есть такие фрагменты кода из проекта, которые еще работает только частично.
#define F_CPU 8000000 //тактовая частота
#define TIC0 ((unsigned char)(F_CPU/(1024*255))) //столько раз в секунду переполняется таймер 0
#define SCROLL_TIME ((unsigned char)(0,5*TIC0))

SIGNAL(TIMER0_OVF_vect)
{
tics.led_scroll++;
}

main()
{
//тактовая для таймера0 = F_CPU/1024
//разрешаем прерывание по переполнению таймера0
TCCR0=(1<<CS02) | (1<<CS00);
TIMSK|=(1<<TOIE0);

if ( tics.led_scroll == SCROLL_TIME )
{
tics.led_scroll = 0;
и тд прокрутка бегущей строки.
}
}


Как высчитывается #define TIC0 ((unsigned char)(F_CPU/(1024*255)))? Посчитайте отдельно и заставьте препроцессор это вычислить и сравните.( F_CPU/(1024*255)) и F_CPU/1024/255 ).
SIGNAL(TIMER0_OVF_vect) - старая форма записи, не рекомендуется, см. описание библиотеки.
Какой процессор и правильный ли выбран таймер?
the_victor
blush.gif
Цитата(mdmitry @ Dec 14 2007, 01:21) *
Как высчитывается #define TIC0 ((unsigned char)(F_CPU/(1024*255)))? Посчитайте отдельно и заставьте препроцессор это вычислить и сравните.( F_CPU/(1024*255)) и F_CPU/1024/255 ).
SIGNAL(TIMER0_OVF_vect) - старая форма записи, не рекомендуется, см. описание библиотеки.
Какой процессор и правильный ли выбран таймер?

мега 128. таймер 0. похоже напутал с инициализацией таймера.
надо делать TCCR0=(1<<CS02)|(1<<CS01)|(1<<CS00); вот растяпа. он похоже по многу раз переполнялся и попадал на нужные значения, что убедило меня в правильности программы.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.