右移一个负数 #包括 #包括 int main() { DDRB |=0x82; DDRC=0x00; DDRD=0xFF; TCNT1H=(-640)>>8; TCNT1L=(-640); TCCR1A=0X00; TCCR1B=0X01; TIMSK=(18;TCNT1L=(-640);code.。这真的很让人困惑,因为我一直在使用0-256之间的值。
这个问题的答案是和 在上面的代码中,-640只是编写位模式右移一个负数 #包括 #包括 int main() { DDRB |=0x82; DDRC=0x00; DDRD=0xFF; TCNT1H=(-640)>>8; TCNT1L=(-640); TCCR1A=0X00; TCCR1B=0X01; TIMSK=(18;TCNT1L=(-640);code.。这真的很让人困惑,因为我一直在使用0-256之间的值。,c,avr,bit-shift,avr-gcc,twos-complement,C,Avr,Bit Shift,Avr Gcc,Twos Complement,这个问题的答案是和 在上面的代码中,-640只是编写位模式11111111111001000 0000的一种奇特(且不直观)的方式,而>8部分是一种常用的切断低位8位的习惯用法 这可能不是在C中设置AVR定时器寄存器的最干净的方法,因为至少第二个赋值TCNT1L=(-640);取决于编译器将丢弃8个最低有效位以上的所有位的假设。(我猜大多数(?)编译器(包括AVR gcc)实际上会做到这一点,但这并不保证,而且依赖于实现的行为也会发生。)这个问题的答案是和 在上面的代码中,-640只是编写位模
11111111111001000 0000
的一种奇特(且不直观)的方式,而>8
部分是一种常用的切断低位8位的习惯用法
这可能不是在C中设置AVR定时器寄存器的最干净的方法,因为至少第二个赋值
TCNT1L=(-640);
取决于编译器将丢弃8个最低有效位以上的所有位的假设。(我猜大多数(?)编译器(包括AVR gcc)实际上会做到这一点,但这并不保证,而且依赖于实现的行为也会发生。)这个问题的答案是和
在上面的代码中,-640只是编写位模式11111111111001000 0000
的一种奇特(且不直观)的方式,而>8
部分是一种常用的切断低位8位的习惯用法
这可能不是在C中设置AVR定时器寄存器的最干净的方法,因为至少第二个赋值
TCNT1L=(-640);
取决于编译器将丢弃8个最低有效位以上的所有位的假设。(我猜大多数(?)编译器(包括AVR gcc)实际上会做到这一点,但这并不能保证,而且依赖于实现的行为也会发生。)在AVR中,TCNT1L
和TCNT1H
是8位值的硬件地址。它们被定义为uint8_t,因此即使不首先强制转换到uint8_t,这个习惯用法也会起作用。实际上,现在我仔细观察,-640
并不是不直观的。很清楚这意味着什么:当时钟计数时,溢出中断发生,>TCNT
,滚动到0。中断处理程序将计数重置为-640(或2^16-640),这样它将在另一个640个周期后再次启动。(不过,您仍然可以获得向上投票。)完全同意……它实际上相当优雅!我会天真地设置OCR1A
,并使用TIMER1\u-vect
(时间会更长).thx指出这一点!我也认为这是一个糟糕的编程。为了使它更优雅,你应该在宏中隐藏对正确类型的“-”和强制转换的添加。加上一些解释性的注释。@vega8对我来说,OCR1A
方法更可取,因为1.这是OCR
中断和2的预期用途之一TCNT1
可以同时用于其他目的,因为OCR1B
和TOI仍然可以独立使用(除了计时器的频率之外,它们都必须共享)。在AVR中,TCNT1L
和TCNT1H
是8位值的硬件地址。它们被定义为uint8\t,因此即使不首先强制转换为uint8\t,这个习惯用法也会起作用。实际上,现在我仔细看看,-640
并不是不直观的。很清楚这意味着什么:当时钟上的计数时,TC发生溢出中断NT
,滚动到0。中断处理程序将计数重置为-640(或2^16-640),这样它将在另一个640个周期后再次启动。(不过,您仍然会得到一个向上投票。)完全同意……它实际上相当优雅!我会天真地设置OCR1A
,并使用计时器1\u-vect
(时间会更长).thx指出这一点!我也认为这是一个糟糕的编程。为了使它更优雅,你应该在宏中隐藏对正确类型的“-”和强制转换的添加。加上一些解释性的注释。@vega8对我来说,OCR1A
方法更可取,因为1.这是OCR
中断和2的预期用途之一TCNT1
可以同时用于其他目的,因为OCR1B
和TOI仍然可以独立使用(除了计时器的频率之外,它们都必须共享)。您可以代替TCNT1H
和TCNT1L
。您可以代替TCNT1H
和TCNT1L
。
#include <avr/io.h>
#include <avr/interrupt.h>
int main()
{
DDRB|=0x82;
DDRC=0x00;
DDRD=0xFF;
TCNT1H=(-640)>>8;
TCNT1L=(-640);
TCCR1A=0X00;
TCCR1B=0X01;
TIMSK=(1<<TOIE0)|(1<<TOIE1)
sei();
PORTD=PINC;
}
ISR(TIMER1_OVF_vect)
{
TCNT1H=(-640)>>8;
TCNT1L=(-640);
PORTB^=0X80;
}