【STM32】Hal库学习——PWM驱动电机

本文记录了一位开发者使用STM32 HAL库配置PWM、定时器中断和编码器,实现四旋翼无人机电机控制的过程。详细介绍了如何设置芯片、时钟、串口、PWM、定时器中断以及编码器,同时分享了中断优先级配置和编码器速度计算的代码实现。作者强调了在使用HAL库时开启PWM的重要性,并分享了学习心得。
摘要由CSDN通过智能技术生成

51我觉得我学得差不多了,虽然有一些通讯协议还没学,但是由于忙着团队的考核于是要开始弄四旋翼无人机,我打算用stm32的hal库来写。在此留下我的学习印记。

一。配置Hal库

这部分参考【STM32】HAL库 PWM控制电机转速与编码器读取(超详解)HAL库的学习 —— PWM的配置及控制

1.芯片选择

这里根据自己所用的芯片来进行选择,我用的是stm32f103c8t6

 2.设置RCC(系统时钟)

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

 3.串口配置

这里我配置的是USART1,异步收发,波特率默认:115200 Bit/s

4.PWM配置 

使用定时器1通道1和通道4(TIM1_CH1和TIM1_CH4),频率10KHz在这里插入图片描述

PWM频率计算公式 f = 定时器时钟频率 / [ (Period+1) *(Prescaler) ]= 72M / (7199+1) *1 = 10k HZ

占空比计算公式 = P = pulse/per *100%

程序里面可以通过调用函数__HAL_TIM_SET_COMPARE(); 来改变占空比,我们就是通过这一函数来控制电机转速。

这里的定时器TIM1时钟为72MHz(自己通过时钟树去配置APB1的时钟频率)

若想深入了解Hal库中PWM各选项的含义,可学习此文 STM32对HAL库的PWM控制

5、定时器中断配置


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

在这里插入图片描述

 打开更新定时器中断在这里插入图片描述

7、编码器配置


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

在这里插入图片描述

7、中断优先级配置


  因为编码器中断要发生在定时10ms中断内,故编码器中断的抢占优先级要大于定时10ms在这里插入图片描述

8、配置时钟


  F1系列芯片系统时钟为72MHzs在这里插入图片描述

9、项目创建最后步骤

  • 设置项目名称
  • 选择所用IDE在这里插入图片描述

10、输出文件

  • ②处:复制所用文件的.c和.h
  • ③处:每个功能生产独立的.c和.h文件在这里插入图片描述

 11、创建工程文件


  点击GENERATE CODE 创建工程


到这里就完成工程配置了。

接下来就是我们代码部分了

代码部分

1、配置下载工具


  这里我们需要勾选上下载后直接运行,然后进行一次编译

STM32源代码

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)));    //检查SR标志位是否清零
	USART1->DR = ch;                  //将内容赋给DR位输出
	
	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)
        {
          // 打印定时器4的计数值,short(-32768——32767)
          printf("Encoder = %d moto = %d \r\n",MotorSpeed,MotorOutput);	
          i=0;
        }
    }
}
/* USER CODE END 4 */


学习心得:记得先开HAL_TIM_PWM_Start这个函数,要不然输出不了pwm波

  • 41
    点赞
  • 375
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
以下是使用STM32HAL库控制电机PWM示例代码: 1. 首先,需要在CubeMX中配置PWM通道和定时器。在Pinout & Configuration选项卡中,选择需要使用的定时器和PWM通道,并将其配置为PWM输出模式。然后在Configuration选项卡中,配置定时器的时钟源和频率,以及PWM的周期和占空比。 2. 在代码中,需要包含stm32f4xx_hal.h头文件,并初始化定时器和PWM通道。以下是一个示例代码: ```c #include "stm32f4xx_hal.h" TIM_HandleTypeDef htim2; TIM_OC_InitTypeDef sConfigOC; void MX_TIM2_Init(void) { TIM_MasterConfigTypeDef sMasterConfig = {0}; htim2.Instance = TIM2; htim2.Init.Prescaler = 0; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 999; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_Base_Init(&htim2) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { Error_Handler(); } } void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(tim_pwmHandle->Instance==TIM2) { __HAL_RCC_TIM2_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**TIM2 GPIO Configuration PA0/WKUP ------> TIM2_CH1 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 500; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); } } int main(void) { HAL_Init(); MX_TIM2_Init(); while (1) { // 设置占空比 __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 500); HAL_Delay(1000); __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 250); HAL_Delay(1000); } } ``` 在上面的代码中,我们使用了TIM2通道1和PA0引脚来控制电机。我们使用HAL_TIM_PWM_ConfigChannel函数来配置PWM通道,并使用HAL_TIM_PWM_Start函数来启动PWM输出。在主循环中,我们使用__HAL_TIM_SET_COMPARE函数来设置PWM的占空比,从而控制电机的转速。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值