Search code examples
cinterruptavratmega

ATmega328p, interrupt from timer0


I have problem with interrupt from timer0 in µC ATmega328p. Program doesn't show on LCD anything when interrupt invoke function showOnScreen(). When function showOnScreen() is invoked in main loop, everything works. Any ideas why it doesn't work when I use interrupt?

int main(void){
    DDRD = 0xf0;
    PORTD = 0x0f;

    LCD_Initalize();
    LCD_Clear();
    LCD_Home();

    i2cSetBitrate(100);

    DS3231_init();
    DS3231_setTime(0 ,0 ,0);
    DS3231_setDate(0, 1, 1, 1);

    showOnScreenInit();
    sei();
    while(1) {
        button();
    }
    return 0;
}

ISR(TIMER0_COMPA_vect){
showOnScreen();
}

void showOnScreenInit(void){
    TCCR0A |= (1<<WGM01); //CTC
    TCCR0A |= (1<<CS02)|(1<<CS00);// prescaler 1024
    OCR0A = 100; 
    TIMSK0 |= (1<<OCIE0A); //compare match
}

EDIT: I check TCNT0 register and, this register is equal to 0 all the time, so clock doesn't started.

void showOnScreen(void){
    if (menuFlag == 0){
        DS3231_getDateTime(&dateTime);
        LCD_Clear();
        show_time(&dateTime);
    }
}

Rest functions are in DS3231 library:

void DS3231_getDateTime( TDATETIME * dt ) {
    uint8_t i;
    uint8_t buf[7];
    TWI_read_buf( DS3231_ADDR, 0x00, 7, buf );
    for( i=0; i<7; i++ ) dt->bytes[i] = bcd2dec( buf[i] );
}

void show_time( TDATETIME * dt ) {
    char time[8];
    sprintf(time, "%02d:%02d:%02d", dt->hh, dt->mm, dt->ss);
    LCD_WriteText(time);
}

Solution

  • It seems you have a typo and the clock isn't provided to the timer, so the timer remains stopped.

    Try

    TCCR0B |= (1<<CS02)|(1<<CS00);// prescaler 1024
    

    instead of

    TCCR0A |= (1<<CS02)|(1<<CS00);// prescaler 1024