作为一名嵌入式开发工程师,我经常需要用到STM32系列单片机来控制各种外设。今天要分享的是如何通过串口通讯来控制舵机旋转到指定角度。这个项目非常适合刚接触STM32的开发者作为入门练习,因为它涵盖了时钟配置、PWM生成、串口通讯等嵌入式开发的核心知识点。
在实际项目中,我们经常需要通过上位机来控制下位机执行特定动作。比如在机器人控制中,就需要通过串口发送指令来精确控制各个关节的角度。本文将以STM32F103C8T6(俗称"蓝莓派")为例,详细讲解如何实现这一功能。
舵机的控制原理其实很简单:通过PWM信号的占空比来控制角度。标准舵机通常接受50Hz(周期20ms)的PWM信号,其中:
在STM32中,我们需要配置定时器来产生这样的PWM信号。需要注意的是,不同品牌的舵机可能对脉宽范围有微小差异,实际使用前最好查阅具体型号的规格书。
串口通讯是嵌入式系统中最常用的通讯方式之一。在本项目中,我们使用USART1与电脑进行通讯,波特率设为9600。这里有几个关键点需要注意:
提示:建议将工程保存在没有中文路径的目录下,避免一些潜在的问题。
时钟配置是STM32开发中最容易出错的部分之一。我们需要将系统时钟配置为72MHz,原因如下:
具体配置步骤:
这样配置后,系统时钟将达到72MHz,完全满足我们的需求。
这样配置后,TIM2将产生50Hz的PWM信号,通过调节Pulse值可以改变占空比,从而控制舵机角度。
主程序主要完成以下任务:
c复制int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM2_Init();
MX_USART1_UART_Init();
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
HAL_UART_Receive_IT(&huart1, &rx_data, 1);
while (1)
{
if(cmd_ready == 1)
{
cmd_ready = 0;
// 处理角度指令
}
}
}
当串口接收到数据时,会触发中断回调函数。我们需要在这个函数中验证数据的有效性,并设置标志位通知主程序。
c复制void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
if(rx_data >= ANGLE_MIN && rx_data <= ANGLE_MAX)
{
angle_received = rx_data;
cmd_ready = 1;
}
HAL_UART_Receive_IT(&huart1, &rx_data, 1);
}
}
将角度值转换为PWM的比较值是一个线性映射过程:
c复制uint16_t pwm_compare = PWM_MIN + (uint32_t)(angle_received * (PWM_MAX - PWM_MIN)) / ANGLE_MAX;
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pwm_compare);
这里PWM_MIN对应0度,PWM_MAX对应180度。根据舵机的规格,可以调整这两个值来获得最佳的控制效果。
舵机不转动:
串口通讯失败:
PWM控制不精确:
这个项目虽然简单,但可以应用于很多实际场景:
我在一个智能家居项目中就使用了类似的技术,通过手机APP控制窗帘的开合角度。关键在于理解基本原理后,可以根据具体需求进行灵活调整。