文章目录[隐藏]
大家好,我是小政。本篇文章我将针对PWM控制电机与编码器读取电机转速的STM32CubeMX配置过程进行详细的讲解,让准备学习HAL库的小伙伴能够更好的理解STM32CubeMX如何配置。
有小伙伴对于电机驱动和编码器不懂的话请看:
电机驱动讲解:【平衡小车制作】(二)电机驱动(超详解)
编码器讲解:【平衡小车制作】(三)编码器讲解(超详解)
下一篇文章会推出利用PID算法闭环控制电机转速(HAL库)。
话不多说,开始今天的学习吧!
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(根据自己的板子来进行选择)
2、设置RCC
设置高速外部时钟HSE 选择外部时钟源
3、LED1配置
我使用的板子LED1引脚为PD2,初始电平为高电平,目的是通过观察小灯的亮灭判断是否进入定时器中断
4、USART1配置
异步收发,波特率默认:115200 Bit/s
5、PWM配置
使用定时器1通道1和通道4(TIM1_CH1和TIM1_CH4),频率10KHz
6、定时器中断配置
使用定时器2(TIM2),周期设为10ms,即10ms进一次定时器中断
打开更新定时器中断
7、编码器配置
STM32自带编码器配置,使用定时器4(TIM4_CH1和TIM4_CH2),打开更新定时器中断
8、中断优先级配置
因为编码器中断要发生在定时10ms中断内,故编码器中断的抢占优先级要大于定时10ms
9、配置时钟
F1系列芯片系统时钟为72MHzs
10、项目创建最后步骤
- 设置项目名称
- 选择所用IDE
11、输出文件
- ②处:复制所用文件的.c和.h
- ③处:每个功能生产独立的.c和.h文件
12、创建工程文件
点击GENERATE CODE 创建工程
13、配置下载工具
这里我们需要勾选上下载后直接运行,然后进行一次编译
3、STM32源代码:
(1)下面的代码之前有用过hal库的小伙伴应该都很容易理解,小政就不过多解释,有不懂的地方欢迎在评论区下方提问。在main.c加上:
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "math.h"
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
unsigned int MotorSpeed; // 电机当前速度数值,从编码器中获取
int MotorOutput; // 电机输出
/* USER CODE END PV */
/* USER CODE BEGIN 0 */
int fputc(int ch, FILE *p)
{
while(!(USART1->SR & (1<<7)));
USART1->DR = ch;
return ch;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // TIM1_CH1(pwm)
HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_1); // 开启编码器A
HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_2); // 开启编码器B
HAL_TIM_Base_Start_IT(&htim2); // 使能定时器2中断
/* USER CODE END 2 */
/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static unsigned char i = 0;
if (htim == (&htim2))
{
//1.获取电机速度
MotorSpeed = (short)(__HAL_TIM_GET_COUNTER(&htim4)/18);
// TIM4计数器获得电机脉冲,该电机在10ms采样的脉冲/18则为实际转速的rpm
__HAL_TIM_SET_COUNTER(&htim4,0); // 计数器清零
//2.将占空比导入至电机控制函数
MotorOutput=3600; // 3600即为50%的占空比
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, MotorOutput);
MotorOutput=MotorOutput*100/7200;
// 占空比(按最高100%计算,串口打印)
i++;
if(i>100)
{
// 通过观察小灯亮灭来判断是否正确进入定时器中断
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_2);
// 打印定时器4的计数值,short(-32768——32767)
printf("Encoder = %d moto = %d \r\n",MotorSpeed,MotorOutput);
i=0;
}
}
}
/* USER CODE END 4 */
(2)烧入STM32中,串口展示:
(3)实物展示:
4、下载
(1)程序下载地址:https://pan.baidu.com/s/1mXYS8lQKaMX6XNA961UuJw
提取码:z3ax
(2)串口助手下载地址:https://pan.baidu.com/s/11xBkoLBMVcIv7QNALpOeeg
提取码:yzx3
5、总结
以上就PWM控制电机转速与编码器读取电机速度的HAL库配置与keil编程,后续会推出利用PID算法闭环控制电机转速(HAL库),若文章中出现错误或者小伙伴对以上内容有所疑问,欢迎大家在评论区留言,小政看到后会尽快回复大家!我们下期再见!
版权声明:本文为CSDN博主「鲁乎乎」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44270218/article/details/114045057
暂无评论