Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Микроконтроллеры (MCU) и микропроцессоры (MPU) > Не выполняеться прерывание?


Автор: Ofer 8.7.2008, 12:44
Доброе время суток! У меня есть программа, которая должна через каждую секунду инвертировать вывод порта. Но когда происходит прерывание, таймер восстанавливает свои значения, то есть вроде бы прерывание обрабатывается, но значение на порте не меняется. Пишу на WinAVR.  В чем у меня ошибка?

h-файл
Код

#ifndef __USERDEF__
#define __USERDEF__
#ifdef F_CPU
#undef F_CPU
#endif
#define F_CPU 8000000UL
//Настройка таймеров(в программе не использовал, хотя можно)
#define TIME_INIT_MS 1000
#define TCNT16_TIME_INIT (uint16_t)(~((uint64_t)TIME_INIT_MS*(uint64_t)F_CPU/10240000)+1)
//Операции над битами
#define set_bit(port,mask) ((port) |= _BV(mask))
#define clear_bit(port,mask) ((port) &= ~_BV(mask))
#define invert_bit(port,mask) ((port) ^= _BV(mask))
#endif




с-файл
Код

#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "main.h"

void init_io(void)
{
 DDRB = _BV(DDB1);//настройка линий
}

int main(void)
{
 cli();//запрет прерываний
 init_io();//инициализация портов
 TCCR1B = 1;//инициализация таймера
 TCNT1 = 64535;
 TIMSK = 4;
 SREG = 128;
 sei();//разрешение прерываний
 while(1);//цикл
 {
 }
}

INTERRUPT(SIG_OVERFLOW1)//обработчик таймера1
{
 TCNT1 = 64535;
 invert_bit(PORTB,PB1);
 TIFR = 0;
}


Автор: Mazzi 8.7.2008, 12:57
В отладчике пройдись, убедись, что правильно настроен порт на вывод. Если не поможет, то
попробуй написать вот так

Код

INTERRUPT(SIG_OVERFLOW1)//обработчик таймера1
{
 TCNT1 = 64535;
    PB1 = ~PB1;
 TIFR = 0;
}


Или попробуй инкрементировать 8-разр. переменную и полностью выводить в порт.
Сядь осциллографом на выводы и посмотри.

Удачи!

Автор: Ofer 8.7.2008, 13:13
После того, как произошло прерывание происходит переход в начало программы. В чем дело???

Цитата(Mazzi @  8.7.2008,  12:57 Найти цитируемый пост)
Сядь осциллографом на выводы и посмотри.

Это на все на эмуляторе. Физически устройства нет smile

Строка
    PB1 = ~PB1;

дает ошибку
main.c:30: error: lvalue required as left operand of assignment

Автор: Mazzi 8.7.2008, 13:38
К сожалению у меня нет WINAVR. 

Если пришлёшь все файлы, могу попробовать в CVAVRStudio.

Автор: Ofer 8.7.2008, 13:42
Я как раз проверяю на AVRStudio 4. Все те же ошибки. А файлов то всего два. Весь исходный код в первом посте выложен.

Добавлено через 8 минут и 25 секунд
Правильно ли вообще у меня описан вызов прерывания?
Как кроме этого обработчика сделать обработчики на прерывания от совпадений и др.?

Автор: cardinal 8.7.2008, 19:09
Цитата(Ofer @  8.7.2008,  12:13 Найти цитируемый пост)
Строка
    PB1 = ~PB1;

дает ошибку

PORTB ^= 0x01

Автор: Ofer 8.7.2008, 22:49
Все до ужаса просто. Запись

Цитата(Ofer @  8.7.2008,  12:44 Найти цитируемый пост)
INTERRUPT(SIG_OVERFLOW1)


"устаревшая" . Надо 
Код

  ISR(TIMER1_OVF_vect)


Благодарю всех за посильную помощь! Спасибо!

Автор: Masyanya 28.7.2008, 10:08
Цитата(cardinal @ 8.7.2008,  19:09)
Цитата(Ofer @  8.7.2008,  12:13 Найти цитируемый пост)
Строка
    PB1 = ~PB1;

дает ошибку

PORTB ^= 0x01

Если PB1, то так:
PORTB ^= 0x02

Автор: cardinal 28.7.2008, 10:25
Masyanya, там важен принцип smile 

Автор: Семен78 19.8.2008, 23:37
Цитата(Ofer @  8.7.2008,  22:49 Найти цитируемый пост)
"устаревшая" . Надо код C++1:  ISR(TIMER1_OVF_vect)


  я тоже  с этим парился 
  подскажи где  узнать все новшества?

Автор: Mazzi 20.8.2008, 08:48
Как правило на сайте разработчика компилятора есть масса примеров, и если компилятор развивается, то примеры достаточно свежие.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)