51 片内有 2个16位定时计数器(定时器 0和定时器 1),但问题是这两个定时计数器是加 1计数器不能直接使用,所以需要通过合适的编程来实现“减”计数功能。硬件电路如图 5所示。图2.2-5 单片机内部计数器加减计数的硬件结构把光电编码器输出的 A 接至 D 触发器的 D 端同时再接至 T0 端, B 相脉冲接至触发器的 CLK 端,同时触发器的输出信号 DIR 一路接至 INT0 ,另一路经反相器后接入 INT1 端。设计思想是:让INT0 、INT1 工作于下降沿触发方式,这样当 DIR 信号脉冲改变时会触发两个中断中的一个。当 INT1 中断时,进行加计数, 反之,当 INT0 中断时,进行减计数。这种设计思想可以用 C 语言编程得到很好的实现。以下就是 C语言程序: #include int data k=1; void service_int0() interrupt 0using 0 {k-- ;/* 标志位减 1*/ TR0=0 ;/* 停止计数*/ TH0= -TH0 ;TL0= -TL0 ;/* 把计数器重新复值,此时相当于减计数*/ TR0=1 ;/* 开始计数*/ }void service_int1() interrupt 2using 1 {k++ ;/* 标志位加 1*/ TR0=0 ;/* 停止计数*/ TH0= -TH0 ;TL0= -TL0 ;/* 把计数器重新复值,此时相当于加计数*/ TR0=1 ;/* 开始计数*/ }void timer0(void) interrup 1using2 {if(k=0) /*反向计数满*/ else if(k=1) /*计数为 0*/ else /*正向计数满*/ }void main(void) {TCON=0X05 ;/* 设置下降沿中断*/ TMOD=0X05 ;/*T0 为16位计数方式*/