Функция прерывания AtMega 8
-
petrovich1285
- Родился
- Сообщения: 3
- Зарегистрирован: Пн ноя 21, 2011 01:10:55
Функция прерывания AtMega 8
Здравствуйте.
Недавно начал осваивать прерывания микроконтроллера. Освоение двигалось нормально, но вот когда дошол до внутренних прерываний - прерывание по совпадению, то тут столкнулся с проблемкой.
В функции прерывания нужно увеличивать переменную на единицу и в фуннкции main выводить значение на 7-ми сегментном индикаторе (что-то похожее на часы - подсчет количества временных интервалов). Но значение переменной (time) не увеличивается, не пойму почему.
Может кто-то подскажет в чем проблема. Заранее благодарен.
P.S. испытания проводил на макетной плате
#include <avr/io.h>
#include <avr/interrupt.h>
int time=0;
ISR (TIMER1_COMPA_vect)
{
TCNT1H=0x00;
TCNT1L=0x00;
time++;
}
int main (void)
{
TCCR1A=1<<6;
TCCR1B=5;
TIMSK=1<<4;
OCR1AH=0x1F;
OCR1AL=0x40;
sei();
while (1)
{
//код программы индикации
}
}
Недавно начал осваивать прерывания микроконтроллера. Освоение двигалось нормально, но вот когда дошол до внутренних прерываний - прерывание по совпадению, то тут столкнулся с проблемкой.
В функции прерывания нужно увеличивать переменную на единицу и в фуннкции main выводить значение на 7-ми сегментном индикаторе (что-то похожее на часы - подсчет количества временных интервалов). Но значение переменной (time) не увеличивается, не пойму почему.
Может кто-то подскажет в чем проблема. Заранее благодарен.
P.S. испытания проводил на макетной плате
#include <avr/io.h>
#include <avr/interrupt.h>
int time=0;
ISR (TIMER1_COMPA_vect)
{
TCNT1H=0x00;
TCNT1L=0x00;
time++;
}
int main (void)
{
TCCR1A=1<<6;
TCCR1B=5;
TIMSK=1<<4;
OCR1AH=0x1F;
OCR1AL=0x40;
sei();
while (1)
{
//код программы индикации
}
}
- Реклама
-
woosterstring
- Нашел транзистор. Понюхал.
- Сообщения: 192
- Зарегистрирован: Чт сен 16, 2010 19:47:01
- Откуда: Украина
Re: Функция прерывания AtMega 8
Может быть заработает
если в регистрах настройка правильная. Это особенности компилятора.
Код: Выделить всё
volatile int time = 0;-
BerZerK-ku
- Мучитель микросхем
- Сообщения: 492
- Зарегистрирован: Вт июл 22, 2008 08:10:54
Re: Функция прерывания AtMega 8
Ошибка в том, что вместо установки СТС режима, вы настроили управление портом.
В прерывании обнулять регистр TCNT1 не надо, лишняя трата времени.
+ как выше написано, для переменных изменяемых в прерывании привыкайте использовать volatile.
Код: Выделить всё
TCCR1A = 0;
TIMSK = (1 << OCIE1A);
OCR1AH = 0x1F;
OCR1AL = 0x40;
TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10);
+ как выше написано, для переменных изменяемых в прерывании привыкайте использовать volatile.
-
petrovich1285
- Родился
- Сообщения: 3
- Зарегистрирован: Пн ноя 21, 2011 01:10:55
Re: Функция прерывания AtMega 8
Код: Выделить всё
volatile int time = 0;Большое спасибо! А где можно почитать об volatile? А то я об этом первый раз слышу. Перерыл не один форум, сайт и в книгах не встречал такого объявления переменных.
А управление портом мне как раз и надо. К ШИМ режимам я еще не дошол... практически, только теорию почитал.
- BCluster
- Собутыльник Кота
- Сообщения: 2512
- Зарегистрирован: Пн апр 06, 2009 19:33:29
- Откуда: Молдова, Кишинев
- Контактная информация:
Re: Функция прерывания AtMega 8
А че тут читать) volatile запрещает компилятору оптимизировать переменную. То есть например есть код
тут цикл скорее всего выполняться не будет, ибо значение переменной flag не поменятеся в процессе выполнения программы.
если же ее объявить как volatile цикл честно выполнится.
В вашем случае тоже самое - компилятор не просматривает обработчики прерываний, считает что переменная не используюется и оптимизирует ее. ИМХО ибо я в winavr не работаю
Код: Выделить всё
bool flag=false;
while(flag)
{
...
}если же ее объявить как volatile цикл честно выполнится.
В вашем случае тоже самое - компилятор не просматривает обработчики прерываний, считает что переменная не используюется и оптимизирует ее. ИМХО ибо я в winavr не работаю
- Реклама
-
Мастер Ломастер
- Поставщик валерьянки для Кота
- Сообщения: 1995
- Зарегистрирован: Ср май 11, 2011 21:37:45
- Откуда: Цветочный город
- Контактная информация:
Re: Функция прерывания AtMega 8
извините, а вы где искали и в каких книгах рылись? не в "сказках народов мира" случайно? просто ну никак не верится вашим словам! если вас в гугле не забанили, посмотрите повнимательнееpetrovich1285 писал(а):А где можно почитать об volatile? А то я об этом первый раз слышу. Перерыл не один форум, сайт и в книгах не встречал такого объявления переменных.
битва с дураками проиграна, победители торжествуют. слава победителям!
-
petrovich1285
- Родился
- Сообщения: 3
- Зарегистрирован: Пн ноя 21, 2011 01:10:55
Re: Функция прерывания AtMega 8
В одной из ссылок, автор сам пишет, что встречался с этим всего 2 раза!
Я, перед открытием этой темы, перерыл форумы, смотрел готовые прошивки електронных часов... в прерываниях использовались переменные, которие там же изменяли свое значение и использовались в бругих местах и не мог понять, почему у них все работает, а у меня нет!
Я так понял, что это и еще зависит и от компилятора, потому как с бодобным уже встречался при изучении прерываний внешних.
Я, перед открытием этой темы, перерыл форумы, смотрел готовые прошивки електронных часов... в прерываниях использовались переменные, которие там же изменяли свое значение и использовались в бругих местах и не мог понять, почему у них все работает, а у меня нет!
Я так понял, что это и еще зависит и от компилятора, потому как с бодобным уже встречался при изучении прерываний внешних.
-
woosterstring
- Нашел транзистор. Понюхал.
- Сообщения: 192
- Зарегистрирован: Чт сен 16, 2010 19:47:01
- Откуда: Украина
Re: Функция прерывания AtMega 8
Вот выдержка из разела справки FAQ WinAVR (v. 20100110). Этот вопрос часто всплывает у них на форуме.
My program doesn't recognize a variable updated within an interrupt routine.
When using the optimizer, in a loop like the following one:the compiler will typically access flag only once, and optimize further accesses completely away, since its code path analysis shows that nothing inside the loop could change the value of flag anyway. To tell the compiler that this variable could be changed outside the scope of its code path analysis (e. g. from within an interrupt routine), the variable needs to be declared like:Код: Выделить всё
uint8_t flag; ... ISR(SOME_vect) { flag = 1; } ... while (flag == 0) { ... }Код: Выделить всё
volatile uint8_t flag;


