Search code examples
reststackembeddedavr

Problem AVR stuck and program counter lost ...?


I am facing a strange behavior i am working on project using ATMEL MCU (ATMEGA328p) with huge amount with strings so i stored it in flash memory and during run time i read it from flash memory and send it via UART. i don't know if this the problem or not because i was using the same technique before in other projects but what is different here the amount of strings larger than before.

void PLL_void_UART_SendSrting_F(U8_t* RXBuffer,const char * str , U8_t UART_No)
{
    unsigned int _indx=0;
    memset(RXBuffer,'\0', A9G_RX_Index);    // Initialize the string
    RXBuffer[A9G_RX_Index-1]='\0';

    //  cli();
    while((RXBuffer[_indx]=pgm_read_byte(&(*str))))
    {
        str++;
        _indx++;
        _delay_ms(5);
    }
    //  sei();
    PLL_void_UART_SendSrting(RXBuffer,0);

} 

But after awhile the whole program stuck and even after doing hard reset , to work again i should unplug and plug the power again.

Notes :- - I am sure that hard reset working - I am using timers in background as system tick .


Solution

  • Thank you for support I found the issues, it was because watch dog timer keep the MCU in restart mode even when i press the hardware rest. this is because, i was considering all registers,flags back to its default value after rest.WDT Block Digram

    i was doing that in code when MCU start execution the code like that :

    U8_t PLL_U8_System_Init()
    {
    static U8_t SetFalg=0;
    
    PLL_void_TimerInit();                               // General Timer Initialize                         
    PLL_WDT_Init();                                     // Initialize WDT and clear  WDRF 
    wdt_enable(WDTO_8S);                                // Enable WDT Each 2 S
    ........
    }
    

    but once WDT occurred and rest the program then CPU found WDRF flag is set so it keep in rest for ever since i did power rest.

    Solution i have to clear WDT timer once program start first, before execute any code and its work

    U8_t PLL_U8_System_Init()
    {
    static U8_t SetFalg=0;
    
    PLL_void_TimerInit();                               // General Timer Initialize                         
    PLL_WDT_Init();                                     // Initialize WDT and clear WDRF   
    wdt_enable(WDTO_8S);                                // Enable WDT Each 2 S
    ........
    }
    

    this is what written in data sheet

    Note:  If the Watchdog is accidentally enabled, for example by a runaway pointer or brown-out condition, the device will be reset and the Watchdog Timer will stay enabled. If the code is not set up to handle the Watchdog, this might lead to an eternal loop of timeout resets. To avoid this situation, the application software should always clear the Watchdog System Reset Flag (WDRF) and the WDE control bit in the initialization routine, even if the Watchdog is not in use.