2015-12-14 2 views
0

У меня проблема с прерыванием от timer0 в μC ATmega328p. Программа не показывает на ЖК-дисплее ничего, когда функция вызова прерывания showOnScreen(). Когда функция showOnScreen() вызывается в основном цикле, все работает. Любые идеи, почему это не работает, когда я использую прерывание?ATmega328p, прерывание от timer0

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: Я проверяю TCNT0 регистр и этот регистр равен 0 все время, так что часы не начались.

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

Отдых функции в библиотеке DS3231:

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); 
} 
+0

Это может быть goodd идея, чтобы показать эту функцию в вопросе. Однако, вероятно, плохой вызов назвать эту функцию из ISR. Обратите внимание, что вы вызываете неопределенное поведение, вызывая функцию с определением, отличным от его (неявного) объявления. Используйте компилятор C99 или C11, и вы получите предупреждения. – Olaf

+0

Если бы у меня был только цента (какая бы валюта) каждый раз, когда я слышал «функция/модуль/программа/... XY в порядке». Используйте отладчик. Тем не менее, очень плохой идеей является вызов функции, которая требует ненужного времени в обработчике прерываний. Это станет окончательно проблемой, если вы также выдадите что-то в своем обычном коде. Просто мои 2ct, но я занимаюсь этой работой уже несколько десятилетий, возможно, у вас больше опыта. – Olaf

+0

Я думаю, вам нужно установить источник синхронизации и запустить таймер через регистр TCCR0B. (Извините, если какая-либо из ваших функций уже делает это) – MikeCAT

ответ

3

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

Попробуйте

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

вместо

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