Страница 1 из 1

Прерывание не меняет переменную

Добавлено: Вс сен 13, 2009 04:54:24
-==MAXCELERON==-

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

#include (avr/interrupt.h)  // скобы угловые
#include (util/delay.h)
#define F_CPU 1000000UL      // 1 MHz
char a;
 ISR(INT0_vect){  //Обработчик внешнего прерывания
 a = 0x01;  
}

int main(void){     //Главная функция
DDRC = 0xff;
PORTD = 0xff; // Подтяжка int0
MCUCR=0x02; // 00 - Прерывание при 0 уровне; 02 - при падении; 03 - при повышении
GICR  = 0b11000000;
sei ();

 while (1) {
PORTC = a;}
}
При срабатывании прерывания на порт С должна подаваться 1, но этого не происходит :cry: Объясните почему?? :oops:

Добавлено: Вс сен 13, 2009 06:40:52
Meteor
Может не хочет из-за того что указана символьная переменная char, смените на беззнаковое число unsigned int... Си язык требующий всяческих приведений переменных.

Добавлено: Вс сен 13, 2009 06:44:20
-==MAXCELERON==-
Meteor писал(а):смените на беззнаковое число unsigned int... Си язык требующий всяческих приведений переменных.
Сменил - ничего не дало :cry:

В самом обработчике, переменная меняется, но при выходе в цикле while переменная опять равна 0 :evil:

Добавлено: Вс сен 13, 2009 07:01:02
Meteor
Объявите ее глобальной staticесли не ошибаюсь

Добавлено: Вс сен 13, 2009 07:02:48
-==MAXCELERON==-
Meteor писал(а):Объявите ее глобальной
Она же и так глобальна :shock:, или можно еще глобальней ? :))

Добавлено: Вс сен 13, 2009 07:06:51
Meteor
Если мне память не изменяет, то объявление всех переменных в С, производится в основном теле программы. А не вне этого тела
int main(void){
static unsigned int a;
unsigned int b; и пр
}

Добавлено: Вс сен 13, 2009 07:12:01
-==MAXCELERON==-
Meteor писал(а):Если мне память не изменяет, то объявление всех переменных в С, производится в основном теле программы. А не вне этого тела
int main(void){
static unsigned int a;
unsigned int b; и пр
}

Да ничего подобного, если делать так, то переменная будет действовать только в пределах функции main, т.е. та что в обработчике будет вообще не объявлена и копмилятор будет ругаться!! :idea:

Добавлено: Вс сен 13, 2009 07:28:23
Neekeetos
-==MAXCELERON==- писал(а): Да ничего подобного, если делать так, то переменная будет действовать только в пределах функции main, т.е. та что в обработчике будет вообще не объявлена и копмилятор будет ругаться!! :idea:
попробуй объяви переменную как
volatile char a;

Добавлено: Вс сен 13, 2009 07:33:18
-==MAXCELERON==-
Neekeetos писал(а): попробуй объяви переменную как
volatile char a;
Спасибо!! так работает:

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

#include (avr/interrupt.h)  // скобы угловые 
#include (util/delay.h)
#define F_CPU 1000000UL      // 1 MHz 
volatile char a; 
 ISR(INT0_vect){  //Обработчик внешнего прерывания 
 a = 0x01;  
} 

int main(void){     //Главная функция 
DDRC = 0xff; 
PORTD = 0xff; // Подтяжка int0 
MCUCR=0x02; // 00 - Прерывание при 0 уровне; 02 - при падении; 03 - при повышении 
GICR  = 0b11000000; 
sei (); 

 while (1) { 
PORTC = a;} 
}
:))) :))) :)))

Добавлено: Вс сен 13, 2009 09:32:32
neonix
-==MAXCELERON==- Ты хоть понял почему так заработало ?

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

volatile char a;

Добавлено: Вс сен 13, 2009 10:56:04
Neekeetos
neonix писал(а):-==MAXCELERON==- Ты хоть понял почему так заработало ?

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

volatile char a;
Неправильный вопрос, откуда бы он мог знать что gcc/винавр в погоне за оптимизацией физически удаляет переменные если они не меняются в основном коде, а функция прерывания из мэйна не вызывается соотв переменная для компилятора выглядит как константа.

Добавлено: Вс сен 13, 2009 11:15:45
neonix
Дык собственно я и хотел попытатся заствить узнать почему не работало :) Ибо бездумное следование советам опыта не прибавит )

Добавлено: Вс сен 13, 2009 11:58:50
-==MAXCELERON==-
neonix писал(а): Ибо бездумное следование советам опыта не прибавит )
Почему бездумное?? Я подумал, запомнил 8)

Добавлено: Вс сен 13, 2009 12:35:17
Neekeetos
neonix писал(а):Дык собственно я и хотел попытатся заствить узнать почему не работало :) Ибо бездумное следование советам опыта не прибавит )
Не надо никого заставлять, он и так все правильно делает. Я с этими переменными неделю промучался пока не догадался заглянуть в ассемблер который гцц сгенерил, фишка в том что обычно компиляторы так не делают.

Добавлено: Вс сен 13, 2009 22:40:38
SII
Neekeetos писал(а):
neonix писал(а):Дык собственно я и хотел попытатся заствить узнать почему не работало :) Ибо бездумное следование советам опыта не прибавит )
Не надо никого заставлять, он и так все правильно делает. Я с этими переменными неделю промучался пока не догадался заглянуть в ассемблер который гцц сгенерил, фишка в том что обычно компиляторы так не делают.
На самом деле довольно многие компиляторы примерно так поступают, просто большинство из них не знакомо "широкой общественности", ведь основная масса программистов пишут программы на ПК и под ПК, а там такой проблемы нет. Ну а вообще, если программа ведёт себя странным образом, очень полезно не гадать, а сразу же смотреть, какой ассемблерный код был получен. Иногда, например, он попросту неверный из-за ошибок в компиляторе. Естественно, это относится к любому языку программирования на любой платформе -- совершенных вещей, увы, не существует.