这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » Let'sdo2025年第4期-基于单片机的直流电机控制【成果帖】

共1条 1/1 1 跳转至

Let'sdo2025年第4期-基于单片机的直流电机控制【成果帖】

菜鸟
2026-02-02 14:02:57     打赏

    通过对例程的学习,我对MCXA153单片机有了初步的了解。在进行配置时,我选择使用PWM0_A0通道,即P3_6引脚输出PWM,P3_12和P3_13引脚进行电机的正反转控制,P3_12对应TB6612驱动上的AIN2引脚,P3_13对应TB6612驱动上的AIN1引脚。

image.png

    由于我使用的霍尔减速电机最大只有5V,所以我直接使用了单片机的5V引脚作为电压输入口,霍尔减速电机上只需要接电机的正负引脚口即可。

    我完成的是基础任务的一二

/**
 * @brief 控制电机方向和速度
 * @param direction 方向 (枚举类型)
 * @param speed_percent 速度百分比 (0-100)
 */
void Motor_SetState(motor_dir_t direction, uint8_t speed_percent)
{
/* 安全限幅:确保速度不超过100% */
if (speed_percent > 100)
{
speed_percent = 100;
}

/* 设置GPIO控制电机方向 */
switch (direction)
{
case kMotor_Forward:
/* 正转逻辑 */
GPIO_PinWrite(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PIN, 1);
GPIO_PinWrite(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PIN, 0);
break;

case kMotor_Reverse:
/* 反转逻辑 */
GPIO_PinWrite(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PIN, 0);
GPIO_PinWrite(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PIN, 1);
break;

case kMotor_Stop:
default:
/* 停止逻辑 */
GPIO_PinWrite(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PIN, 1);
GPIO_PinWrite(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PIN, 1);
speed_percent = 0; /* 停止时强制PWM为0 */
break;
}

/* 更新PWM占空比 */
PWM_UpdatePwmDutycycle(BOARD_PWM_BASEADDR, kPWM_Module_0, kPWM_PwmA,
kPWM_SignedCenterAligned, speed_percent);

/* 设置加载位,使配置生效 */
PWM_SetPwmLdok(BOARD_PWM_BASEADDR, kPWM_Control_Module_0, true);
}

    在编写完电机速度控制之后,再写了一个demo函数,用于演示一遍电机的控制。

/**
 * @brief 演示任务:电机自动运行序列
 */
void Demo_RunSequence(void)
{
PRINTF("\r\n=== Motor Control Demo Start ===\r\n");

/* 初始状态:停止 */
Motor_SetState(kMotor_Stop, 0);
SDK_DelayAtLeastUs(1000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); /* 1s */

/* === 正转测试 === */
PRINTF("Direction: Forward, Speed: 20%%\r\n");
Motor_SetState(kMotor_Forward, 20);
SDK_DelayAtLeastUs(5000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); /* 5s */

PRINTF("Direction: Forward, Speed: 50%%\r\n");
Motor_SetState(kMotor_Forward, 50);
SDK_DelayAtLeastUs(5000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

PRINTF("Direction: Forward, Speed: 80%%\r\n");
Motor_SetState(kMotor_Forward, 80);
SDK_DelayAtLeastUs(5000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

/* === 停止缓冲 === */
PRINTF("Motor Stop...\r\n");
Motor_SetState(kMotor_Stop, 0);
SDK_DelayAtLeastUs(1000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

/* === 反转测试 === */
PRINTF("Direction: Reverse, Speed: 20%%\r\n");
Motor_SetState(kMotor_Reverse, 20);
SDK_DelayAtLeastUs(5000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

PRINTF("Direction: Reverse, Speed: 50%%\r\n");
Motor_SetState(kMotor_Reverse, 50);
SDK_DelayAtLeastUs(5000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

PRINTF("Direction: Reverse, Speed: 80%%\r\n");
Motor_SetState(kMotor_Reverse, 80);
SDK_DelayAtLeastUs(5000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

/* === 结束 === */
PRINTF("=== Demo End (Motor Stop) ===\r\n");
Motor_SetState(kMotor_Stop, 0);
}

    其中包括电机的启动,调速,停止以及方向变换,电机在启动后首先正转20%占空比,然后是50%,最后是80%,然后控制电机停止转动,接下来是反转,依旧是同样的逻辑。demo函数只放在了主循环之前,所以只会在上电之后演示一遍,然后就会停止,不需要反复控制电机。以下是演示视频。

演示视频


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]