当前位置: 首页 > news >正文

编码器计速及测速(理论+代码)√

一、参考信息

       注意:

(1)此工程是建立在OLED的基础上,所以需要先把OLED的工程测试成功再开始编码器测速

(2)不管是霍尔编码器还是旋转编码器都是一样的学,不会有太大的区别     

(3) 使用的是STM32F103C8T6的开发板

(4)快捷键:F7是编译;F8是下载

        学习资料来源:(B站)

【15.定时器编码器接口【HAL库复现江协全部STM32例子合集】】

https://www.bilibili.com/video/BV1Q1421y7Us?vd_source=70e3aaa6cbfe13f5858272f48dacf336

【15.定时器编码器接口【HAL库复现江协全部STM32例子合集】】https://www.bilibili.com/video/BV1Q1421y7Us?vd_source=70e3aaa6cbfe13f5858272f48dacf336

二、基本原理

(1)电机的正反转判断

正转时,A信号比B信号会快半个周期先变成高电平

(A上升沿时B是低电平;A下降沿时B是高电平

   B上升沿时A是高电平:B下降沿是A是低电平)

反转时,B信号比A信号会快半个周期先变成高电平

(A上升沿时B是高电平;A下降沿时B是低电平

   B上升沿时A是低电平:B下降沿是A是高电平)

(2)电机的计数及编码器选择 

         一般使用TI1和TI2计数,B上升沿A此时高电平(电机正转,向上计数):A上升沿B此时高电平(电机反转,向下计数):选择编码器模式3

三、CubeMx配置

1、打开编码器模式

         选择定时器-->选择编码器模式(不需要选择内部时钟)

2、设置定时器的相关参数。由于是检测速度,所以这里就不分频,尽可能让定时器快点。计数器设置最大,防止输入信号频率太高溢出

3、设置计数模式,TI1计数和TI2计数

4、A相和B相都设置为上升沿

5、GPIO端口配置

        定时器中的编码器模式配置好之后,就可以看见板子上使用的端口是 PA6和PA7,所以此时接线就需要接在PA6和PA7上

6、OLED不需要在CubeMx中配置

        OLED不需要在CubeMx中配置,但是需要看OLED.c文件里面的引脚是不是一致的。不一致的话是无法显示的

7、电机的定时器PWM
8、记住再开一个专门用中断的定时器

四、计数代码

(1)首先要引用OLED.h的头文件

(2)声明一下中断回调函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef 
(3)重点

        初始化OLED ,打开控制电机PWM的定时器,打开控制编码器的定时器,打开使用定时器中断的定时器

  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);//PA0,控制电机的定时器HAL_TIM_Encoder_Start(&htim3,TIM_CHANNEL_ALL);//PA6,PA7控制编码器的定时器HAL_TIM_Base_Start_IT(&htim6);//开启中断函数的定时器OLED_Init();
(4)在while函数下面写中断函数

(5)新知识点:获取并显示计数值位置
OLED_ShowSignedNum(2,5,__HAL_TIM_GET_COUNTER(&htim3),5);

        这个函数就是获取编码器的计数值的

(6)改进为有符号的代码

        编码器反转时计数器应该返回负数才对,这是因为__HAL_TIM_GET_COUNTER(&htim3)返回时一个无符号的uint32_t数,需要把它强制转换成有符号的int16_t数即可

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定时器的中断函数
{int16_t CNT;//强制转化成有符号的数if(htim->Instance==TIM6)//控制中断的定时器{__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,300);//电机的转动速度HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);//这个不要用0,1;因为会出现警报,最好底层函数不要出现警报HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);CNT=__HAL_TIM_GET_COUNTER(&htim3);OLED_ShowSignedNum(2,5,CNT,5);//把OLED的显示放在中断里面,不会卡顿}}

五、测速代码

        原理就是1秒钟读取 一次定时器的计数值(编码器的脉冲)并清空。得到的数字就是当前的速度,单位就是(脉冲每秒)一秒钟有多少个脉冲

(1)测速的函数代码
int16_t hhGetEncoderSpeedCountAndReset()
{int16_t Tmp;Tmp=__HAL_TIM_GET_COUNTER(&htim3);//每隔一秒去获取一次这个计数值__HAL_TIM_SET_COUNTER(&htim3,0);//获取之后就清空return Tmp;}

 (2)放在中断里面测速

        不能直接把TIM6设成1s来计算,因为这样很耽误进程。可以把TIM6设置成10ms,然后下面用计数的方式让他计数成1s之后再去显示你的速度

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定时器的中断函数
{int16_t CNT;//强制转化成有符号的数uint16_t A;if(htim->Instance==TIM6)//控制中断的定时器,此时是定义的10ms{__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,300);//电机的转动速度HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);//这个不要用0,1;因为会出现警报,最好底层函数不要出现警报HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);A++;if(A>100){OLED_ShowSignedNum(2,5,hhGetEncoderSpeedCountAndReset(),5);A=0;}//		CNT=__HAL_TIM_GET_COUNTER(&htim3);
//		OLED_ShowSignedNum(2,5,CNT,5);//把OLED的显示放在中断里面,不会卡顿}}

六、额外补充

(1)编码器的端口

         除了最上面和最下面的电机正负极其它的都是属于编码器的端口

(2)接线
2.1

        如果不驱动电机,只需要实验编码器的话,可以电机不直接接在TB6612驱动板上,直接接在单片机上

        编码器A相接在PA6上,编码器B相接在PA7上(VCC和GND可以接在单片机上)PA6和PA7正好是开的编码器的定时器的端口

2.2

        电脑可以通过ST-Link来给单片机供电。也可以电源给TB6612驱动板供电,然后TB6612给电机以及单片机供电,只是需要注意用此种供电方法时,在电脑给单片机下载程序的时候,驱动板上要关掉开关或者拔掉单片机连接在TB6612驱动板上的VCC和GND

(3)开定时器中断读数

        可以把这一句放在定时器的中断函数里面,不然在计数上面会有一些卡

 (4)特别注意

         一定要勾选这个,否则下载不进去程序


http://www.mrgr.cn/news/44811.html

相关文章:

  • ECCV 2024 超分辨率(super-resolution)方向上接收论文总结
  • 【FPGA】面试八股
  • 69.x的平方根 367.完全有效的平方数
  • 石岩上屋大道看到一辆贴了很多条子的车
  • 周记-2024年第40周9.30~10.6:无聊时刻就看书
  • 助动词的分类及其缩略形式
  • 大厂面试真题:阿里经典双重检测DCL对象半初始化问题
  • 如何判断一个无向图是不是欧拉图
  • OJ在线评测系统 微服务高级 网关跨域权限校验 集中解决跨域问题 拓展 JWT校验和实现接口限流降级
  • 继电器原理及应用
  • 【艾思科蓝】Java Web开发实战:从零到一构建动态网站
  • 【网络协议大花园】应用层 http协议的使用小技巧,用好了都不用加班,效率翻两倍(上篇)
  • UE5+ChatGPT实现3D AI虚拟人综合实战
  • Mysql(五) --- 数据库设计
  • 手把手带你服务端实现支付功能的通用解决方案!(全网最新)
  • 软件设计师(软考学习)
  • 实验OSPF路由协议(课内实验)
  • 笔试编程题分享记录
  • 关于Qt音乐播放器进度条拖拽无用的问题解决方案
  • Vue2电商项目(七)、订单与支付