你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 HAL库 PWM控制电机转速与编码器读取(超详解)

[复制链接]
STMCU小助手 发布时间:2022-5-24 11:05
本篇文章我将针对PWM控制电机与编码器读取电机转速的STM32CubeMX配置过程进行详细的讲解,让准备学习HAL库的小伙伴能够更好的理解STM32CubeMX如何配置。

1、硬件准备
(1)所需硬件

芯片:STM32F103RCT6
驱动:电机驱动板或TB6612(电机驱动芯片)
电池:12V Libo电池
电机:带编码器电机
轮子:我用的是麦克纳姆轮
(2)硬件连接:

PA8 —— 电机驱动板PWM1
GND —— 电机驱动板PWM2
(这里若要反转则PWM1接地,PWM2接PA8;如果在小车中两者都需接PWM引脚,正转:PWM1给一定占空比,PWM2占空比为0)
PA9(USART1_RX) —— 接串口TX
PA10(USART1_TX) —— 接串口RX
PB6 —— 编码器A
PB7 —— 编码器B
2、STM32CubeMX配置:
1.1 所用工具:

芯片:STM32F103RCT6
IDE:MDK-Keil软件
STM32F1xxHAL库

1.2 知识概括:

STM32CubeMX创建TIMx、USART例程
Keil软件程序编写

1.3 工程创建
1、芯片选择
  芯片:STM32F103RCT6(根据自己的板子来进行选择)

23D0~9`L~7GL07(I_[N{KE2.png

2、设置RCC
  设置高速外部时钟HSE 选择外部时钟源

PW`{J8OBH2[{M@N[5PNQZ79.png

3、LED1配置
  我使用的板子LED1引脚为PD2,初始电平为高电平,目的是通过观察小灯的亮灭判断是否进入定时器中断

$({RM4FPK)]`4S%9ST`Y2IV.png

4、USART1配置
  异步收发,波特率默认:115200 Bit/s

H)P`$@T]OH)A_H[{)H(6@YF.png

5、PWM配置
  使用定时器1通道1和通道4(TIM1_CH1和TIM1_CH4),频率10KHz

SOU4}_(_UV`NP()~L2RAZ%6.png

6、定时器中断配置
  使用定时器2(TIM2),周期设为10ms,即10ms进一次定时器中断

[6DJT48_KSPB0OWES)C%C.png

  打开更新定时器中断

YOU~W`VS981(97ETMJ_GWQ4.png

7、编码器配置
  STM32自带编码器配置,使用定时器4(TIM4_CH1和TIM4_CH2),打开更新定时器中断

WWM7WN6[4QEZV49ZC(5FD_V.png

8、中断优先级配置
  因为编码器中断要发生在定时10ms中断内,故编码器中断的抢占优先级要大于定时10ms

}_DSEQOI[MC]KJKD5}(][4V.png

9、配置时钟
  F1系列芯片系统时钟为72MHzs

4NX{AV$J28BT0`HN2LHC%GC.png

10、项目创建最后步骤

设置项目名称
选择所用IDE

_WFXTK(}2ZE8I8EMBL1)[YC.png

11、输出文件

②处:复制所用文件的.c和.h
③处:每个功能生产独立的.c和.h文件

WQR2U9C_7V691HYV7Q$VL96.png

12、创建工程文件
  点击GENERATE CODE 创建工程

13、配置下载工具
  这里我们需要勾选上下载后直接运行,然后进行一次编译

6F5%O4Y~9Y2M[QO1[68RUXP.png

3、STM32源代码:
(1)下面的代码之前有用过hal库的小伙伴应该都很容易理解,小政就不过多解释,有不懂的地方欢迎在评论区下方提问。在main.c加上:

  1. /* USER CODE BEGIN Includes */
  2. #include "stdio.h"
  3. #include "math.h"
  4. /* USER CODE END Includes */
复制代码
  1. /* USER CODE BEGIN PV */
  2. unsigned int MotorSpeed;  // 电机当前速度数值,从编码器中获取
  3. int MotorOutput;                  // 电机输出
  4. /* USER CODE END PV */
复制代码
  1. /* USER CODE BEGIN 0 */
  2. int fputc(int ch, FILE *p)
  3. {
  4.         while(!(USART1->SR & (1<<7)));
  5.         USART1->DR = ch;
  6.         
  7.         return ch;
  8. }
  9. /* USER CODE END 0 */
复制代码
  1.   /* USER CODE BEGIN 2 */
  2.   HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);            // TIM1_CH1(pwm)
  3.   HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_1); // 开启编码器A
  4.   HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_2); // 开启编码器B        
  5.   HAL_TIM_Base_Start_IT(&htim2);                // 使能定时器2中断
  6.   /* USER CODE END 2 */
复制代码
  1. /* USER CODE BEGIN 4 */
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  3. {
  4.     static unsigned char i = 0;
  5.     if (htim == (&htim2))
  6.     {
  7.         //1.获取电机速度
  8.         MotorSpeed = (short)(__HAL_TIM_GET_COUNTER(&htim4)/18);   
  9.         // TIM4计数器获得电机脉冲,该电机在10ms采样的脉冲/18则为实际转速的rpm
  10.         __HAL_TIM_SET_COUNTER(&htim4,0);  // 计数器清零


  11.         //2.将占空比导入至电机控制函数
  12.         MotorOutput=3600; // 3600即为50%的占空比
  13.         __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, MotorOutput);
  14.         MotorOutput=MotorOutput*100/7200;
  15.         // 占空比(按最高100%计算,串口打印)
  16.         i++;
  17.         if(i>100)
  18.         {
  19.           // 通过观察小灯亮灭来判断是否正确进入定时器中断
  20.           HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_2);
  21.           // 打印定时器4的计数值,short(-32768——32767)
  22.           printf("Encoder = %d moto = %d \r\n",MotorSpeed,MotorOutput);        
  23.           i=0;
  24.         }
  25.     }
  26. }
  27. /* USER CODE END 4 */
复制代码

(2)烧入STM32中,串口展示:

O`T47Y5J`LF6UMHK{DLRM]G.png

(3)实物展示:

WO8L63G[V)3I$BYDF]A`T`A.png


4、总结
  以上就PWM控制电机转速与编码器读取电机速度的HAL库配置与keil编程,后续会推出利用PID算法闭环控制电机转速(HAL库)


收藏 1 评论0 发布时间:2022-5-24 11:05

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版