STM32系列(HAL库)——F103C8T6 控制SG90舵机

1.软件准备 

(1)编程平台:Keil5

(2)CubeMX

2.硬件准备

(1)F1的板子,本例使用经典F103C8T6

(2)一个捡来的舵机

(3)ST-link 下载器

(4)杜邦线若干

 3.关于舵机控制原理

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

 

4.CubeMX配置

(1)芯片选择

 (2)配置RCC、SYS、时钟树

配置RCC

配置SYS

配置时钟树

(3)配置定时器产生PWM波形

                         此时产生PWM波形频率:72M / 719 / (1999+1) = 50HZ     

                        波形周期:1  / 50 = 20ms

                        初始占空比为:0%

(4)设置路径、生成代码工程

5、Keil5代码

(1)main函数

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);//***定时器初始化
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  { 
      int i=1000; //循环时间间隔1s
      
      __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,50); //相当于一个周期内(20ms)有0.5ms高脉冲
      HAL_Delay(i);
      __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,250); //相当于一个周期内(20ms)有2.5ms高脉冲
      HAL_Delay(i);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

        可以通过修改句柄__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,250)里的参数可以实现舵机角度控制。

6.接线图及效果

 本例程源码下载:本例程源码下载:点击跳转

以下是一个简单的驱动SG90舵机的示例代码,基于STM32F103C8T6HAL库: ``` #include "stm32f1xx_hal.h" #define SERVO_GPIO_PORT GPIOA #define SERVO_GPIO_PIN GPIO_PIN_0 TIM_HandleTypeDef htim2; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM2_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM2_Init(); while (1) { TIM2->CCR1 = 50; //设置脉冲宽度为0.5ms,即0度 HAL_Delay(1000); TIM2->CCR1 = 75; //设置脉冲宽度为0.75ms,即90度 HAL_Delay(1000); TIM2->CCR1 = 100; //设置脉冲宽度为1ms,即180度 HAL_Delay(1000); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } static void MX_TIM2_Init(void) { TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; htim2.Instance = TIM2; htim2.Init.Prescaler = 71; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 1999; 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(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 50; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = SERVO_GPIO_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(SERVO_GPIO_PORT, &GPIO_InitStruct); } ``` 在本例中,使用TIM2通道1和GPIOA.0来驱动舵机。在while循环中,按顺序设置脉冲宽度为0.5ms(即0度)、0.75ms(即90度)和1ms(即180度),并延迟1秒钟。你可以根据自己的需求更改这些值。
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式创客工坊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值