前言

最近在做黑龙江东方学院鸿蒙班的物联网实验——智能道闸项目。基于STM32L431主控+鸿蒙LiteOS,利用定时器PWM输出驱动两路舵机,对比智慧交通、智慧家居两块扩展板差异,修改驱动完成双道闸同步开关。本篇把整个实验原理、代码修改要点、踩坑记录完整整理出来,适合刚上手鸿蒙物联网开发的同学参考。

一、实验硬件环境

  • 主控板:NBV2.0(STM32L431VC)
  • 扩展板:智慧家居扩展板(支持两路舵机端子)
  • 执行器件:2个MG996R舵机
  • 系统:华为鸿蒙LiteOS
  • 调试工具:串口助手、Keil工程

⚠️硬件区别重点

  1. 智慧交通扩展板:硬件只引出1路舵机接口,只能驱动单个舵机;
  2. 智慧家居扩展板:引出两路舵机端子,可以同时挂载两个舵机。

引脚分配:

  • PA11 → TIM1_CH4:舵机1 PWM输出
  • PA15 → TIM2_CH1:舵机2 PWM输出

二、工作原理

舵机依靠50Hz PWM信号控制旋转角度。 本实验TIM1、TIM2配置:预分频=799,自动重装载值=1999,输出标准50Hz舵机驱动波形。

改变定时器通道CCR比较值,就可以调整PWM高电平时间,从而控制舵机旋转不同角度。

GPIO引脚不能当作普通输出,需要配置为定时器复用推挽输出,才能输出PWM波形驱动舵机。

三、软件架构分析

3.1 main主函数:LiteOS启动流程

main函数不写业务逻辑,只负责硬件与操作系统初始化,业务逻辑放在任务中执行。 执行顺序:硬件HAL初始化 → 系统时钟 → 显示/控制任务初始化 → LiteOS内核初始化 → 创建任务 → LOS_Start()启动操作系统。

int main(void)
{
    UINT32 uwRet = LOS_OK;
    /*初始化*/
    HAL_Init();                    //硬件初始化
    sysclkinit();                  //系统时钟初始化
    task_view_init();              //显示任务初始化
    task_control_init();           //控制任务初始化
    uwRet = LOS_KernelInit();      //操作系统初始化
    if (uwRet != LOS_OK)
    {
        return LOS_NOK;
    }
    uwRet = creat_control_task();    //创建控制任务
    if (uwRet != LOS_OK)
    {
        return LOS_NOK;
    }
    uwRet = creat_view_task();       //创建显示任务
    if (uwRet != LOS_OK)
    {
        return LOS_NOK;
    }
    LOS_Start();	     //启动操作系统
    while (1)
    {
    }
}

重点:LOS_Start()之后,操作系统接管CPU,main函数的while(1)永远不会执行。

3.2 舵机驱动 p0080.c 修改核心

原始代码适配智慧交通扩展板,只能单路舵机;想要智慧家居扩展板两路舵机同时动作,两处必须修改:

① P0080_Init 初始化函数

同时启动TIM1_CH4、TIM2_CH1两路PWM通道,上电舵机默认0°(道闸关闭状态)

void P0080_Init(void)
{
    MX_GPIO_Init();
    MX_TIM1_Init();
    MX_TIM2_Init();
    HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_4);
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
    Set_Servo_PWM(DEGREE_0);
}
② Set_Servo_PWM角度设置函数

设置角度时,同时更新两个定时器通道比较寄存器,让两个舵机同步接收PWM指令。

void Set_Servo_PWM(unsigned int degree)
{
	unsigned int pwm = 0;
	switch ( degree )
	{
	    case DEGREE_MINOR_90:
	        pwm = 50;
	        break;
	    case DEGREE_MINOR_45:
	        pwm = 100;
	        break;
	    case DEGREE_0:
	        pwm = 150;
	        break;
	    case DEGREE_45:
	        pwm = 200;
	        break;
	    case DEGREE_90:
	        pwm = 250;
	        break;
	    default:
	    	pwm = 50;
	        break;
	}
  	__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_4,pwm);
	__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_1,pwm);
}

对外业务调用接口:

//道闸抬起,舵机转到90°
void Servo_Open(void)
{
    Set_Servo_PWM(DEGREE_90);
}
//道闸落下,舵机回到0°
void Servo_Close(void)
{
    Set_Servo_PWM(DEGREE_0);
}

3.3 PA11、PA15引脚复用配置

引脚配置在HAL_TIM_MspPostInit函数内部,把PA11、PA15设置复用推挽输出,映射到对应定时器通道。

void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(htim->Instance==TIM1)
  {
    __HAL_RCC_GPIOA_CLK_ENABLE();
    //PA11 --> TIM1_CH4
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  }
  else if(htim->Instance==TIM2)
  {
    __HAL_RCC_GPIOA_CLK_ENABLE();
    //PA15 --> TIM2_CH1
    GPIO_InitStruct.Pin = GPIO_PIN_15;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  }
}

四、实验现象

  1. NBV2.0主板插接智慧家居扩展板,两个舵机接到两路舵机端子,编译下载程序上电;
  2. 调用Servo_Open():两路舵机同步旋转至90°,模拟双道闸抬杆开启;
  3. 调用Servo_Close():两路舵机回到0°,模拟双道闸落杆关闭;
  4. 串口打印状态信息,LiteOS任务运行稳定无崩溃,TIM1、TIM2正常输出PWM波形。

对比测试:换到智慧交通扩展板,硬件仅引出一路端子,只能看到单个舵机动作。双舵机正常工作,软硬件两者缺一不可。

五、开发踩坑总结

  1. ❗定时器初始化完成不等于输出PWM,必须调用HAL_TIM_PWM_Start开启通道,否则引脚没有波形输出;
  2. PA11、PA15必须配置为定时器复用推挽输出,如果配置成普通GPIO,舵机完全不会动;
  3. 想要两个舵机同时动作:硬件需要智慧家居扩展板,软件需要同时设置两个定时器通道CCR值;
  4. 角度与PWM比较值的映射关系不能写错,数值不对舵机角度会发生偏移;
  5. LiteOS开发模式:main只做初始化,业务逻辑要写在任务函数中,LOS_Start()之后main死循环不会运行。

六、拓展优化思路

  1. 时序优化:给两个舵机分配不同PWM值,实现道闸先后开、先后关,复刻真实停车场场景;
  2. 传感联动:外接红外检测传感器,检测车辆自动开关道闸;
  3. 云端控制:通过WiFi连接物联网云平台,实现网页/小程序远程控制道闸;
  4. 硬件保护:增加舵机堵转检测逻辑,避免电机长时间卡死烧毁。

写在最后

这个实验完整演示了STM32定时器PWM、GPIO复用、鸿蒙LiteOS任务开发,硬件扩展板的差异很容易被忽略,很多同学代码改完舵机不转,问题就出在软硬件不匹配。如果你正在做鸿蒙物联网课程实验,希望本篇博客对你有帮助。


Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐