Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: почемуто в ходе выполнения прерывания
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
TamTam
МК иногда ресетится, пробывал в ПРОТЕУСЕ, ЗАЛИЛ в девайс тажа фигня, (собака выключена, но вставки для обнуления собаки в коде присудствуют)

Почему МК ресетится и как можно узнать из за чего ????
andk
1. Запостить сюда исходник (Экстрасенсов тут нет) smile.gif
TamTam
Цитата(kertis @ Jun 6 2006, 06:58) *
Цитата(TamTam @ Jun 6 2006, 06:36) *

Почему МК ресетится и как можно узнать из за чего ????


источник сброса можно узнать в специальном регистре.

в мастере начального кода CVAVR есть пунктик - сделать код для выяснения этого.


Это понятно но для AT90S2313 такой галки нет.

Цитата(andk @ Jun 6 2006, 06:52) *
1. Запостить сюда исходник (Экстрасенсов тут нет) smile.gif


Вот сурц, (сильно не пинать я только учусь)
Код
#define DEBUG

/*****************************************************
При первом включение
1. перед запуском установить перемычку между 1 и 2 контактом
2. каснуться ключом лузы (что приведет к стиранию всех ключей)
3. переставить перемычку на контакты 3 и 4 (добовление новых ключей)
4. мк перейдет в режим программирования новых ключей
5. поднести по очереди 1 до 4 ключей
6. убрать перемычку, устройство готово к работе.
*****************************************************/

#include <90s2313.h>
#include <1wire.h>                                         // Функции однопроводной шины
#include <stdio.h>                                         // Функции ввода вывода
#include <delay.h>                                         // Функции задержек
#include <key.h>

#define DS1990_FAMILY_CODE 1                               // Код симейства для DS1990 - 01
#define DS1996_FAMILY_CODE 0x0C                            // Код симейства для DS1990 - 0C
#define SEARCH_ROM 0xF0                                    // Команда поиска
#define MAX_DEVICES 1                                      // Макс. колличество устройств инф. о которых будет сохр.
unsigned char rom_code[MAX_DEVICES][9];                    // Массив с инфомацией о ключах

#define TOCH_MEMORY_LED_ON      PORTB |= (1<<0);           // Включить индикатор (подключенный к PB0)
#define TOCH_MEMORY_LED_OFF     PORTB &= ~(1<<0);          // Выключить индикатор (подключенный к PB0)
#define TOCH_MEMORY_LED_INV     PORTB ^= (1<<0);           // Инверсия индекатора (подключенный к PB0)

//#define ALARM                   byte_read(127);            // Посмотреть в каком состояние флаг тревоги.
#define CHANGE_ALARM            byte_write(127, byte_read(127) ^ 0x01); // Инверсия флага тревоги
//#define ARMED                   byte_read(126);            // Посмотреть в каком состояние флаг охраны.
//#define CHANGE_ARMMED           byte_write(126, byte_read(126) ^ 0x01); // Инверсия флага постановки на охрану
//#define FIRST_RUN               byte_read(125);            // Посмотреть в каком состояние флаг первого запуска.

unsigned int call_time=0;
char call_count=0;

#define END_ALL_CALLS           putsf("\x41\x54\x48\x30"); // ATH0 завершить звонок

// 1 Wire Bus functions
#asm
   .equ __w1_port=0x12;PORTD
   .equ __w1_bit=2
#endasm

void alarm(void);
void ind_code (unsigned char tick, unsigned char HI_AMPLITUD, unsigned char LO_AMPLITUD);
void call_to (void);

void alarm(void)
{
//SIREN_ALARM;
while (byte_read(127)==1) // будем выполнять пока чстановлен флаг тревоги
   {  
//      SVET_ALARM_INV;
      delay_ms(45);
//      SVET_ALARM_INV;
      delay_ms(15);
      call_to();
      #ifdef DEBUG
      putsf("ALARM!!!!\n\r");
      #endif
   }        
//SIREN_ALARM;
//SVET_ALARM_OFF;
//TOCH_MEMORY_LED_OFF;  
}


void ind_code (unsigned char tick, unsigned char HI_AMPLITUD, unsigned char LO_AMPLITUD)
{
unsigned char i;
TOCH_MEMORY_LED_OFF;
for (i=0;i<=tick;i++)
   {    
      TOCH_MEMORY_LED_ON;
      delay_ms(HI_AMPLITUD);
      TOCH_MEMORY_LED_OFF;
      delay_ms(LO_AMPLITUD);
   }
}



void call_to (void)
{
call_time++;
TOCH_MEMORY_LED_INV;
   if (call_count>=0 && call_count<=2)
      {
         if (call_time==1) putsf("F");
         if (call_time==3000) putsf("S");
         if (call_time==7000) putsf("D");
//         if (call_time==3000)// putsf("A");
//         if (call_time==4000)// putsf("V");
         if (call_time==65500)
            {
               call_time=0;
               call_count++;
            }    
      }
}

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
char i=0;
if (PIND.3==1) i++;
delay_ms(25);
if (PIND.3==1) i++;
delay_ms(25);
if (PIND.3==1) i++;
delay_ms(25);
if (PIND.3==1) i++;
delay_ms(25);
if (i>=3)
   {
      GIMSK=0x40;
      MCUCR=0x00;
      GIFR=0x40;
      byte_write(127,1);
      #asm("sei")
      
      #ifdef DEBUG
      putsf("ALARM!!!!\n\r");
      #endif
      alarm();
   }      
}

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
unsigned char devices;
//#asm("cli")
delay_ms(50);
if (PINB.5==1)                            // Затираем все ключи в памяти
   {
      #ifdef DEBUG
      putsf("START CLEAR KEY MEM !!!\n\r");
      #endif  
      set_count(0);
      
   }
   else
   {
devices=w1_search(SEARCH_ROM,&rom_code[0,0]);
if (devices!=0)
   if (rom_code[0][0]==DS1990_FAMILY_CODE)
      {
         if (PINB.7==1)                            // Добавляем несуществующий ключь в память
            {
               #ifdef DEBUG
               putsf("START ADD KEY TO MEM !!!\n\r");
               #endif            
               if (add_key(&rom_code[0,0])==1)
                  {
                     ind_code(5,500,500);
                     #ifdef DEBUG
                     putsf("OK !!!\n\r");
                     #endif                          
                  }
                  else
                  {
                     ind_code(10,250,250);
                     #ifdef DEBUG
                     putsf("ERROR !!!\n\r");
                     #endif      
                  }                
            }
         if ((PINB.7==0) && (PINB.5==0))           // Проверяем валидность ключа
            {
               #ifdef DEBUG
               putsf("START CHACK KEY IN MEM !!!\n\r");
               #endif            
               #asm("wdr");
               if (find_key_in_mem(&rom_code[0,0])==1)
                  {
                     #ifdef DEBUG
                     putsf("CHACK KEY IS TRUE !!!\n\r");
                     #endif
                     ind_code(20,300,300);
                     if ((byte_read(126)==1) && (byte_read(127)==1)) // если на охране и сработало
                        {                                          // то принять тревогу и оставить на охране
                           byte_write(127,0);
                           GIMSK=0xC0;
                           MCUCR=0x0C;
                           GIFR=0xC0;
                           TOCH_MEMORY_LED_ON;
                           #ifdef DEBUG
                           putsf("UNALARM ARMED !!!\n\r");                          
                           #endif
                        }
                        else                                       // в противном случае
                        {
                           if (byte_read(126)==1)                  // если на охране и нет сработки
                              {                                    // то снять с охраны
                                 byte_write(126,0);                          
                                 GIMSK=0x40;
                                 MCUCR=0x00;
                                 GIFR=0x40;
                                 TOCH_MEMORY_LED_OFF;
                                 #ifdef DEBUG
                                 putsf("UNARMED !!!\n\r");
                                 #endif
                              }
                              else                                 // в противном случае
                              {
                                 if (byte_read(126)==0)                              
                                    {                              // тогда поставить на охрану
                                       byte_write(126,1);
                                       GIMSK=0xC0;
                                       MCUCR=0x0C;
                                       GIFR=0xC0;
                                       TOCH_MEMORY_LED_ON;
                                       #ifdef DEBUG
                                       putsf("ARMED !!!\n\r");
                                       #endif
                                    }
                              }
                        }
                  }
                  else
                  {
               #ifdef DEBUG
               putsf("CHACK KEY IS FALSE OUT!!!\n\r");
               #endif                                        
                    ind_code(5,500,50);
                  }                
            }                
      };
      }
#asm("sei")      
}


void main(void)
{
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=T State6=P State5=T State4=0 State3=0 State2=0 State1=0 State0=0
PORTB=0x40;
DDRB=0x1F;


// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Low level
// INT1: Off
GIMSK=0x40;
MCUCR=0x00;
GIFR=0x40;

// UART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// UART Receiver: Off
// UART Transmitter: On        

// UART Baud rate: 19200
UCR=0x08;
UBRR=0x23;

// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/2048k
// WDTCR=0x0f;

// 1 Wire Bus initialization
w1_init();

#ifdef DEBUG
putsf("START BOOT PROGRAM !!!\n\r");
#endif  
if (byte_read(0)==0xff) byte_write(0,0x00);
if (byte_read(0)==0)
   {
      #ifdef DEBUG
      putsf("FIRST RUN !!!\n\r");
      #endif        
      byte_write(126,0);
      byte_write(127,0);        
      ind_code(10,500,500);
   }
   else
   {
      if (byte_read(126)==1)          // если устройство стоит на охране
         {
            TOCH_MEMORY_LED_ON;       // зажечь светодиод
            #ifdef DEBUG              
            putsf("ARMED !!!\n\r");  
            #endif                    
            if (byte_read(127)==1)    // если флаг тревоги установлен то перешодим в состояние тревога
               {
                  GIMSK=0x40;         // тогда отключаем прерывание по сработке шлейфа
                  MCUCR=0x00;          
                  GIFR=0x40;
                  #asm("sei")
                  #ifdef DEBUG
                  putsf("ALARM FROM BOOT!!!!\n\r");
                  #endif
                  alarm();            // и включаем тревогу
               }
            else                      // а елси не установлен тогда
               {
                  GIMSK=0xC0;         // разрешить все прерывания
                  MCUCR=0x0C;
                  GIFR=0xC0;
               }
         }
   };

// Global enable interrupts
#asm("sei")

#ifdef DEBUG
putsf("PROGRAM IS LOAD !!!\n\r");
#endif  

while (1)
   {
#asm("wdr");
   };
}


Реситится он тогда - когда в режиме тревоги происходит чтение ключа.
WHALE
Поставь VMLAB-он понимает еер и прогони в нем.
TamTam
Цитата(WHALE @ Jun 6 2006, 08:40) *
Поставь VMLAB-он понимает еер и прогони в нем.


Прогонял на макетке там и заполил что он перезбрасывается.
haker_fox
Цитата(TamTam @ Jun 6 2006, 13:55) *
Цитата(WHALE @ Jun 6 2006, 08:40) *

Поставь VMLAB-он понимает еер и прогони в нем.


Прогонял на макетке там и заполил что он перезбрасывается.

Вы поняли, что вообще написали???
=AK=
Цитата(TamTam @ Jun 6 2006, 13:28) *
Реситится он тогда - когда в режиме тревоги происходит чтение ключа.

Oбработки прерываний занимают огромное время - с какого-то бодуна там везде стоят огромные задержки. "Вредных советов" начитались?
TamTam
Цитата
Вы поняли, что вообще написали???


Ну вообщето да, а что есть какието сомнения.

Цитата(=AK= @ Jun 6 2006, 10:18) *
Цитата(TamTam @ Jun 6 2006, 13:28) *

Реситится он тогда - когда в режиме тревоги происходит чтение ключа.

Oбработки прерываний занимают огромное время - с какого-то бодуна там везде стоят огромные задержки. "Вредных советов" начитались?


А почемубы им не занимать столько сколько они занимают ??? ведь кроме этого он ничего не делает.
=AK=
Цитата(TamTam @ Jun 6 2006, 15:57) *
А почемубы им не занимать столько сколько они занимают ??? ведь кроме этого он ничего не делает.

Потому что писать в таком стиле - значит ходить по граблям. Прерывания всегда "интерферируют" с основной прогой, а иногда и друг с другом. Чем дольше исполняется обработка прерывания - тем сильнее "интерференция по времени", т.к. время исполнения основного кода становится нeвозможно предсказать (например, управление вочдогом летит к чертям, и т.п.). Чем длиннее код обработки прерывания - тем больше вероятность "интерференции по коду", т.е. неатомарный доступ к переменным, неучтенный захват ресурсов (портов и пр.), и т.д.

Вот по вочдогу и ресетится.
haker_fox
Цитата(TamTam @ Jun 6 2006, 15:27) *
Цитата(=AK= @ Jun 6 2006, 10:18) *

Цитата(TamTam @ Jun 6 2006, 13:28) *

Реситится он тогда - когда в режиме тревоги происходит чтение ключа.

Oбработки прерываний занимают огромное время - с какого-то бодуна там везде стоят огромные задержки. "Вредных советов" начитались?


А почемубы им не занимать столько сколько они занимают ??? ведь кроме этого он ничего не делает.

Ну и что, что кроме этого они ничего не делают? В нижеприведенном фрагменте кода полная ерудна, у Вас там в общей сложности задержка на 100 мс! И в какое время должны успевать выполнять ся другие обработчики прерываний?

Код
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
char i=0;
if (PIND.3==1) i++;
delay_ms(25);
if (PIND.3==1) i++;
delay_ms(25);
if (PIND.3==1) i++;
delay_ms(25);
if (PIND.3==1) i++;
delay_ms(25);
TamTam
Цитата(haker_fox @ Jun 6 2006, 10:57) *
Цитата(TamTam @ Jun 6 2006, 15:27) *


Цитата(=AK= @ Jun 6 2006, 10:18) *

Цитата(TamTam @ Jun 6 2006, 13:28) *

Реситится он тогда - когда в режиме тревоги происходит чтение ключа.

Oбработки прерываний занимают огромное время - с какого-то бодуна там везде стоят огромные задержки. "Вредных советов" начитались?


А почемубы им не занимать столько сколько они занимают ??? ведь кроме этого он ничего не делает.

Ну и что, что кроме этого они ничего не делают? В нижеприведенном фрагменте кода полная ерудна, у Вас там в общей сложности задержка на 100 мс! И в какое время должны успевать выполнять ся другие обработчики прерываний?

Код
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
char i=0;
if (PIND.3==1) i++;
delay_ms(25);
if (PIND.3==1) i++;
delay_ms(25);
if (PIND.3==1) i++;
delay_ms(25);
if (PIND.3==1) i++;
delay_ms(25);



невижу никакой связи между праблемой и задержками так как прерывания всего 2 одно из них, то из которого вы зделали выдержку отвечает за разрыв шлейфа, а другое за чтения ключа точь мемори, и одновремено они врядли когда нибудъ произойдут.

P.S. а то блин развели базар, про мусор, сам спросил сам ответил. не знаю я сам ответ на этот вопрос и не имею никакого понятия как его решить, может трабл со схемотехникой, Резюками подтянуты к плюсу обе ножки по которым происходит прерывания (4к7). ohmy.gif
=AK=
Повторяю: по вочдогу ресетится, пока прерывание телепается сотни мс - вочдог никто не сбрасывает, oн ресетит проц.

Цитата(TamTam @ Jun 6 2006, 16:55) *
невижу никакой связи между праблемой и задержками так как прерывания всего 2 одно из них, то...

Я зато вижу прямую связь между грамотностью и техническим уровнем. Как правило, если человек не усвоил правила русского языка, то и в технике он не разбирается. Потому что читал мало. Ибо грамотность обычно сама приходит к тем, кто читает книги, включая технические. biggrin.gif
haker_fox
Давайте начнем с того, что в этом форуме Вам никто и ничего не должен, тем более что в таких ситуациях не плохо бы самому разобраться, для новичка это даже и полезно. Это я про последнию фразу.

По-делу: я заметил, что Вы используете Watch Dog. Сбрасываете в главном цикле

Код
while (1)
   {
#asm("wdr");
   };


так?

А если у Вас в обработчиках прерывания стоят такие большие паузы, то когда же успеет сброситься "сторожевой пес"?
andk
Вам абсолютно правильно сказали по поводу задержек в обработчиках
прерываний - скорее всего там и проблема.
Если я правильно разглядел исходник, вы не конфигурируете WDT (оставляете по значение умолчанию), а оно соответствует ~16мс.
То есть, попадая в прерывание с задержками более чем 16мс собака гарантировано кусает.
Поэтому в прерываниях нужно делать только абсолютно необходимые действия. (В Вашем случае - установить флаг о том, что прерывание было. Все.)
А обработку событий перенести в основной цикл.
И не забывать о периоде WDT. Если процедура длинная (по времени естес-но) вставить код сброса WDT.
Сейчас в тупую можете поставить сбросы WDT в обаботчик прерывания, скорее всего поможет.

2 kertis
Успокойтесь, творческий подход в этом случае не поможет smile.gif
У этого проца НЕТ возможности узнать причину сброса.
TamTam
Цитата(andk @ Jun 6 2006, 12:12) *
Вам абсолютно правильно сказали по поводу задержек в обработчиках
прерываний - скорее всего там и проблема.
Если я правильно разглядел исходник, вы не конфигурируете WDT (оставляете по значение умолчанию), а оно соответствует ~16мс.
То есть, попадая в прерывание с задержками более чем 16мс собака гарантировано кусает.
Поэтому в прерываниях нужно делать только абсолютно необходимые действия. (В Вашем случае - установить флаг о том, что прерывание было. Все.)
А обработку событий перенести в основной цикл.
И не забывать о периоде WDT. Если процедура длинная (по времени естес-но) вставить код сброса WDT.
Сейчас в тупую можете поставить сбросы WDT в обаботчик прерывания, скорее всего поможет.


Последовал советам делаю следующие
в цикле где сравниваеться каждый байт ключа ставлю сброс собаки, и еще на всякий случай решил проинициализировать собаку
Код
WDTCR=0x00;


и все повторилось в новь.

блин ну в чемже дело ???

Мужики ну не злитесь вы на меня просто вроде все готово но есть маленький трабл, вот и нервничаю.

и так подведу краткий итог

1. в AT90S2313 фузов НЕТ
2. собака проинициализированиа по шиту как выключена нафиг 0х00
3. в цикле сравнения каждого байта ключа есть сброс собаки

но результат - инигда перезагрузка мк при проверки ключа, счас попробую переписать код, вынесу процедуру обработки ключей в отдельную, в прерывание буду менять только флаг.
TamTam
Простите дурака грешного что не хотел видеть очевидного, и так
все заработало должным образо как только я в прерывание стал выставлять флаг а в основном циклде его проверять и только потом задумаваться о ключах, попутно нашол пару багов.

ВСЕМ ОГРОМНОЕ ОГРОМНОЕ спасибо. и еще раз простите.
haker_fox
Цитата(TamTam @ Jun 6 2006, 18:35) *
Простите дурака грешного что не хотел видеть очевидного, и так
все заработало должным образо как только я в прерывание стал выставлять флаг а в основном циклде его проверять и только потом задумаваться о ключах, попутно нашол пару багов.

ВСЕМ ОГРОМНОЕ ОГРОМНОЕ спасибо. и еще раз простите.

Ну чтож, я думаю здесь Вас можно и поздравить! Видите, поиск багов - не такое уж и страшное дело smile.gif
Так держать! a14.gif
Woodoo
Цитата(TamTam @ Jun 6 2006, 11:35) *
Простите дурака грешного что не хотел видеть очевидного, и так
все заработало должным образо как только я в прерывание стал выставлять флаг а в основном циклде его проверять и только потом задумаваться о ключах, попутно нашол пару багов.

ВСЕМ ОГРОМНОЕ ОГРОМНОЕ спасибо. и еще раз простите.


Ну и поведал бы о них, чтобы другие не наступали на теже грабли.
Я ваще думал, что у тя стек переполняеться и пересекаеться с данными, и када RET делает переходит на 0. такое частенько бывает при использовании си в слабеньких кристалах.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.