我正在尝试实现我在YouTube上看到的一个简单的timer1示例: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 :(得分: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,但我现在还没有...我一拿到它就会尝试使用它
答案 1 :(得分:1)
我遇到了同样的问题,在Atmel文档中,我发现其他引脚会影响计数器模式。也就是说,引脚:WGM13,WGM12,WGM11,WGM10分别为0,1,0,0,计数器将处于CTC模式,这意味着它将计数到OCR1A的值而不是(2 ^ 16-1) )您的代码可能就是这种情况。
WGM11,WGM10是TCCR1A中的位1,0和WGM13,WGM12是TCCR1B中的位4,3所以将它们设置为零应该可以完成这项工作。
答案 2 :(得分:1)
我的其中一个代码有类似的东西。我找不到该问题的确切原因。最后,我删除了设置和循环功能,并用c代码替换了它们。 然后工作正常。如果需要这些功能,则通过清除TCCR1A和TCCR1B寄存器来启动代码。我希望这是由于不确定Arduino IDE而发生的。但这有效。