STM32 CubeIDE 模拟舵机sg90控制

1、简介

  舵机有数字舵机和模拟舵机,数字舵机一般价格高,带限位,旋转最大0-180就会停止。模拟舵机,比如sg90,不带限位,如果控制不合理,那么就会出现旋转360的结果。
使用sg90舵机测试,这个舵机的三根线分别为:GND(棕色)、VCC(红色)、PWM(黄色)。

  舵机一般是需要通过PWM经行控制的,控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度伺服为例,那么对应的控制关系是这样的:

  时间      ----------->    角度
  0.5ms     ----------->    0度;

  1.0ms     ----------->    45度;

  1.5ms     ----------->    90度;

  2.0ms     ----------->    135度;

  2.5ms     ----------->   180度;

使用STM32 单片机定时器输出一个20ms的PWM波,通过改变占空比值,实现舵机的控制。

一度的占空比 = 1 / 90 * 角度 + 0.5

2、创建编写

使用STM32F103RC经行测试,使用定时器3的PWM通道1。
在这里插入图片描述
在这里插入图片描述

2.1 控制时间计算方式

定时器3使用的是APB1,所以时钟频率为72MHz。

在这里插入图片描述
方式1:分频720,设定值(720-1),计数值2000,设定值(2000-1)
PWM 频率:2000 * 720 / 72000000 = 0.02s = 20ms
1、设置定时器预分频器为719(即:720-1)可以得到100KHz的定时器计数时钟;
2、设定定时器计数周期为1999(即:2000-1),这样定时器的频率为50Hz,即可得到20ms的周期;
3、设置定时器的通道1(CH1)为PWM模式1(配置默认模式1),脉冲数为150,即可得到1.5ms的高电平时间。

方式2:
上面图片所示,是方式2的配置,方式1类似。
分频7200,设定值(7200-1),计数值200,设定值(200-1)
PWM 频率:200 * 7200 / 72000000 = 0.02s = 20ms
计数值是200,那么计算1度的时间就要扩大10倍:
一度的占空比 = 1 / 9 * 角度 + 5

2.2、代码

方式1:
开启定时器PWM
在这里插入图片描述

HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);

修改占空比:
150 是指计数周期,舵机就回转动90度,和上面那个时间相对应。下面2种方式都可以修改占空比,只是第二种在直接修改寄存器值。

 __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 150);
   //htim3.Instance->CCR1 = 150;//修改占空比
 while (1)
  {
    
    

	  __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 150);
	  HAL_Delay(500);
	  __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 90);
	  HAL_Delay(500);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

方式2:
使用上面说到的那个公式
开启定时器PWM:
在这里插入图片描述

//HAL_TIM_Base_Start(&htim3);
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);

  /* USER CODE END 2 */

舵机控制函数:

/* USER CODE BEGIN 4 */
/// angle:角度值,0~180
void Servo_Control(uint16_t angle)
{
    
    
   float temp;
   temp =(1.0 / 9.0) * angle + 5.0;  //占空比值 = 1/9 * 角度 + 5
   __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, (uint16_t )temp);//修改占空比
   //htim3.Instance->CCR1 = temp;//修改占空比
}
/* USER CODE END 4 */
while (1)
  {
    
    
	  Servo_Control(120);//120度
	  HAL_Delay(500);
	  Servo_Control(90); //90度
	  HAL_Delay(500);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

猜你喜欢

转载自blog.csdn.net/weixin_45488643/article/details/108237545