Timer1 действует странно на Arduino UNO (ATMEGA328)

Я пытаюсь реализовать простой пример timer1, который я видел на YouTube: http://youtu.be/Tj6xGtwOlB4?t=22m7s . Пример был на c ++ для автономного чипа ATMEGA328, и я пытаюсь заставить его работать на Arduino UNO. Вот мой рабочий код:

void setup() {
//initialize port for LED
DDRB =  0b11111111; //initialize port B as output (really only care about 5th bit)
PORTB = 0b00000000; //set ouput values to zero
TCCR1A = 0; //clear control register A (not sure that I need this)
TCCR1B |= 1<<CS10; //no prescaler, turns on CS10 bit of TCCR1B
}

void loop() {
if (TCNT1 >= 255){
TCNT1 = 0; //resets timer to zero
PORTB ^=1<<PINB5; //1<<PINB5 is same as 0b00100000, so this toggles bit five of port b which is pin 13 (red led) on Arduino
}
}

Все работает, но TCNT1 будет рассчитывать только до 255. Если я установлю значение в операторе if на что-то более высокое, код в операторе if никогда не будет выполнен. Timer1 должен быть 16-битным таймером, поэтому не имеет смысла, почему счетчик останавливается на 255. Arduino что-то делает за кулисами, чтобы запутаться? Похоже, что это прекрасно работает в примере на YouTube (без Arduino).

0

Решение

Я столкнулся с той же проблемой, в документации Atmel я обнаружил, что другие контакты влияют на режим счетчика. То есть выводы: WGM13, WGM12, WGM11, WGM10 равны 0,1,0,0, соответственно, счетчик будет в режиме CTC, то есть он будет считать до значения OCR1A вместо (2 ^ 16-1 ) что может быть в вашем коде.

WGM11, WGM10 — это биты 1,0 в TCCR1A и WGM13, WGM12 — это биты 4,3 в TCCR1B, поэтому их установка в ноль должна выполнять свою работу.

1

Другие решения

Прежде всего …. Почему вы устанавливаете регистры? Единственное преимущество Arduino заключается в том, что он объединяет некоторые функции, так почему бы не использовать его? Вместо

DDRB =  0b11111111;
PORTB = 0b00000000;
...
PORTB ^=1<<PINB5;

использовать просто

int myoutpin = XXXX; // Put here the number of the ARDUINO pin you want to use as output
...
pinMode(myoutpin, OUTPUT);
...
digitalWrite(myoutpin, !digitalRead(myoutpin));

Я думаю, что, вероятно, есть некоторые похожие функции для таймера тоже ..

Что касается вашего вопроса, я попробовал этот код:

// the setup routine runs once when you press reset:
void setup() {
TCCR1A = 0; //clear control register A (not sure that I need this)
TCCR1B |= 1<<CS10; //no prescaler, turns on CS10 bit of TCCR1B
Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
if (TCNT1 >= 12000){
TCNT1 = 0; //resets timer to zero
Serial.println("Timer hit");
}
}

в симуляторе и все работает хорошо; Я должен попробовать это с настоящим Arduino, но у меня его пока нет … Как только я получу один, я попытаюсь использовать его

0