Значения регистров сравнения относительного вывода изменяют поведение
Я использую 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, 1, 0
за WGM02, WGM01, WGM00
, вы включили CTC (Clear Timer on Compare match mode) - TCNT0
регистр будет очищен после достижения OCR0A
значение так, чтобы OCR0B
значение никогда не будет достигнуто, если оно больше чем OCR0A
.
Обновлено, чтобы ответить на вопросы в комментарии:
Да, очистку TCNT0 можно отключить. Просто установите биты WGM0x в 0. См. Таблицу Описание битов режима генерации сигналов в конце описания TCCR0A.
Нет, верхнее значение регистра 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;
}