Время переполнения Timer2 на Atmega328P.
- Войдите на сайт для отправки комментариев
Чт, 19/12/2019 - 14:18
Добрый день.
Разбираюсь с таймерами на arduino. Для тестов использую arduino nano. Как основную инструкцию использую статью на хабре. Согласно формулам указанным в статье делаю расчет за сколько должен переполнится таймер и сработать перываение. Расчетные значения не совпадают с реальными показателями при установленных делителях: 64, 256, 1024. Замеры делаю с помощью DSO138(Может он показывает не правду?!). Почему так проиходит? Может кто проверить результаты на своем оборудовании и с нормальным осциллографом?

Значения CS12,CS11,CS10 нужно раскомментировать в зависимости от тестируемого делителя.
Используемый код для тестирования:
void setup() {
pinMode(7, OUTPUT);
cli();
TCCR2A = 0;
TCCR2B = 0;
//TCCR2B |= (1<<CS12);
//TCCR2B |= (1<<CS11);
//TCCR2B |= (1<<CS10);
TIMSK2 |= (1<<TOIE2);
sei();
}
void loop() {
// put your main code here, to run repeatedly:
}
ISR(TIMER2_OVF_vect){
digitalWrite(7, !digitalRead(7));
}
не вижу где вы включаете прерывание по переполнению?
Вот этой строчкой TIMSK2 |= (1<<TOIE2). Ориентировался по таблице.
Кажется разобрался. Я выставлял не правильные значения делителей. Смотрел в таблицу для Timer1.
Надо было настраивать по этой для Timer2.
DSO138 - нормальный прибор для такой работы. Даже не думайте.
Вот такая программа отлично работает (в т.ч. и на DSO138)
enum Prescalers { prescaler0, prescaler1, prescaler8, prescaler32, prescaler64, prescaler128, prescaler256, prescaler1024 }; void setup(void) { pinMode(7, OUTPUT); cli(); TCCR2A = 0; TCCR2B = prescaler256; TIMSK2 |= (1<<TOIE2); sei(); } void loop(void) {} ISR(TIMER2_OVF_vect){ digitalWrite(7, !digitalRead(7)); }Пока писал, Вы, похоже, уже сами разобрались.
Спасибо за enum. Элегантное решение получается. :)
Кроме делителей ещё TCNT2 не занулялось, digitalWrite() оверхедил...
#define D10_High PORTB |= B00000100 #define D10_Low PORTB &= B11111011 ISR(TIMER2_OVF_vect) { D10_Low; } void setup() { pinMode(10, OUTPUT); TCCR2A = TCCR2B = 0; TIMSK2 |= (1 << TOIE2); TCNT2 = 0; D10_High; TCCR2B |= (1 << CS20); // no prescaling - 17,6us // TCCR2B |= (1<<CS21); // F_CPU / 8 - 130 us // TCCR2B |= (1<<CS22); // F_CPU / 64 - 1.04ms } void loop() {}Про digitalWrite я понимал, но вот изначально выставлять таймер в 0. Даже не задумывался про это. Спасибо.
В данном случае оно, может и не важно, но если по ходу пьесы останавливать/стартовать таймер, то можно получить неожиданный результат. TCNT сам при старте не зануляется, продолжает тикать в том же режиме, как и перед остановкой:
void setup() { uint8_t nTCNT2; Serial.begin(115200); pinMode(10, OUTPUT); TCCR2A = TCCR2B = TCNT2 = 0x00; // Start timer TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20); delay(100); // Stop timer TCCR2B = 0x00; nTCNT2 = TCNT2; Serial.print("Checkpoint #1 (count): "); Serial.println(nTCNT2); // TCNT2 = 0x00; delay(100); // Start timer TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20); nTCNT2 = TCNT2; Serial.print("Checkpoint #2 (count): "); Serial.println(nTCNT2); delay(100); // Stop timer TCCR2B = 0x00; nTCNT2 = TCNT2; Serial.print("Checkpoint #3 (count): "); Serial.println(nTCNT2); } void loop() {}