打印
[应用相关]

STM32CubeMX的正交编码器encoder

[复制链接]
1544|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
正交编码器通常是安装在电机上的,与电机转子的主轴同轴,有一些是通过主轴连接减速或加速齿轮组再接入编码器的,编码器一般有光栅编码器和磁极编码器两种,正转反转输出的脉冲都是下图这个样子

STM32本身带有处理正交脉冲的功能,也就是定时器中的Encoder模式
具体操作:

STM32CubeMX配置
1.打开STM32CubeMX,选择自己使用的芯片,此处我以STM32F429IGT6为例进行;
2.设置系统、时钟基本操作
SYS



使用特权

评论回复
沙发
renzheshengui|  楼主 | 2021-7-1 12:11 | 只看该作者
RCC

使用特权

评论回复
板凳
renzheshengui|  楼主 | 2021-7-1 12:12 | 只看该作者
3.定时器设置
此处我选用的是TIM3,TIM3位通用定时器,一般芯片通用定时器比较多
Combined Channels采用Encoder Mode(编码器模式)
选用此模式后TIM3的CH1和CH2就变为编码器接口了,记住对应的两个接口,之后要把编码器信号接到这两个口上,我的是PA6和PA7



使用特权

评论回复
地板
renzheshengui|  楼主 | 2021-7-1 12:12 | 只看该作者
下方参数设定根据需求进行设定,由于我需要记录编码器的上升沿和下降沿,所以此处选择的是Encoder Mode TI1 and TI2,这个模式将AB两组脉冲的上升下降沿都计数了,就是计数4次,不需要那么精确的同学可以把预分频系数(Prescaler)修改为4-1,那么脉冲检测到4个脉冲就会计数1次了,滤波器看个人,我用杜邦线直连的,距离10cm不到所以我设的是0,具体怎么选可以看STM32中文参考手册,懒人看下面的图




使用特权

评论回复
5
renzheshengui|  楼主 | 2021-7-1 12:12 | 只看该作者
4.串口设置

为了方便观察,需要通过串口发送对应的旋转方向,旋转计数值到串口调试助手。
由于芯片只用于发送数据,就不搞中断了,直接选择异步串口即可


使用特权

评论回复
6
renzheshengui|  楼主 | 2021-7-1 12:12 | 只看该作者
5.最后配置时钟树

这个大家自行处理,每块芯片都不同,最终让中间HCLK(MHz)为72即可


使用特权

评论回复
7
renzheshengui|  楼主 | 2021-7-1 12:12 | 只看该作者
6.项目配置

我用的开发环境是Keil5,所以在Toolchain/IDE中选择了MDK-ARM


使用特权

评论回复
8
renzheshengui|  楼主 | 2021-7-1 12:13 | 只看该作者
代码生成的时候把Generated files中的第一项选中,不然h文件和c文件混着,看着都难受

使用特权

评论回复
9
renzheshengui|  楼主 | 2021-7-1 12:13 | 只看该作者
7.点击右上角GENERATE CODE生成代码即可

代码修改

1.串口代码修改
为了方便,用printf函数输出信息,所以需要在串口的/* USER CODE BEGIN 0 */后添加串口重定向函数,如下所示:

/* USER CODE BEGIN 0 */
#include <stdio.h>
struct __FILE
{
        int handle;
};
FILE __stdout;      
void _sys_exit(int x)
{
        x = x;
}
int fputc(int ch, FILE *f)
{        
        while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
        USART1->DR=(uint8_t)ch;      
        return ch;
}

/* USER CODE END 0 */


使用特权

评论回复
10
renzheshengui|  楼主 | 2021-7-1 12:13 | 只看该作者
2.main.c修改
首先要添加stdio.h的包含,方便后面用printf输出
在main.c的/* USER CODE BEGIN Includes */后添加如下代码:

/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */


之后需要几个变量,分别为


使用特权

评论回复
11
renzheshengui|  楼主 | 2021-7-1 12:14 | 只看该作者
定义变量,在/* USER CODE BEGIN 1 */后添加如下代码

/* USER CODE BEGIN 1 */
  uint8_t Direction;
  uint16_t counter;
  uint16_t enc1 = 0,enc1_old = 0;
  int16_t enc2 = 0;
  int32_t enc;
  /* USER CODE END 1 */



启动编码器解释,在/* USER CODE BEGIN 2 */后添加编码器启动函数

/* USER CODE BEGIN 2 */
  HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
/* USER CODE END 2 */



在循环中,也就是/* USER CODE BEGIN 3 */后添加读取编码器数值函数以及进位处理函数和打印输出函数:

/* USER CODE BEGIN 3 */
        Direction = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3);  
    enc1 = (uint32_t)(__HAL_TIM_GET_COUNTER(&htim3));        //获取定时器的值
        if((Direction == 0) &(enc1 < enc1_old))                                //正向旋转数值变小,说明进位
        {
                enc2++;
        }
        if((Direction == 1) &(enc1 > enc1_old))                                //反向旋转数值变小,说明借位
        {
                enc2--;
        }
        enc1_old = enc1;                                                                        //更新enc1_old,便于下次计算
        enc = enc2<<16 | enc1;                                                                //计算当前计数总值,带+-号
        counter++;                                                                                        //主函数计数
        if(counter>1000)                                                                        //主函数每次运行约1ms,此处用于每1000ms发送一次数
        {
                counter = 0;                                                                        //计数值清零
                printf("Dir %d,        Enc2 %d, Enc1 %d, ENC %d\r\n",Direction,enc2,enc1,enc);//打印相关计数数据
        }
        HAL_Delay(1);
  }
  /* USER CODE END 3 */



此时代码已经完全修改完成,编译下载到芯片内,等待接线测试


使用特权

评论回复
12
renzheshengui|  楼主 | 2021-7-1 12:15 | 只看该作者
接线测试

我用的编码器是5v供电的一款磁极编码器,但最终接口都应该是VCC、GND、A、B四个接口,此时按如下方式连接



接好之后就可以上电,打开串口调试助手,连接上串口1
就会收到如下数据,此时转动编码器就可以看到数值的改变


至此,编码器功能已完成。


使用特权

评论回复
13
mbutterfly| | 2023-11-22 08:59 | 只看该作者

使用特权

评论回复
14
guijial511| | 2023-11-24 08:21 | 只看该作者
传统编码器输出都是ABCZ四相输出。

使用特权

评论回复
15
Pulitzer| | 2024-7-21 07:06 | 只看该作者

STM32芯片中有多个工作时钟源的外设很常见

使用特权

评论回复
16
童雨竹| | 2024-7-21 09:02 | 只看该作者

CPU借助于APB总线访问相关寄存器达到对I2C1工作模块的控制

使用特权

评论回复
17
Wordsworth| | 2024-7-21 10:05 | 只看该作者

ART2固定使用PCLK时钟,只有开启和关闭的问题,不存在其它时钟源选择

使用特权

评论回复
18
Clyde011| | 2024-7-21 11:08 | 只看该作者

一部分是I2C1的工作模块,另外一部分是其控制模块

使用特权

评论回复
19
公羊子丹| | 2024-7-21 12:01 | 只看该作者

控制模块的时钟仍然由外设时钟PCLK提供

使用特权

评论回复
20
万图| | 2024-7-21 13:04 | 只看该作者

USART1可以有多个时钟源

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

78

主题

4079

帖子

2

粉丝