VideoHelp Forum
+ Reply to Thread
Results 1 to 2 of 2
Thread
  1. I have AVR Atmega328p which I want to blink for 5 secs every 16 secs (to test the watchdog interrupts).

    Then how to bootloader atmega328p

    I have the following code, which keeps restarting, and the last line is:

    test_blink(2);

    Which I know because the led on PC2 is always on. Where did I wrong? I re-checked the WD settings for 10s times already..

    #define F_CPU 128000

    // LED Definitions
    #define LED_PORT PORTD
    #define LED_PIN PD6
    #define LED_DDR DDRD
    #define LED_PWM_PCNT 50

    // Watchdog definitions
    // counter = 2*8 = 16 seconds
    #define WD_COUNTER_MAX 2

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/sleep.h>
    #include <stdint.h>
    #include <util/delay.h>
    #include <avr/wdt.h>

    // Global watchdog counter (for wake-up counts)
    volatile uint8_t watchdog_counter;

    // Function declarations [may split to files]
    void reset_pins();
    void led_blink();
    void sleep_me();
    void setup_init();
    void test_blink(int pin);
    void setup_watchdog(uint8_t state);

    void led_blink()
    {
    LED_DDR = (1<<LED_PIN);
    LED_PORT = (1<<LED_PIN);
    _delay_ms(5000);
    }

    void test_blink(int pin)
    {
    reset_pins();
    DDRC |= (1<<pin);
    PORTC |= (1<<pin);
    _delay_ms(300);
    reset_pins();
    }

    void reset_pins()
    {
    DDRB = 0;
    DDRC = 0;
    DDRD = 0;
    PORTB = 0;
    PORTC = 0;
    PORTD = 0;
    }

    void setup_watchdog(uint8_t state)
    {
    // Watchdog:
    // Clear WD reset flag
    MCUSR = 0;

    WDTCSR = (1 << WDCE) | (1 << WDE);
    if (state == 0) {
    WDTCSR = 0;
    } else {
    WDTCSR = (1<<WDP3) | (1<<WDP0) | (1<<WDIE);
    }
    wdt_reset();
    test_blink(2);
    }

    void sleep_me()
    {
    ADCSRA = 0;
    reset_pins();
    PRR = 0xff;

    // Set sleep mode to POWER DOWN
    SMCR |= (1 << SM1);
    // Enable SLEEP
    SMCR |= (1<<SE);

    // Enable global interrupts.
    sei();

    // Disable pull-up resistors
    SMCR |= (1<<PUD);

    test_blink(2);
    setup_watchdog(1);
    sleep_cpu();
    }

    void setup_init()
    {
    watchdog_counter = 0;
    setup_watchdog(1);
    }

    // watchdog interrupt
    ISR(WDT_vect) {
    setup_watchdog(0);
    }

    int main(void)
    {
    cli();
    setup_init();
    test_blink(4);
    while(1)
    {
    cli();
    // Disable SLEEP
    SMCR &= ~(1<<SE);

    if (watchdog_counter >= WD_COUNTER_MAX) led_blink();
    else sleep_me();

    watchdog_counter++;
    }
    }

    I am using the following fuses, and avrdude command:

    avrdude -B 250 -c usbtiny -P usb -p m328p -U lfuse:w:0xD3:m -U hfuse:w:0xDF:m -U efuse:w:0x07:
    Quote Quote  
  2. I ran your code with the clock set to the internal 128KHz clock (via the fuses). I verified the CPU was running at 128 KHz. But I was seeing WD interrupts every 30 ms (by pulsing an output pin within the ISR and watching it with a scope). The problem is too much time is passing between writing the WD prescale enable bits and writing to the prescale bits. Change this:

    Code:
    WDTCSR = (1 << WDCE) | (1 << WDE);
    if (state == 0) {
        WDTCSR = 0;
    } else {
        WDTCSR = (1<<WDP3) | (1<<WDP0) | (1<<WDIE);
    }
    to this:

    Code:
    if (state == 0) {
        WDTCSR = (1 << WDCE) | (1 << WDE);
        WDTCSR = 0;
    } else {
        WDTCSR = (1 << WDCE) | (1 << WDE);
        WDTCSR = (1<<WDP3) | (1<<WDP0) | (1<<WDIE);
    }
    You also need to set watchdog_counter back to zero after led_blink() in main().

    The timing may still be not quite right. I'm seeing the LED on for 5 seconds off for about 9. I'm sure you can track that down yourself.

    Some other issues:

    That reset_pins() is really nasty. I would initialize the pins at startup and turn individual pins off/on as necessary.

    I wouldn't call a slow function like test_blink() (twice!) within an ISR.
    Last edited by jagabo; 24th Jun 2017 at 00:29.
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!