Относительные выходные регистры сравнения значений изменяют поведение - PullRequest
0 голосов
/ 19 апреля 2020

Я использую 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

1 Ответ

0 голосов
/ 19 апреля 2020

Используя 0, 1, 0 для WGM02, WGM01, WGM00, вы включили CT C (Сброс таймера в режиме сравнения совпадений) - регистр TCNT0 будет очищен после достижения значения OCR0A, так что значение OCR0B никогда не будет достигнуто, если оно выше OCR0A.

Обновлено, чтобы ответить на вопросы в комментарии:

  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;
}
...