0
\$\begingroup\$

I am currently working with ATTiny1634, executing the following code

After executing break statement the program is not exiting from the inner while loop to outer while loop; instead, it jumps to main function.

To test, I removed all the USART functions uart_init, writecommand, transmit, after removing all these function code is working perfectly.

The code works with ATMega16A, but getting problem in ATTiny1634. Why?

int main()
{   
    DDRC=1<<DDRC0;
    DDRA|= 1<<PORTA3;
    uart_init();
    sei();  
    writecommand("AT");

    writecommand("ATE0");
while (1)

  {
    int8_t t;
    PORTA=1<<PORTA3;
    // controller sleep mode
        if(MCUSR & (1<<WDRF))
        {
            MCUSR&= ~(1<<WDRF);
            WDTCSR|= 1<<WDE;
            WDTCSR= 0x00;
        }
        PORTA=0<<PORTA3;
        set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode selected
            //PRR=0X75;
            wdt_reset();
            WDTCSR |= 1<<WDE;           
            WDTCSR |= (1<<WDIE|1<<WDP3 |1<<WDP0); // ENABLE WATCH DOG TIMER INTERRUPT WITH 8S TIME OUT          
        sleep_enable();  //set SE bit   
        sei();  
        sleep_cpu(); //sleep mode activated

      while (1)
        {
         if(count >=2) // 80S DELAY
           {
            count=0;
            sleep_disable();   // SE bit reset
            WDTCSR|=0<<WDE|0<<WDIE; // disable watch dog timer
            transmit("AT+CFUN=1\r\n");
            _delay_ms(2000);            
            clearbuffer(buff);
            clearbuffer(temp_buff);
            _delay_ms(2000);
            break;
           }
         else
          {
            WDTCSR|=1<<WDIE;
            sleep_cpu();
          }         
        }

    }    

} 

The code for writecommand: void writecommand(char *q) {

    char str[3]="OK";
    char str1[50];
    do
    {
        clearbuffer(str1);
        strcpy(str1,q);

        i=0;
        _delay_ms(10);
        clearbuffer(buff);
        clearbuffer(temp_buff);
        transmit(str1);
        transmit("\r\n");
        _delay_ms(200);
        for(j=10;j>0;j--)
        _delay_ms(10);
        logic();   // my me
        clearbuffer(buff);        

    }while(strcmp(str3,str)!=0);    

I am using the 8 MHz internal osc and the baud rate in USART is 9600. Other functions are:

void uart_init()
{
    UCSR0B=(1<<TXEN0)|(1<<RXEN0)|(1<<RXCIE0); //transmitter enable,receiver enable,receive complete interrupt enable
    UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);//8 bit data bits  
    UBRR0L=51; // baud rate 9600
}
void uart_send(unsigned char ch)
{
    while(!(UCSR0A &(1<<UDRE0)));
    UDR0=ch;
}
void transmit(char *p)
{
    i=0;
    while(*p!='\0')
    {
        uart_send(*p);
        p++; 
    }
}
void clearbuffer(char *p)
{
    while(*p!=0)
    {
        *p=' ';
        p++;
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ Since you're playing with the watchdog here, I'm assuming your UART code either has a bug or is too slow, so you get a reset. Debugging your code is both impossible (it's not complete) and something I wouldn't consider doing anyway. \$\endgroup\$ Commented Sep 12, 2016 at 10:35

1 Answer 1

0
\$\begingroup\$

Whenever you change from one processor to another, EVERY reference to a peripheral needs to be re-examined. Your code is a perfect example - it is full of Watchdog-specific code, and any change could cause the new processor to behave strangely.

Do you know what a Watchdog timer is? It is inside the controller, and its sole purpose is to reset the microcontroller back to the beginning of main(). That is all it does, and the only thing that can stop it is if the code "pats" the Watchdog before it times out. The idea is that you carefully structure your program so that it "pats" the Watchdog every so often - if it doesn't, then the code is bad and the microcontroller resets.

The code given even has a bug inside it:

    WDTCSR|= 1<<WDE;
    WDTCSR= 0x00;

This code carefully sets up bits inside the "WatchDog Timer Control/Status Register (WDTCSR)" - then zeroes it. Ummm... what?

In short, it is difficult to take existing code for one processor and simply execute it on a different one and expect it to work. Until you do, I would recommend that you comment out ALL code that references the Watchdog, until you get the rest of your code working.

\$\endgroup\$
7
  • \$\begingroup\$ sir i instead of using this command WDTCSR|=0<<WDE|0<<WDIE; \$\endgroup\$ Commented Sep 12, 2016 at 11:31
  • \$\begingroup\$ That is even worse. It does absolutely nothing: you are ORing 0 into a variable, which leaves... exactly the same value. If you want to zero those variables, you need to instead do WDTCSR &= ~(0<<WDE|0<<WDIE); - or not set them in the first place... \$\endgroup\$ Commented Sep 12, 2016 at 11:34
  • \$\begingroup\$ sir i instead of using this command WDTCSR|=0<<WDE|0<<WDIE; i used wdt_disable to disable the wdt.now it not jumping to main function. it is just exiting the inner while loop.(i also omit the bug you talked about) The reason m not getting because in data sheet what i read if we set WDE bit && WDIE bit of WDTCSR to 0(zero),the wdt will stop and no action at the time of timeout.but when i used the predefined command it works why? \$\endgroup\$ Commented Sep 12, 2016 at 11:41
  • \$\begingroup\$ Whoops! I wasn't thinking. My line should have been WDTCSR &= ~(1<<WDE|1<<WDIE); \$\endgroup\$ Commented Sep 12, 2016 at 11:46
  • \$\begingroup\$ The wdt is getting disable correctly with wdt_disable command.i even tried both the line u have told, still was jumping to main function.i really wanna knw the reason why this was happening. \$\endgroup\$ Commented Sep 12, 2016 at 11:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.