STM32舵机控制详解
STM32是一款广泛应用于嵌入式系统开发的单片机,舵机是一种常见的机电传动装置,用于控制角度的精确位置。在本文中,我将为你详细介绍如何使用STM32来控制舵机,包括硬件连接和编程实现。我将使用STM32CubeIDE作为开发环境,并在NUCLEO-F446RE开发板上进行演示。
第一部分:硬件准备
在开始之前,我们需要准备以下硬件设备:
- STM32开发板(NUCLEO-F446RE)
- 舵机
- 杜邦线
接下来,我们需要将舵机与STM32开发板连接起来。舵机通常有三个线,包括电源线(红色)、地线(黑色)和信号线(白色、黄色等)。在本例中,我们将使用直流电源为舵机供电。将舵机的电源线连接到STM32开发板的5V引脚,将地线连接到开发板的GND引脚,将信号线连接到开发板的任意GPIO引脚。
第二部分:软件准备
在开始编程之前,我们需要安装STM32CubeIDE,并配置好开发环境。你可以从STMicroelectronics的官方网站上下载并安装最新版本的STM32CubeIDE。
安装完成后,打开STM32CubeIDE,并按照以下步骤进行配置:
-
创建一个新的STM32项目。选择File -> New -> STM32 Project。在弹出的对话框中,选择“NUCLEO-F446RE”作为目标板,输入项目名称,并选择合适的工程路径。点击“Next”进入下一步。
-
选择合适的MCU系列和型号。在弹出的对话框中,选择“STM32F4 Series”和“STM32F446xx”。点击“Next”进入下一步。
-
配置项目设置。在弹出的对话框中,选择相应的时钟配置,并勾选“RTE”选项。点击“Finish”完成项目配置。
-
配置引脚。在CubeMX视图中,选择“Pinout & Configuration”选项卡,然后按照舵机信号线连接到的GPIO引脚配置对应的引脚模式和输出类型。
-
生成代码。点击CubeMX视图左上角的“Project”按钮,选择“Generate Code”选项。这将生成初始化代码和驱动文件,并将其添加到项目中。
现在,我们已经完成了软件环境的配置,可以开始编写舵机控制的代码了。
第三部分:舵机控制代码实现
在本部分,我将为你提供一个简单的代码示例,来控制舵机的角度。
首先,我们需要引入相应的头文件和库文件,并定义一些常量和变量:
#include "stm32f4xx_hal.h"
#include "main.h"
#define SERVO_GPIO_PORT GPIOA
#define SERVO_GPIO_PIN GPIO_PIN_0
TIM_HandleTypeDef htim2;
接下来,我们需要进行一些初始化配置。在MX_TIM2_Init()
函数中,我们将设置定时器的参数和通道的参数:
void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 83; // 设置预分频器,将定时器时钟设置为1 MHz
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 19999; // 设置自动重装值,将周期设置为20ms,对应50 Hz的PWM信号
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != 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_PWM2;
sConfigOC.Pulse = 1500; // 设置初始占空比,对应1.5 ms的脉宽
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
}
在SystemClock_Config()
函数中,我们需要配置系统时钟:
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
接下来,我们需要实现主函数main()
。在函数中,我们将初始化GPIO引脚和定时器,并控制舵机的角度。
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM2_Init();
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); // 启动定时器2的通道1的PWM输出
while (1)
{
for (int angle = 0; angle < 180; angle += 10)
{
int pulse = angle_to_pulse(angle); // 将角度转换为对应的脉宽
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pulse); // 设置脉宽
HAL_Delay(500); // 延时500ms
}
}
}
在上述代码中,我们使用了一个名为angle_to_pulse()
的自定义函数来将角度转换为对应的PWM脉宽。函数的实现如下:
int angle_to_pulse(int angle)
{
int pulse = (angle * 10) + 500;
return pulse;
}
通过上述代码,我们已经完成了舵机控制的代码实现。在主函数中,我们通过循环将舵机的角度从0度逐渐增加到180度,并通过PWM输出来控制舵机的角度。
第四部分:编译和下载
编译代码时,你可以点击STM32CubeIDE顶部菜单的“Project”按钮,选择“Build Project”选项。编译成功后,你可以通过链接器按钮
作者:大黄鸭duck.