tommy писал(а):
wtf?! и как это всё видится в ide через jtag? т.е. если пошагово выполнять, то заходит сначала в первые операторные скобки, а потом и во вторые? а так - эт либо это косяк компилятора, что маловероятно, тк в таком случае это будет видно в .lss файле, либо ошибка не там.
Именно так!
Сначала выполняются операторы в первых скобках (if), а затем,с чистой совестью, контроллер выполняет операторы в скобках else!
Именно при пошаговой отладке и обнаружил сей баг!
Или я уже настолько забыл Си, что синтаксис нарушаю?!
Вот конкретный глючный кусок кода:
Код:
/**************************************************************************************
* Обработчик прерываний timer1A
***************************************************************************************/
ISR(TIMER1_COMPA_vect){
TIMSK &=~_BV(OCIE1A);
sei();
if (bullets >0)//если патроны не кончились
{
if (last_simple == 0)
{
fire_led_status=ON; //включаем вспышку
// if (fire_mode()==queues) fire_led_status=FQR_4HZ;
// else fire_led_status=ON; //включаем вспышку
}
if (last_simple < sizeof(pSnd))//3913
{
if (last_simple==(sizeof(pSnd)/100)*CUT_OFF_SOUNT)
{
if (fire_mode()==queues)
{
if ((get_keyboard_status()==key_pressed)&&(life>0)) //курок нажат, то отсекаем звук
{
bullets--;//уменьшаем на 1 количество патронов
send_ir_package(); //Производим "выстрел"
last_simple=0; //воспроизводим звук сначала
fire_led_status=FQR_4HZ;
}
else fire_led_status=ON;
}
}
OCR0 = pgm_read_byte(&(pSnd[last_simple++]));
}
else
{
// last_simple = 0;
// PORTA &= ~(1 << 2);
OCR0 = 128; //Скважность = 0,5
fire_led_status=OFF;
//FIRE_LED_OFF;
}
}
else //патроны кончились
{
BULLETS_OUT_LED_ON; // включаем светодиод "Патроны кончились"
if (last_simple < sizeof(pSnd)) OCR0 = pgm_read_byte(&(pSnd[last_simple++]));//дадим выстрелу прозвучать до конца
else fire_led_status = OFF; //СЮДА ЛЕЗЕТ, ДАЖЕ ЕСЛИ bullets >0!!!!
}
Пришлось переписать этот кусок так:
Код:
/**************************************************************************************
* Обработчик внещних прерываний timer1A
***************************************************************************************/
ISR(TIMER1_COMPA_vect){
TIMSK &= ~_BV(OCIE1A); //запрещаем прерывания timer1, чтобы не было рекурсии
sei();
if (bullets >0)//если патроны не кончились
{
if (last_simple == 0)
{
fire_led_status=ON; //включаем вспышку
// if (fire_mode()==queues) fire_led_status=FQR_4HZ;
// else fire_led_status=ON; //включаем вспышку
}
else;
if (last_simple < sizeof(pSnd))//3913
{
if (last_simple==(sizeof(pSnd)/100)*CUT_OFF_SOUNT)
{
if (fire_mode()==queues)
{
if ((get_keyboard_status()==key_pressed)&&(life>0)) //курок нажат, то отсекаем звук
{
bullets--;//уменьшаем на 1 количество патронов
send_ir_package(); //Производим "выстрел"
last_simple=0; //воспроизводим звук сначала
fire_led_status=FQR_4HZ;
}
else fire_led_status=ON;
}
else;
}
else;
OCR0 = pgm_read_byte(&(pSnd[last_simple++]));
}
if (last_simple >= sizeof(pSnd)&&(last_simple)!=0xFFFF)//3913
{
// last_simple = 0;
// PORTA &= ~(1 << 2);
OCR0 = 128; //Скважность = 0,5
fire_led_status=OFF;
//FIRE_LED_OFF;
};
}
if (bullets <= 0) //патроны кончились
{
BULLETS_OUT_LED_ON; // включаем светодиод "Патроны кончились"
if (last_simple < sizeof(pSnd)) {OCR0 = pgm_read_byte(&(pSnd[last_simple++]));}//дадим выстрелу прозвучать до конца
else fire_led_status = OFF;
};
Или я просто запутался в if else?
Где ошибка?
Есть у меня подозрения, что это связано с тем, что я прерывания разрешаю и где то в других обработчиках меняется значение регистра статуса, но, разве компилятор не сохраняет регистры при вызове обработчика?
Да и тогда, когда я не разрешал прерывания, вроде то же самое было.
Надо перепроверить!