Перейти к содержанию
    

почемуто в ходе выполнения прерывания

МК иногда ресетится, пробывал в ПРОТЕУСЕ, ЗАЛИЛ в девайс тажа фигня, (собака выключена, но вставки для обнуления собаки в коде присудствуют)

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

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

 

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

 

1. Запостить сюда исходник (Экстрасенсов тут нет) :)

 

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

#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");
   };
}

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Вы поняли, что вообще написали???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы поняли, что вообще написали???

 

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

 

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

Вот по вочдогу и ресетится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

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

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:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Повторяю: по вочдогу ресетится, пока прерывание телепается сотни мс - вочдог никто не сбрасывает, oн ресетит проц.

 

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

Я зато вижу прямую связь между грамотностью и техническим уровнем. Как правило, если человек не усвоил правила русского языка, то и в технике он не разбирается. Потому что читал мало. Ибо грамотность обычно сама приходит к тем, кто читает книги, включая технические. :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

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

 

так?

 

А если у Вас в обработчиках прерывания стоят такие большие паузы, то когда же успеет сброситься "сторожевой пес"?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вам абсолютно правильно сказали по поводу задержек в обработчиках

прерываний - скорее всего там и проблема.

Если я правильно разглядел исходник, вы не конфигурируете WDT (оставляете по значение умолчанию), а оно соответствует ~16мс.

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

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

А обработку событий перенести в основной цикл.

И не забывать о периоде WDT. Если процедура длинная (по времени естес-но) вставить код сброса WDT.

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

 

2 kertis

Успокойтесь, творческий подход в этом случае не поможет :)

У этого проца НЕТ возможности узнать причину сброса.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вам абсолютно правильно сказали по поводу задержек в обработчиках

прерываний - скорее всего там и проблема.

Если я правильно разглядел исходник, вы не конфигурируете WDT (оставляете по значение умолчанию), а оно соответствует ~16мс.

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

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

А обработку событий перенести в основной цикл.

И не забывать о периоде WDT. Если процедура длинная (по времени естес-но) вставить код сброса WDT.

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

 

Последовал советам делаю следующие

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

WDTCR=0x00;

 

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

 

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

 

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

 

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

 

1. в AT90S2313 фузов НЕТ

2. собака проинициализированиа по шиту как выключена нафиг 0х00

3. в цикле сравнения каждого байта ключа есть сброс собаки

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...