向右移动负数

spl*_*ash 1 c avr bit-shift avr-gcc twos-complement

#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;
}
Run Code Online (Sandbox Code Playgroud)

请帮我解决TCNT1H=(-640)>>8; TCNT1L=(-640);代码....因为我一直在使用0-256的值,所以真的很混乱....

veg*_*ga8 5

这个问题的答案是两个补码位移.

在上面的代码中,-640只是编写位模式的一种奇特(而且不直观)的方式,1111 1101 1000 0000而该>>8部分是用于切断低8位的常用惯用语.


这可能不是在C中设置AVR定时器寄存器的最简洁方法,因为至少第二次分配TCNT1L=(-640);取决于编译器将丢弃高于8个最低有效位的所有位的假设.(大多数(?)编译器(包括我猜的avr-gcc)实际上会做到这一点,但它不能保证和依赖于实现的行为AFAIK.)

  • 实际上,现在我看得更近了,`-640`并不是不直观的.很清楚是什么意思:当时钟计数"TCNT"翻转到达0时,发生溢出中断.中断处理程序将计数重置为-640(或2 ^ 16 - 640),这样它将再次触发又经过640次循环.(尽管如此,你仍然会得到一个赞成.) (3认同)