0

我使用 Atmega328p Timer0 及其两个 OCR:

void timer0_ini(void)
{
    TCCR0A = 0;// set entire TCCR0A register to 0
    TCCR0B = 0;// same for TCCR0B
    TCNT0  = 0;//initialize counter value to 0

    OCR0B = 125; // OCR0B is less than OCR0A, so it works
    OCR0A = 250;

    TCCR0A = (0<<COM0A1)|(0<<COM0A0)|(0<<COM0B1)|(1<<COM0B0)|(1<<WGM01)|(0<<WGM00);

    TCCR0B  |=  (0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(1<<CS02)|(1<<CS00);
    TIMSK0 = (1 << OCIE0A)|(1 << OCIE0B);
}

ISR (TIMER0_COMPB_vect)
{
    PORTB ^= (1 << PORTB2);
}

ISR (TIMER0_COMPA_vect)
{
    PORTB ^= (1 << PORTB1);
}

它仅在 OCR0B < OCR0A 时起作用。我不明白为什么这有意义。

4

1 回答 1

0

使用0, 1, 0for WGM02, WGM01, WGM00,您启用了 CTC(比较匹配模式下的清除计时器)-寄存器在达到值TCNT0后将被清除,因此如果它高于 ,则永远不会达到该值。OCR0AOCR0BOCR0A

更新以回答评论中的问题:

  1. 是的,可以禁用 TCNT0 的清除。只需将 WGM0x 位设置为 0。请参见TCCR0A 说明末尾的表格波形生成模式位说明。

  2. 不,TCNT0 寄存器的最高值是 OCR0A 或固定 0xFF,参见同一张表。

从你的问题中不清楚你想做什么。也许,可以将较大的值放入 OCR0A,将较小的值放入 OCR0B,并设置一个标志,说明哪个中断应该更改哪个端口位。

如果要制作两个独立的频率,请将定时器设置为自由运行模式(所有 WGM 位等于 0)并尝试

ISR (TIMER0_COMPB_vect)
{
    PORTB ^= (1 << PORTB2);
    OCR0A += 125;
}

ISR (TIMER0_COMPA_vect)
{
    PORTB ^= (1 << PORTB1);
    OCR0B += 250;
}
于 2020-04-19T08:03:17.547 回答