Функция прерывания AtMega 8

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
petrovich1285
Родился
Сообщения: 3
Зарегистрирован: Пн ноя 21, 2011 01:10:55

Функция прерывания AtMega 8

Сообщение petrovich1285 »

Здравствуйте.
Недавно начал осваивать прерывания микроконтроллера. Освоение двигалось нормально, но вот когда дошол до внутренних прерываний - прерывание по совпадению, то тут столкнулся с проблемкой.
В функции прерывания нужно увеличивать переменную на единицу и в фуннкции 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

Сообщение woosterstring »

Может быть заработает

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

volatile int time = 0;
если в регистрах настройка правильная. Это особенности компилятора.
Реклама
BerZerK-ku
Мучитель микросхем
Сообщения: 492
Зарегистрирован: Вт июл 22, 2008 08:10:54

Re: Функция прерывания AtMega 8

Сообщение BerZerK-ku »

Ошибка в том, что вместо установки СТС режима, вы настроили управление портом.

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

TCCR1A = 0;
TIMSK = (1 << OCIE1A);
OCR1AH = 0x1F;
OCR1AL = 0x40;
TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10);
В прерывании обнулять регистр TCNT1 не надо, лишняя трата времени.
+ как выше написано, для переменных изменяемых в прерывании привыкайте использовать volatile.
petrovich1285
Родился
Сообщения: 3
Зарегистрирован: Пн ноя 21, 2011 01:10:55

Re: Функция прерывания AtMega 8

Сообщение petrovich1285 »

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

volatile int time = 0;
Урааа!!! заработало!!!
Большое спасибо! А где можно почитать об volatile? А то я об этом первый раз слышу. Перерыл не один форум, сайт и в книгах не встречал такого объявления переменных.

А управление портом мне как раз и надо. К ШИМ режимам я еще не дошол... практически, только теорию почитал.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: Функция прерывания AtMega 8

Сообщение BCluster »

А че тут читать) volatile запрещает компилятору оптимизировать переменную. То есть например есть код

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

bool flag=false;
while(flag)
{
...
}
тут цикл скорее всего выполняться не будет, ибо значение переменной flag не поменятеся в процессе выполнения программы.
если же ее объявить как volatile цикл честно выполнится.

В вашем случае тоже самое - компилятор не просматривает обработчики прерываний, считает что переменная не используюется и оптимизирует ее. ИМХО ибо я в winavr не работаю
Реклама
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: Функция прерывания AtMega 8

Сообщение Мастер Ломастер »

petrovich1285 писал(а):А где можно почитать об volatile? А то я об этом первый раз слышу. Перерыл не один форум, сайт и в книгах не встречал такого объявления переменных.
извините, а вы где искали и в каких книгах рылись? не в "сказках народов мира" случайно? просто ну никак не верится вашим словам! если вас в гугле не забанили, посмотрите повнимательнее
битва с дураками проиграна, победители торжествуют. слава победителям!
Реклама
petrovich1285
Родился
Сообщения: 3
Зарегистрирован: Пн ноя 21, 2011 01:10:55

Re: Функция прерывания AtMega 8

Сообщение petrovich1285 »

В одной из ссылок, автор сам пишет, что встречался с этим всего 2 раза!
Я, перед открытием этой темы, перерыл форумы, смотрел готовые прошивки електронных часов... в прерываниях использовались переменные, которие там же изменяли свое значение и использовались в бругих местах и не мог понять, почему у них все работает, а у меня нет!
Я так понял, что это и еще зависит и от компилятора, потому как с бодобным уже встречался при изучении прерываний внешних.
woosterstring
Нашел транзистор. Понюхал.
Сообщения: 192
Зарегистрирован: Чт сен 16, 2010 19:47:01
Откуда: Украина

Re: Функция прерывания AtMega 8

Сообщение woosterstring »

Вот выдержка из разела справки 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:

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

uint8_t flag;
...
ISR(SOME_vect) {
  flag = 1;
}
...

        while (flag == 0) {
                ...
        }
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:

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

volatile uint8_t flag;
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»