小熊派学习——获取旋转编码器转动角度、角速度

举报
ttking 发表于 2020/09/01 23:01:27 2020/09/01
【摘要】 本篇文章使用小熊派开发板+欧姆龙的E6B2-CWZ3E编码器,通过转动编码器,获取正转或者反转的角度并在串口中显示。通过此文章可以了解STM32的编码器模式,熟悉编码器的使用

本篇博客使用小熊派开发板+欧姆龙的E6B2-CWZ3E编码器,通过转动编码器,获取正转或者反转的角度并在串口中显示

一、实验准备

1.实验环境

  • 一块stm32开发板(推荐使用小熊派),以及数据线

  • 已经安装STM32CubeMX

  • 已经安装KeilMDK,并导入stm32开发板对应的芯片包(小熊派使用的是STM32L431RCT6)

  • 一个编码器以及四根杜邦线(我使用的编码器为欧姆龙E6B2-CWZ3E,为1000线,即选择一圈产生1000个脉冲))

  • 准备一个串口调试助手,我使用的是UartAssist(包含在附件中)
    image.png
    image.png


2.目标效果

  • 通过CubeMX创建工程并配置参数

  • 定时器编码器模式的使用

  • 小熊派通过编码器模式获取编码器的值

  • 串口1重定向输出编码器转动的角度、角速度

二、通过CubeMX生产MDK工程

A.芯片选择

  • 打开CubeMX,进入芯片选择:

image.png

  • 选择自己的stm32芯片(即STM32L431RCT6):

image.png

B.时钟源RCC设置

  • 更改系统时钟源

    系统时钟默认使用内部的高速时钟(HSI),选择使用HSE,时钟更精确

  • 设置外部时钟对应的端口
    image.png

  • 配置时钟树

    STM32L431RCT6系统时钟最大可以为80MHz,我们配置到最大即可

image.png

C.参数配置(对应端口设置)

1)配置USART1

使用USART,模式为异步,波特率为115200,无硬件流控制


image.png

2)定时器配置

STM32L431RCTC的定时器有
1.高级定时器:TIM1
2.通用定时器:TIM2  TIM15  TIM16
3.基本定时器:TIM6  TIM7
4.低功耗定时器:LPTIM1  LPTIM2

使用定时器2的编码器模式(以下有讲解),重装载值为20000,设置为两个通道捕获且上升沿、下降沿都捕获。

打开定时器模式,设置TF1\TF2都捕获,不分频(此时,旋转一圈将计数1000*4=4000),计数值为20000。

注意的是,我们设置的上升沿捕获,并不是只捕获上升沿,而是从上升沿开始捕获。

image.png

3)编码器模式有什么作用

编码器模式使用两个通道,捕获编码器的AB相脉冲。按照编码器的工作原理,正转时A相超前。设置stm32捕获AB相的上升沿、下降沿,stm32的编码器模式可以自动的消除干扰(比如抖动带来的干扰),如果正转,计数器向上计数,反则向下计数。

image.png

4).打开定时器2中断

我们希望计数值溢出时进行相应的处理,比如重新计数,因此打开定时器2全局中断

image.png

最后,生成代码就OK了

D.工程设置

一些基础的设置,包括工程名、存储位置、工程环境、工程中各个文件的组成


image.png

image.png

E.生成代码

image.png

三、编写相应代码

1. 串口1输出重定向

我们知道printf是打印函数,原理是根据传入的字符串参数格式化打印输出到stdout中。我们需要让printf打印到串口之中,只需要在usart.c文件中模仿printf写一个输出函数即可

  • 在添加头文件

    /* USER CODE BEGIN 0 */#include <stdarg.h>#include <string.h>#include <stdio.h>/* USER CODE END 0 */
  • 写输出函数

/* USER CODE BEGIN 1 */void UsartPrintf(UART_HandleTypeDef *huart, char *fmt,...){

    unsigned char UsartPrintfBuf[296];
    va_list ap;
    unsigned char *pStr = UsartPrintfBuf;

    va_start(ap, fmt);
    vsprintf((char *)UsartPrintfBuf, fmt, ap);    //格式化
    va_end(ap);

    while(*pStr != 0)
    {
        USART1->TDR = *pStr++;
        while((USART1->ISR & 0x40)  == 0);
    }}//注意:在usart.h中添加void UsartPrintf(UART_HandleTypeDef *huart, char *fmt,...);//使用方法:UsartPrintf(&huart1,"hello world\r\n");/* USER CODE END 1 */

注意:自己添加的代码,需要在begin和end之间

2.设置初始计数值10000

注意,这是一个巧妙的处理。上面提到,编码器向前,计数值向上加;编码器向后,计数值向下减。问题就来了,一开始计数值为0,不是一减就溢出了吗?因此我们手动设置为10000,即ARR的1/2.(__HAL_TIM_SET_COUNTER(&htim2,10000);)

3.更新中断回调函数

进入更新中断后,说明已经溢出,需要重新装载,当然也可以加入自己需要的操作

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
    if(htim == &htim2)
    {
        __HAL_TIM_SET_COUNTER(&htim2,10000);
    }}

3.main函数

在main函数中,我们首先设置计数器初值为10000,然后打开编码器,每1S获取一次计数器的更新值,判断编码器信息

unsigned char Direction = 0;unsigned int EncoderCount = 0;unsigned int EachTime = 0;unsigned int Angle = 0;
while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    while(EachTime + 1000 != HAL_GetTick()) ;//精确延迟1S
    EachTime = HAL_GetTick();

    EncoderCount = __HAL_TIM_GET_COUNTER(&htim2);//获取计数器值

    Direction = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim2);//判断方向
    if(Direction == 0 ) //正转
    {
        Angle = (uint16_t)(((EncoderCount - 10000)/4) * 0.036);
        UsartPrintf(&huart1,"转动了 %d 度\r\n",Angle);
        UsartPrintf(&huart1,"转动角速度为%0.2f 圈/秒",(EncoderCount - 10000)/4000.0);
    }
    else
    {
        Angle = (uint16_t)(((10000-EncoderCount)/4) * 0.036);
        UsartPrintf(&huart1,"转动了 %d 度\r\n",Angle);
        UsartPrintf(&huart1,"转动角速度为%0.2f 圈/秒",(10000-EncoderCount)/4000.0);
    }
    __HAL_TIM_SET_COUNTER(&htim2,10000);    
  }

四、编译+下载

点击编译后,0 error,0 warning


image.png

小熊派连接在电脑上,代码下载到开发板

image.png

五、连接硬件

1.将小熊派串口1和电脑相连,即拨到 AT-MUC,按下复位键

image.png

2.连接欧姆龙编码器

编码器有四根线,我们不使用Z相,AB相分别与PA0 PA1相连,然后连接5V、GND

image.png

image.png

3.效果

打开串口调试助手,转动编码器可以看到对应的角度、角速度

image.png

至此,我们已经可以通过小熊派获取编码器的转动信息

附件中包含CubeMX工程、MDK工程、串口调试助手



【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。