在控制直流电动机时,需要确定电机的转向、位置、速度,因此会使用到码盘,在使用增量式码盘时,通过分析计数器的值进行判断,具体原理(可以借鉴他人文章):电机控制基础——定时器编码器模式使用与转速计算和编码器计数原理与电机测速原理——多图解析
但是如何判断电机转动方向,通过CNT计数器的值进行判断,一般在设置初始值时,设置为0,在正转时,计数器增加,这个很好理解,但是在反转的时候,计数器会不会出现负数?
其实我们在读取计数器值时的操作:
s16 num;
num = (int)TIMEx->CNT;
其实计数器作为一种寄存机,里面存放的数据不会是负值,只不过在程序编译的时候,单片机底层区分了正负,具体理解过程如下:
寄存器CNT为16位(u16 CNT),取值范围为(0-65535),65535的二进制:
在65535加1之后,为(1)0000 0000 0000 0000,因为越界,所以可以认为为0,所以在不断累加的情况下,CNT里面的数值是这样的情况:
(0,1········65536)(0,1········65535)······
但是(int)TIMEx->CNT操作后,赋值给num,int类型的范围为(-32768~32767),所以,当CNT中的值不断累加时,0,1,2······32767,当运行到32768时,通过int)TIMEx->CNT操作,单片机认为此时32768越界,不能代表32768,但是int型有负数,
此时认为1000 0000 0000 0000为负数,负数的存储方式为补码的形式,
(1000 0000 0000 0000)
取反(符号位不变,其它位取反) (1111 1111 1111 1111)
+1 (1(1)000 0000 0000 0000)
其中1位负号,(1)000 0000 0000 0000为32768,此时为-32768。进而为-32767·····
65535为 1111 1111 1111 1111,
取反 (1000 0000 0000 0000)
+1 (1000 0000 0000 0001)
此时代表-1,
(0,1·······65536) (0,1.·······65536)
对应的为:
(0,1.······32767,-32768,-32767······-1) (0,1······32767,-32768,-32767·····-1)。
变化成 (-32767·····-1,0,1·······32767)。
所以num = (int)TIMEx->CNT;在CNT为0时,反转减1,num为-1,依次类推。