У меня проблема с прерыванием от 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);
}
Это может быть goodd идея, чтобы показать эту функцию в вопросе. Однако, вероятно, плохой вызов назвать эту функцию из ISR. Обратите внимание, что вы вызываете неопределенное поведение, вызывая функцию с определением, отличным от его (неявного) объявления. Используйте компилятор C99 или C11, и вы получите предупреждения. – Olaf
Если бы у меня был только цента (какая бы валюта) каждый раз, когда я слышал «функция/модуль/программа/... XY в порядке». Используйте отладчик. Тем не менее, очень плохой идеей является вызов функции, которая требует ненужного времени в обработчике прерываний. Это станет окончательно проблемой, если вы также выдадите что-то в своем обычном коде. Просто мои 2ct, но я занимаюсь этой работой уже несколько десятилетий, возможно, у вас больше опыта. – Olaf
Я думаю, вам нужно установить источник синхронизации и запустить таймер через регистр TCCR0B. (Извините, если какая-либо из ваших функций уже делает это) – MikeCAT