历史上的今天
今天是:2024年09月16日(星期一)
2018年09月16日 | STM32的16位编码器溢出问题
2018-09-16 来源:eefocus
STM32定时器有编码器接口,但是它的计数器只有16位。当要记录的数过大时,会溢出。下文介绍了一种方法,能有效解决因计数器位数过少引起的溢出问题。
(在网上搜了好多,感觉不他们说的方法都不准。这个方法经过我自己验证,可以准确记录编码器的位置)
原理一:
unsigned short int j;(j的长度为16bit)
① 当j=65535 ,运行j++后,j=0;
② 当j=0 , 运行j- -后,j=65535;
定时器的16位计数器寄存器(CNT)同样符合上面的逻辑。在编码器模式时,
(一)当加计数时(up计数),加到65535后,再加1,CNT的值变为0,且溢出标志位 被置1(UIF=1),
(二)当减计数时(down计数),减到0后,再减1,CNT的值变为65535,且溢出标志位被置1(UIF=1),
当溢出中断被使能时(UIE=1),(一)、(二)两种情况都会触发中断,在中断函数中判断CNT的值,就可以判断是加溢出还是减溢出,用一个变量(update)记录溢出的次数
signed int update;
if(CNT < 32768)
{
update++;
}
else
{
update--;
}
若使用圆形编码器,update的正负表示是顺时针还是逆时针转动
假设update正为顺时针转动
当update为正
update * 65535 + CNT当前值 就是顺时针转动的步数
当update为负
(0-update*65536-CNT当前值 就是逆时针转动的步数
也可以按照自己的实际情况修改算法来记录转动步数
史海拾趣
|
我现在用伟福仿真器 连接到硬件上 (ATMEL 89S51) 89S51的P1口连接一个按键键盘(总共12个按键: 0-9 确认 取消) 程序如下: #include #include #include unsigned char temp,temp1,temp ...… 查看全部问答> |
|
6410 2d加速的BitBLt运行不正常。弄过的兄弟给点建议 在linux 2.6.33上弄的,只想实现最简单的从一块区域拷贝到另外一块区域显示的功能。 将(linux 2.6.28的)中g2d部分的代码移植到了video s3c-fb中,通过io_ctrl实现的。但移植的代码更本不能使用。 然后自己按照手册,配置的寄存器。 从FIFO sta ...… 查看全部问答> |
|
NDIS中间驱动MPsend OR MPSendPackets中 获得数据的问题 NDIS中间驱动MPsend OR MPSendPackets中 获得了数据包首地址,然后用结构体分析,可以取得正确的 MAC地址,在取IP地址的时候输出全是0,检查发现除了以太头以外,包括IP头,TCP等其他的部分全部都是空的??这是怎么会事啊??… 查看全部问答> |
|
我试了下,不执行擦除操作,反复在一段空间里写入不同的数,后面的数能覆盖前面的数,这不就行了吗?为什么要先擦除再写,何况擦除的时间那么长,影响程序实时性。 有知道的大虾指教下。我写入的地址段是F400H。… 查看全部问答> |
|
本帖最后由 paulhyde 于 2014-9-15 03:57 编辑 大赛给你印象最深的事情是什么? 是老师的帮助?是同学之间的相互合作? 是自己的不懈努力,还是四天三夜就睡了十几个小时? ······ … 查看全部问答> |
|
终于用811读取出ADXL345的数据了,庆祝下,源码参考了网上的,呵呵 static unsigned char DataX1, DataX2, DataY1, DataY2, DataZ1, DataZ2; //xyz的高低字节 static unsi ...… 查看全部问答> |




