【问题标题】:ATmega328p, interrupt from timer0 [closed]ATmega328p,来自定时器0的中断[关闭]
【发布时间】:2015-12-14 22:53:31
【问题描述】:

我在 µC ATmega328p 中遇到来自 timer0 的中断问题。 中断调用函数showOnScreen() 时,程序在 LCD 上不显示任何内容。在主循环中调用函数showOnScreen() 时,一切正常。任何想法为什么我使用中断时它不起作用?

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
}

编辑:我检查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);
}

【问题讨论】:

  • 显示有问题的函数可能是个好主意。但是,从 ISR 调用该函数可能是个坏主意。请注意,您通过调用具有不同于其(隐式)声明的定义的函数来调用未定义的行为。使用 C99 或 C11 编译器,您会收到警告。
  • 如果我每次听到“函数/模块/程序/... XY 都可以”时只有一美分(无论哪种货币)。使用调试器。尽管如此,调用一个在中断处理程序中不必要地花费大量时间的函数是一个非常糟糕的主意。如果您还在正常代码中输出某些内容,这绝对会成为一个问题。只是我的 2ct,但我只做了几十年的工作,你可能有更多的经验。
  • 我猜你必须设置一个时钟源并通过TCCR0B寄存器启动定时器。 (对不起,如果您的任何功能已经这样做了)
  • @santisg 函数我已经检查过了,你好像只在那里初始化了TCCR0AOCR0ATIMSK0

标签: c interrupt avr atmega


【解决方案1】:

看来你打错了,时钟没有提供给计时器,所以计时器保持停止状态。

试试

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

而不是

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

【讨论】:

    猜你喜欢
    • 2021-01-20
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多