专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
STM32
现在可以用编码器读取计数器的值了,但是怎么去测速呢?
2019-08-14 18:49
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
STM32/STM8
10144
28
1096
编码器怎么去测速呢?怎么通过PWM去控制直流电机呢?求教各位大神!最近在用直流电机,希望大家可以帮帮忙!谢谢啦!
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
28条回答
joe_knight
1楼-- · 2019-08-16 22:35
你在TIM2的5ms中断里做的是什么呀:打开TIM3和TIM5后就读计数器?读完然后就关闭?这样在一个测速周期内TIM3和TIM5都不工作,测出来不是0都怪了。
先禁用定时器,再读数,最后再使能定时器,这流程是不是你想要的?
但这样测速是不精确的,尤其对于慢速系统。
1,我们先来看Tc是不是满足需求,n = (60 × M1)/(P × Tc),为了在一个Tc内至少能收到一个编码脉冲,那么M1=1,P恒量4×400,n >= 60000 / (4 ×400 × 5),n>=7.5rpm,
也就是说,在低于7.5rmp的转速时,你的测速周期就不能满足需求,如果有示波器,可以通过编码脉冲的波形可以看一看不同转速下的最小Tc;
2,为什么说这样测速精度不够呢?copy一段,你好好理解一下:Tc开始时刻与码盘输出脉冲上升沿并非一定同步到达。同样,TC结束时刻也很难刚好与码盘的输出脉冲上升沿同步。这两个时间差都与转速的大小有关,而与高频计数时钟的频率无关。由此引起的计数和计时的时间偏差可能比高频时钟周期大得多,从而降低测速的精度;
加载中...
张晓斌
2楼-- · 2019-08-17 00:57
回复【19楼】joe_knight:
---------------------------------
蒙圈了。。。应该是初始化时使能TIM3和TIM5,然后在TIM2中断里面禁用TIM3和TIM5,读取计数值放到M1和M2里面在进行计算。这样也不能实现。然后又仔细看了看那篇文章,换了种思路,
主函数中
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_6)==1)//TIM3的PC6 
C7作为编码器接口
{
TIM3->CNT=0;
TIM_Cmd(TIM5,ENABLE);
}
然后在TIM2中断里
void TIM2_IRQHandler(void)
{
u16 M1=0,M2=0;
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_6)==1)
{
TIM_Cmd(TIM3,DISABLE);
TIM_Cmd(TIM5,DISABLE);
M1=TIM3->CNT;
M2=TIM5->CNT;
TIM3->CNT=0;
TIM5->CNT=0;
n=60*(1000000)*M1/(M2*4*400);
TIM_Cmd(TIM3,ENABLE);
TIM_Cmd(TIM5,ENABLE);
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
但是这样也不可以啊!这样应该可以啊!奔溃了。。。
加载中...
joe_knight
3楼-- · 2019-08-17 05:02
精彩回答 2 元偷偷看……
加载中...
张晓斌
4楼-- · 2019-08-17 05:26
回复【21楼】joe_knight:
---------------------------------
void TIM2_IRQHandler(void)
{
u8 count=0;
if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
{
if(count==0)//第一次进入中断后
{
TIM3_Cap_Init();//输入捕获模式
count++;
}
if(count==2)//第二次进入中断
{
count=0;
TIM_Cmd(TIM3,DISABLE);
M1=TIM3->CNT;
TIM3->CNT=0;//计数器清零
TIM3_Cap_Init();
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
void TIM3_IRQHandler(void)
{
u8 i=0;
if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)
TIM_ClearFlag(TIM3,TIM_IT_Update);
if(TIM_GetITStatus(TIM3,TIM_IT_CC1)!=RESET|TIM_GetITStatus(TIM3,TIM_IT_CC2)!=RESET)
{
if(i==0)//第一次捕获
{
TIM_Cmd(TIM3,DISABLE);
TIM3->CNT=0;
TIM_Encoder();
TIM_Cmd(TIM5,ENABLE);
i++;
}
if(i==2)//第二次捕获
{
i=0;
TIM_Cmd(TIM5,DISABLE);
M2=TIM5->CNT;
}
TIM_ClearFlag(TIM3,TIM_IT_CC1);
TIM_ClearFlag(TIM3,TIM_IT_CC2);
}
}
我是按照你给的思路写的啊,但结果还是一样的。唉。。。对自己失望了。
加载中...
张晓斌
5楼-- · 2019-08-17 06:41
回复【23楼】joe_knight:
---------------------------------
哦哦,可能是溢出没有处理好吧,我再弄弄吧!真心谢谢你!
加载中...
13262695623
6楼-- · 2019-08-17 10:55
同问11111
加载中...
上一页
1
2
3
4
5
下一页
一周热门
更多
>
相关问题
STM32F4上I2C(在PROTEUS中模拟)调试不通的问题
6 个回答
芯片供应紧张,准备换个MCU,MM32L系列替换STM32L系列的怎么样?
7 个回答
STM32同时使用两个串口进行数据收发时数据丢包的问题
5 个回答
STM32F103串口通信死机问题
4 个回答
STM32WLE5CC连接SX1268在LoRa模式下能与 SX1278互通吗?
2 个回答
STM32开发板免费用活动
7 个回答
stm32 处理 DHT11占用太多时间,大家程序是怎么设计的
8 个回答
分享一个STM32单片机做的离线编程器代码
9 个回答
相关文章
ST公司第一款无线低功耗单片机模块有效提高物联网设计生产效率
0个评论
如何实现对单片机寄存器的访问
0个评论
通过USB用STM32片内自带Bootloader下载程序及注意事项
0个评论
欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行
0个评论
×
关闭
采纳回答
向帮助了您的网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
STM32
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
关闭
您已邀请
15
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
先禁用定时器,再读数,最后再使能定时器,这流程是不是你想要的?
但这样测速是不精确的,尤其对于慢速系统。
1,我们先来看Tc是不是满足需求,n = (60 × M1)/(P × Tc),为了在一个Tc内至少能收到一个编码脉冲,那么M1=1,P恒量4×400,n >= 60000 / (4 ×400 × 5),n>=7.5rpm,
也就是说,在低于7.5rmp的转速时,你的测速周期就不能满足需求,如果有示波器,可以通过编码脉冲的波形可以看一看不同转速下的最小Tc;
2,为什么说这样测速精度不够呢?copy一段,你好好理解一下:Tc开始时刻与码盘输出脉冲上升沿并非一定同步到达。同样,TC结束时刻也很难刚好与码盘的输出脉冲上升沿同步。这两个时间差都与转速的大小有关,而与高频计数时钟的频率无关。由此引起的计数和计时的时间偏差可能比高频时钟周期大得多,从而降低测速的精度;
---------------------------------
蒙圈了。。。应该是初始化时使能TIM3和TIM5,然后在TIM2中断里面禁用TIM3和TIM5,读取计数值放到M1和M2里面在进行计算。这样也不能实现。然后又仔细看了看那篇文章,换了种思路,
主函数中
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_6)==1)//TIM3的PC6 C7作为编码器接口
{
TIM3->CNT=0;
TIM_Cmd(TIM5,ENABLE);
}
然后在TIM2中断里
void TIM2_IRQHandler(void)
{
u16 M1=0,M2=0;
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_6)==1)
{
TIM_Cmd(TIM3,DISABLE);
TIM_Cmd(TIM5,DISABLE);
M1=TIM3->CNT;
M2=TIM5->CNT;
TIM3->CNT=0;
TIM5->CNT=0;
n=60*(1000000)*M1/(M2*4*400);
TIM_Cmd(TIM3,ENABLE);
TIM_Cmd(TIM5,ENABLE);
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
但是这样也不可以啊!这样应该可以啊!奔溃了。。。
---------------------------------
void TIM2_IRQHandler(void)
{
u8 count=0;
if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
{
if(count==0)//第一次进入中断后
{
TIM3_Cap_Init();//输入捕获模式
count++;
}
if(count==2)//第二次进入中断
{
count=0;
TIM_Cmd(TIM3,DISABLE);
M1=TIM3->CNT;
TIM3->CNT=0;//计数器清零
TIM3_Cap_Init();
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
void TIM3_IRQHandler(void)
{
u8 i=0;
if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)
TIM_ClearFlag(TIM3,TIM_IT_Update);
if(TIM_GetITStatus(TIM3,TIM_IT_CC1)!=RESET|TIM_GetITStatus(TIM3,TIM_IT_CC2)!=RESET)
{
if(i==0)//第一次捕获
{
TIM_Cmd(TIM3,DISABLE);
TIM3->CNT=0;
TIM_Encoder();
TIM_Cmd(TIM5,ENABLE);
i++;
}
if(i==2)//第二次捕获
{
i=0;
TIM_Cmd(TIM5,DISABLE);
M2=TIM5->CNT;
}
TIM_ClearFlag(TIM3,TIM_IT_CC1);
TIM_ClearFlag(TIM3,TIM_IT_CC2);
}
}
我是按照你给的思路写的啊,但结果还是一样的。唉。。。对自己失望了。
---------------------------------
哦哦,可能是溢出没有处理好吧,我再弄弄吧!真心谢谢你!
一周热门 更多>