STM32F1/HAL库/CubeMX下实现编码器模式测速:平衡小车与直流减速电机的超详细指南

系列文章目录(STM32常用外设/HAL库版)

一、HC-SR04超声波模块的使用
二、OLED的HAL库代码介绍及使用
三、直流减速电机的测速以及电机驱动的使用(本篇)


文章目录

  • 系列文章目录(STM32常用外设/HAL库版)
  • 前言
  • 一、所用的器材模块介绍
  • 二、接线说明
  • 三、CubeMX配置
  • 3.1. 时钟树的配置
  • 3.2. PWMA配置(TIM4)
  • 3.3. 编码器模式配置(TIM3)
  • 3.4. 定时器配置(TIM1)
  • 3.5. IIC和USART配置
  • 3.6. NVIC配置
  • 3.7. 最终引脚图
  • 四、程序代码及说明
  • 4.1. encoder.h
  • 4.2. encoder.c
  • 4.3. motor.h
  • 4.4. main.c
  • 总结

  • 前言

    由于之后要着手开始做一些闭环的小项目,比如常见的两轮平衡小车,那就必须使用编码器来测量直流减速电机的转速,本文将介绍如何使用stm32f103c8t6的编码器模式测量带15线霍尔编码器的直流减速电机的空载转速。

    预告:我即将会写一篇全网最详细PID平衡小车教程(HAL库版)


    先放上最终效果展示吧

    使用STM32的编码器模式测量直流减速电机的转速





    提示:以下是本篇文章正文内容,下面案例可供参考

    一、所用的器材模块介绍

    1. stm32f103c8t6最小系统板
    2. 12V锂电池
    3. DC-DC可调降压模块(LM2596S)
    4. 0.96寸OLED(IIC接口)
    5. HC-08蓝牙模块
    6. 两路直流电机驱动(这里用的是DRV8848而不是TB6612,因为TB6612已经停产)
    7. 直流减速电机(电机型号为GM25-370,空载转速12V12000RPM,减速比为34:1,减速后350转/分)
    8. 15线霍尔编码器(编码器单圈15脉冲,减速后单圈为510脉冲每圈,可以通过stm32编码器模式4倍频至2040脉冲每圈)

    所用的带15线霍尔编码器的GM25-370直流减速电机及其参数见下图


    所用模块的具体作用:
    蓝牙模块:通过手机蓝牙直接改变电机转速
    OLED:实时显示电机的转速以及读取到的脉冲数

    二、接线说明

    特别注意:这步至关重要,稍有不慎就会烧坏单片机

    下面给出原理图:(最好不要把电机驱动板上所有的GND都与单片机共地,VCC下面的GND可以不与单片机共地,还有就是STM32只外接信号线,不要用它给电机驱动板的VCC供电,STM32接一些感性负载(比如电机)时最好加光耦隔离,我之前也是用了光耦隔离,但是要想完全隔离只能用双电源,最终就没加)

    三、CubeMX配置

    3.1. 时钟树的配置

    (1)点击RCC ,开启HSE,并选择RC或晶体作为时钟源

    (2)配置时钟树

    3.2. PWMA配置(TIM4)

    (1)点击TIM4,在Mode选项中设置Clock Source为Internal Clock。设置Channel1为PWM Generation CH1,其余默认即可。

    (2)设置Configuration选项中Parameter Settings的参数

    将PWM设置为10KHz

    (3)TIM4_CH1 的GPIO参数设置
    PB6参数设置

    3.3. 编码器模式配置(TIM3)

    (1)点击TIM3,在Mode选项中设置Combined Channels为编码器模式。

    (2)设置Configuration选项中Parameter Settings的参数

    注意:将Encoder Mode 设置为Encoder Mode TI1 and TI2,使得编码器模式为4倍频模式,得到的脉冲值X4

    编码器模式中Polarity是用来设置触发的信号是否反向,即用来匹配编码器与电机的旋转方向,而不是像“输入捕获”功能那样用来设置触发的边沿

    (3)GPIO参数设置

    3.4. 定时器配置(TIM1)

    配置定时器,配置为0.1S定时中断一次读取TIM3编码器模式记录的脉冲值

    3.5. IIC和USART配置

    这部分就是开启I2C1的I2C模式,开启USART2的异步模式

    3.6. NVIC配置

    开启TIM1 update interrupt,USART2 global interrupt 两个中断并将USART2 global interrupt的优先级设置的高于TIM1 update interrupt,因为要通过串口接收中断来改变转速,如果串口中断的优先级低于定时器中断的优先级,此时串口中断就不能立刻执行


    3.7. 最终引脚图

    四、程序代码及说明

    提示:OLED代码见OLED的HAL库代码介绍及使用,这里就不再赘述

    4.1. encoder.h

    #ifndef ENCODER_ENCODER_H_
    #define ENCODER_ENCODER_H_
    
    #include "stm32f1xx_hal.h" //HAL库文件声明
    #include <main.h>
    
    extern TIM_HandleTypeDef htim1;
    extern TIM_HandleTypeDef htim3;
    
    void GET_NUM(void);
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
    
    #endif /* ENCODER_ENCODER_H_ */
    
    

    4.2. encoder.c

    #include"encoder.h"
    #include"../oled/oled.h"
    
    float  n=0;//转速,单位为:转/秒
    short encoder_counter=0;//STM32编码器模式读取的总脉冲数
    
    /**
     * @function: void GET_NUM(void)
     * @description: 使用STM32编码器模式,读取编码器产生的脉冲值
     * @param {*} 
     * @return {*}
     */
    void GET_NUM(void)
    {
    	encoder_counter=(short) __HAL_TIM_GET_COUNTER(&htim3);
    	__HAL_TIM_SET_COUNTER(&htim3,0);
    }
    
    /**
     * @function:void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
     * @description: 定时器中断回调函数,0.1S中断一次并计算转速,将电机转速以及编码器产生的脉冲数显示在OLED屏上
     * @param {TIM_HandleTypeDef *htim} 
     * @return {*}
     */
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
    	if(htim==&htim1)
    	{
    		 GET_NUM();//得到所记录的脉冲数
    		 OLED_Showdecimal(0,6,encoder_counter,5,2,12,0);//在特定位置显示5位整数+2位小数的脉冲数
    		 n=(float)encoder_counter/2040/0.1;//转速为n,r/s
    		 OLED_Showdecimal(0,4,n,2,2,12,0);//在特定位置显示2位整数+2位小数的电机转速
    	}
    }
    
    

    4.3. motor.h

    这个.h就是给电机驱动板AO1,AO2赋高低电位的

    #ifndef MOTOR_MOTOR_H_
    #define MOTOR_MOTOR_H_
    
    #include "stm32f1xx_hal.h" //HAL库文件声明
    #include <main.h>
    
    #define MOTOR_GO HAL_GPIO_WritePin(GPIOA, AIN1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, AIN2_Pin, GPIO_PIN_SET)
    
    #endif /* MOTOR_MOTOR_H_ */
    
    

    4.4. main.c

    /* USER CODE BEGIN Includes */
    #include "../../icode/motor/motor.h"
    #include "../../icode/usart/usart.h"
    #include "../../icode/encoder/encoder.h"
    #include "../../icode/oled/oled.h"
    /* USER CODE END Includes */
    

      /* USER CODE BEGIN 2 */
      HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); //开启TIM4 PWMA模式
      HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);//开启TIM3编码器模式
      HAL_UART_Receive_IT(&huart2,(uint8_t *)&USART2_NewData,1); //开启串口二的接收中断,用于蓝牙改变电机转速
      HAL_TIM_Base_Start_IT(&htim1);//开启TIM1的定时器中断
    
      OLED_Init();                           //OLED初始
      OLED_Clear();                         //清屏
      OLED_ShowString(0,0,"Rotational Speed:",12,0);
      OLED_ShowString(50,4,"rad/s",12,0);
        /* USER CODE END 2 */
    

    下面这部分main.c内容是通过蓝牙改变电机转速,与本文的重点>通过STM32编码器模式对直流减速电机测速的讲解关系不大

      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
    
    	  if(USART2_RX_STA&0x8000)           //判断中断接收标志位(蓝牙模块使用USART2)
    	  {
    		 if((USART2_RX_STA&0x7FFF) ==4 	//判断接收数量是不是为四个
    				&& USART2_RX_BUF[0]==0xA5 	//判断接收第一个数据是不是包头0xA5
    				&& USART2_RX_BUF[3]==(USART2_RX_BUF[1]+USART2_RX_BUF[2])%0x100)	//判断接收校验码是不是原数据之和的低八位
    
    		{
    			 switch(USART2_RX_BUF[2])      //接收并读取蓝牙发送过来的第三个数,改变车速
    			 {   //ARR的在CubeMX中设置为20000
    
    				 case(0x00):__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1,0);break;    //0%的speed
    
    				 case(0x14):__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1,1440) ;break;//20%
    
    				 case(0x28):__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1,2880) ;break;//40%
    
    				 case(0x3C):__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1,4320);break;//60%
    
    				 case(0x50):__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1,5760);break;//80%
    
    				 case(0x64):__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1,7200);break;//100%
    
    				 default:break;
    
    			 }
    		}
    		USART2_RX_STA=0;//标志位清0
    	  }
    
    	  MOTOR_GO;
      }
      /* USER CODE END 3 */
    
    

    总结

    最终结果就是文章开头视频中显示的,还是测量的比较精准,和电机的参数十分接近,这部分内容对于之后的平衡小车至关重要,因为后续PID控制时要经常读取电机转速来对小车进行闭环控制。

    码字不易,希望喜欢的小伙伴别忘了点赞+收藏+关注,你们的肯定就是我创作的动力

    欢迎大家积极交流,本文未经允许谢绝转载!!!

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32F1/HAL库/CubeMX下实现编码器模式测速:平衡小车与直流减速电机的超详细指南

    发表评论