SIEMENS山西省太原市 西门子代理商——西门子华北一级总代理
| 更新时间 2024-11-16 07:00:00 价格 请来电询价 西门子总代理 PLC 西门子一级代 驱动 西门子代理商 伺服电机 联系电话 15903418770 联系手机 15915421161 联系人 张经理 立即询价 |
这里使用一款直流减速电机:
减速比是34(即电机转轴转1圈,电机本身要转34圈)
电机转一圈的物理脉冲数是11
所以,电机转轴转1圈时,可以产生的物理脉冲为34*11=374个,又由于编码器器模式实现了4倍频计数,所以,电机转轴转1圈时,定时器可以计数374×4=1496个。
对于转速的计算,这里使用M法测速(M法测速的具体原理参考之前的文章:),即统计固定时间间隔内的编码器的脉冲数,来计算速度值。
C:编码器单圈总脉冲数
T0:每次的统计时间(单位为秒)
M0:该时间内统计到的编码器脉冲数
比如,对于本次实验的电机,转轴转1圈时,定时器计数1496个,即C=1496个,对应程序中的TOTAL_RESOLUTION。T0可以选择100ms,即0.1s。
程序编写如下,这里通过另外一个定时器7来实现每100ms调用一次calc_motor_rotate_speed()函数来进行转速的实时计算,每次使用read_encoder()读取编码器器的值后,都将计数值CNT设为初始值0,重新开始计数,这样就可以保证每次读到的都是上个100ms的计数值。
另外,这里通过将CNT的uint32类型的计数值, 转为int16类型,就可以利用正负来区分上个100ms电机整体的转动方向(正转CNT从0向上计数,转为int16还是正值;反转CNT从0向下计数,会溢出,转为int16就为负数)。
// 读取定时器计数值static int read_encoder(void){int encoderNum = 0;encoderNum = (int)((int16_t)(TIM4->CNT)); /*CNT为uint32, 转为int16*/TIM_SetCounter(TIM4, CNT_INIT);/*CNT设初值*/
return encoderNum;}
//计算电机转速(被另一个定时器每100ms调用1次)void calc_motor_rotate_speed(){int encoderNum = 0;float rotateSpeed = 0;
/*读取编码器的值,正负代表旋转方向*/encoderNum = read_encoder();/* 转速(1秒钟转多少圈)=单位时间内的计数值/总分辨率*时间系数 */rotateSpeed = (float)encoderNum/TOTAL_RESOLUTION*10;
printf("encoder: %d\t speed:%.2f rps\r\n",encoderNum,rotateSpeed);}5实验演示
通过串口发送指令,控制另外一个定时器产生指定占空比的PWM来控制电机进行恒速转动,然后测试编码器读到的速度值。
(串口指令用到了字符串切割和串口接收不定长字符的功能,可参考之前的文章:C语言字符串相关函数使用示例 strtok_r strstr strtok atoi与FreeRTOS例程3-串口中断接收不定长的数据与二值信号量的使用中的部分内容,PWM的产生可参考:电机控制基础——定时器基础知识与PWM输出原理)视频中,串口打印的encoder为100ms内读到的编码器器的计数值,正负号代表正反转,speed为根据编码器的计数值计算的电机输出轴的转速,单位为圈每秒。
首先是全速正反转,转速接近5圈每秒。
然后通过调整pwm,使得电机转轴转速接近1圈每秒,由于转1圈的脉冲理论上有1496个,现在是每100ms读一次,所以能读到149个左右,符合理论值。