STM32 HAL库实现编码器测速

STM32 HAL库实现编码器测速

(还开了串口1用来调试,下文没写;然后那个short的用法就是看平衡小车之家(就是喵呜实验室的文档里头的,用法确实惊艳),文末贴了工程)
编码器接口模式
TI1和TI2连接编码器,开启定时器编码器模式后,根据TI1和TI2的信号转换序列,产生对应的计数脉冲和方向信号(此时是硬件控制CR寄存器的DIR位,软件不能再进行编程控制) 编码器接口只能是TI1和TI2,TI3和TI4是不具备编码器接口功能的。
在这里插入图片描述

对于计数器的计数和方向判断,如下:
在这里插入图片描述

cubeMx配置:直接选择一个通用定时器或者高级定时器,点开编码器模式即可
在这里插入图片描述

之后直接生成代码即可

Keil:
编码器数据读取函数:
在这里插入图片描述

强制转换short的作用:实现正转读数为正,反转读数为负。
实现原理:寄存器所读出来的值是0-65535,而short是2字节,技术范围是-32768-32767,当寄存器读到32767的时候经过short强制转换就会溢出,使得寄存器的读数32768经过强制转换编程-32768,再下一个32769转换成-32767。所以,电机反转的时候读出的数就是反方向的速度值,不需要用 65535 去减去读出的值再加上负号才可以得到方便观察的值

Main.c需要添加的:
在这里插入图片描述

在这里插入图片描述

实现效果:

当电机不转的时候,编码器读数为0,当反转的时候读数为负数,正转时候为正数;由于我前面设置的是Encoder TI1&TI2,所以他是四倍频。如果要计算圈数(四倍频为例),则需要知道该电机的单相单圈脉冲,计算公式:圈数=所读的脉冲数/单相单圈脉冲/4
在这里插入图片描述

注意:要接编码器正负极,不然读到的数据无效且保持在一个数上下浮动。

完整工程:(指南者F103的,其实可以移植encoder的.c和.h)
链接:https://pan.baidu.com/s/1xmDYSHZCCOrg66TMNV7uSg
提取码:ld9i

### 配置 STM32 HAL 和 USART 实现编码器电机测速 #### 1. 环境准备与硬件连接 为了实现通过USART串口读取并发送编码器测量到的电机速度数据,首先需要完成基本的硬件连接设置。确保编码器信号线正确接入STM32F401CCU6的相关GPIO引脚,并且这些引脚已经在STM32CubeMX中被配置为输入模式用于接收增量式编码器A相和B相信号。 对于USART通信部分,则需指定一对TX/RX管脚作为串行接口的数据传输通道[^1]。 #### 2. 初始化定时器以支持编码器功能 利用STM32CubeMX工具,在项目创建阶段应选择合适的定时器资源(如TIM2),将其工作方式设为“Encoder Mode”,这一步骤可通过调用`HAL_TIM_Encoder_Init()`函数来完成初始化过程[^3]: ```c static void MX_TIM2_Init(void) { TIM_Encoder_InitTypeDef sConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; htim2.Instance = TIM2; htim2.Init.Prescaler = 0; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 65535; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (htim2.Instance->CR1 & TIM_CR1_CEN) { __HAL_TIM_DISABLE(&htim2); } sConfig.EncoderMode = TIM_ENCODERMODE_TI12; // 设置为四倍频模式 sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; sConfig.IC1Prescaler = TIM_ICPSC_DIV1; sConfig.IC1Filter = 0; sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; sConfig.IC2Prescaler = TIM_ICPSC_DIV1; sConfig.IC2Filter = 0; if (HAL_TIM_Encoder_Init(&htim2, &sConfig) != HAL_OK){ Error_Handler(); } } ``` 上述代码片段展示了如何针对特定需求调整定时器参数,特别是选择了适合于处理正交解码的任务选项——即采用上升沿触发的方式捕捉两个通道上的脉冲变化情况。 #### 3. 定义周期性的计数更新机制 为了让系统能够持续监测编码器的状态变动,可以设定一个定期执行的任务或中断服务程序(ISR),用来查询当前累计脉冲数量,并据此计算瞬时角位移量及相应的转速。这里可以通过开启定时器溢出事件或者编写专门的时间管理逻辑达成目的。 #### 4. 数据打包并通过USART发送 当获得最新的速度信息之后,就可以按照预定协议格式化成字符串形式,再借助`HAL_UART_Transmit()` API经由预先定义好的UART端口向外传送该消息体了。下面给出一段简单的示例代码说明这一操作流程: ```c void SendSpeedData(float speedValue) { char buffer[32]; sprintf(buffer,"Current Speed:%.2frpm\r\n",speedValue); /* 发送数据 */ HAL_UART_Transmit(&huart2,(uint8_t*)buffer,strlen(buffer),HAL_MAX_DELAY); } ``` 此段代码实现了将浮点型的速度变量转换为字符数组的形式,随后调用了`HAL_UART_Transmit()`方法向uart2设备写入这条记录有实时速率的消息。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值