这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 行业应用 » 汽车电子 » stm32f103驱动舵机

共1条 1/1 1 跳转至

stm32f103驱动舵机

高工
2025-09-01 19:59:28     打赏

一、功能描述
使用 STM32F103 上使用 PA8 引脚控制舵机 SG90,通过 PWM 脉冲宽度调制实现。
舵机通常需要 50Hz 周期 20ms 的 PWM 信号,脉冲宽度在 0.5ms(0°)~ 2.5ms(180°) 之间。

二. 认识舵机

1.硬件连接

舵机信号线 → PA8(TIM1_CH1,STM32F103 的高级定时器)
舵机 VCC → 外部电源(5V,建议单独供电,避免电流不足)
舵机 GND → STM32 的 GND

image.png

SG90 舵机产品参数

image.png

尺寸
image.png

  1. 代码实现

步骤 1:配置 TIM1 生成 PWM

使用 STM32CubeMX 配置:

启用 TIM1(高级定时器)。

设置 Channel1 为 PWM Generation。

设置 Prescaler 和 Counter Period 以生成 50Hz 的 PWM:

时钟频率(假设 72MHz):

Prescaler = 72-1 → 定时器时钟 = 1MHz(1μs 分辨率)

Counter Period = 20000-1 → 20ms 周期(50Hz)

PWM 模式:PWM Mode 1(向上计数)

Pulse(初始脉宽):

0° → 500(0.5ms)

90° → 1500(1.5ms)

180° → 2500(2.5ms)

启用 TIM1_CH1 对应的 GPIO(PA8)。

手动计算(无 CubeMX):

定时器时钟 = 72MHz(STM32F103 默认)

Prescaler = 72 - 1 → 定时器时钟 = 1MHz(1μs 分辨率)

Counter Period = 20000 - 1 → 20ms 周期(50Hz)

PWM 脉宽:

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, pulse_width);

pulse_width 范围:500 ~ 2500(对应 0.5ms ~ 2.5ms)

三、cube mx 配置
image.png
配置步骤
(1) CubeMX 设置
1.
选择 TIM1 → Channel1 → PWM Generation CH1
Counter Period(ARR):PWM 分辨率
Pulse(CCR):初始占空比
GPIO Settings确认 PA8 模式:应显示 TIM1_CH1
通道 1 模式,PWM Generation CH1,产生 PWM 信号
对应引脚,PA8,TIM1_CH1 输出引脚

image.png

四、代码

初始
TIM_HandleTypeDef htim1;

/* TIM1 init function */
void MX_TIM1_Init(void)
{

  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

  /* USER CODE BEGIN TIM1_Init 1 */

  /* USER CODE END TIM1_Init 1 */
  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 719;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 1999;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 0;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM1_Init 2 */

  /* USER CODE END TIM1_Init 2 */
  HAL_TIM_MspPostInit(&htim1);

}

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle)
{

  if(tim_pwmHandle->Instance==TIM1)
  {
  /* USER CODE BEGIN TIM1_MspInit 0 */

  /* USER CODE END TIM1_MspInit 0 */
    /* TIM1 clock enable */
    __HAL_RCC_TIM1_CLK_ENABLE();
  /* USER CODE BEGIN TIM1_MspInit 1 */

  /* USER CODE END TIM1_MspInit 1 */
  }
}

主函数
int main(void)
{

  // 重置所有外设,初始化Flash接口和Systick(系统滴答定时器)
  HAL_Init();

  // 配置系统时钟(如HSE、HSI、PLL等)
  SystemClock_Config();
  // 初始化所有配置的外设(如GPIO、TIM1等)
  MX_GPIO_Init();
  MX_TIM1_Init();

  // 用户自定义代码区域2(外设初始化后)
  // 启动TIM1的PWM通道1(PA8引脚输出PWM信号)
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
  /* USER CODE END 2 */

  while (1)
  { 
    // 定义延时时间(单位:毫秒)
    int i = 1000; // 循环延时1秒(1000ms)
    
    // 设置PWM脉宽为50(对应舵机0°位置)
    // 假设TIM1的PWM配置为:
    // - 计数器时钟 = 1MHz(1μs分辨率)
    // - 周期 = 20000(20ms)
    // - 脉宽50 = 50μs(实际应为500~2500,此处可能是示例错误)
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 50); 
    HAL_Delay(i); // 延时1秒

    // 设置PWM脉宽为250(对应舵机180°位置)
    // 250 = 250μs(实际应为500~2500,此处可能是示例错误)
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 250); 
    HAL_Delay(i); // 延时1秒

  }
}

五、实现效果
SG90000000000030.gif



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]