完成了对电机的控制,下面来简单介绍一下
1.连线
| TB6612 | MCXA153 |
| PWMA | P3_6 |
| AIN1 | P3_13 |
| AIN2 | P3_12 |
| GND | GND |
| VCC | 3.3V |
| 电机 | |
| MOT.A | 电机两端 |
| TXN50-112 | |
| VM | V+ |
| GND | V- |
2.功能
实现了电机的正反转,停止。
通过led颜色反馈当前电机状态。
通过串口发送给单片机,实现控制电机。
3.代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <board.h>
#include <peripherals.h>
#include <pin_mux.h>
#include <clock_config.h>
#include <MCXA153.h>
#include <fsl_debug_console.h>
#include "fsl_lpuart.h"
#include <MCXA153_COMMON.h>
#include "app.h"
#include "fsl_pwm.h"
/*******************************************************************************
* 定义部分
******************************************************************************/
#define CTIMER CTIMER1
#define CTIMER_MAT_OUT kCTIMER_Match_2
#define CTIMER_CLK_FREQ CLOCK_GetCTimerClkFreq(1U)
#define CMD_BUFFER_SIZE 64
#define MAX_PARAMS 4
#define MAX_TASKS 2
/* 命令解析结构体(保留定义但不再使用) */
typedef struct
{
char cmd[32];
char params[MAX_PARAMS][16];
int paramCount;
} parsed_cmd_t;
#define APP_DEFAULT_PWM_FREQUENCY (1000UL)
/*******************************************************************************
* 函数原型声明
******************************************************************************/
void Debug_SysTick_Configuration(void);
void task1(void);
void task2(uint8_t direction, int speed);
/*******************************************************************************
* 变量定义
******************************************************************************/
volatile uint32_t g_Milliseconds = 0U;
volatile uint32_t g_pwmPeriod = 0U;
volatile uint32_t g_pulsePeriod = 0U;
volatile bool g_MotorRunningState = false;
/*******************************************************************************
* 代码实现
******************************************************************************/
static void PWM_DRV_InitSinglePwm(void)
{
pwm_signal_param_t pwmSignal;
uint32_t pwmSourceClockInHz;
uint32_t pwmFrequencyInHz = APP_DEFAULT_PWM_FREQUENCY;
pwmSourceClockInHz = PWM_SRC_CLK_FREQ;
pwmSignal.pwmChannel = kPWM_PwmA;
pwmSignal.level = kPWM_HighTrue;
pwmSignal.dutyCyclePercent = 0;
pwmSignal.deadtimeValue = 0;
pwmSignal.faultState = kPWM_PwmFaultState0;
pwmSignal.pwmchannelenable = true;
PWM_SetupPwm(BOARD_PWM_BASEADDR, kPWM_Module_0, &pwmSignal, 1,
kPWM_SignedCenterAligned, pwmFrequencyInHz, pwmSourceClockInHz);
}
/**
* @brief SysTick中断处理函数
*/
void SysTick_Handler(void)
{
g_Milliseconds++;
}
void task1(void)
{
PRINTF("\nTesting Motor Control...\r\n");
task2(0, 0);
SDK_DelayAtLeastUs(1 * 1000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
task2(1, 30);
SDK_DelayAtLeastUs(2 * 1000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
task2(1, 60);
SDK_DelayAtLeastUs(2 * 1000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
task2(0, 0);
SDK_DelayAtLeastUs(1 * 1000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
task2(2, 30);
SDK_DelayAtLeastUs(2 * 1000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
task2(2, 60);
SDK_DelayAtLeastUs(2 * 1000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
PRINTF("\nMotor Stop...\r\n");
task2(0, 0);
}
void task2(uint8_t direction, int speed)
{
if (direction == 1)
{
GPIO_PinWrite(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PIN, 1);
GPIO_PinWrite(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PIN, 0);
}
else if (direction == 2)
{
GPIO_PinWrite(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PIN, 0);
GPIO_PinWrite(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PIN, 1);
}
else
{
GPIO_PinWrite(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PIN, 1);
GPIO_PinWrite(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PIN, 1);
}
if (speed >= 0 && speed <= 100)
{
PWM_UpdatePwmDutycycle(BOARD_PWM_BASEADDR, kPWM_Module_0, kPWM_PwmA,
kPWM_SignedCenterAligned, speed);
}
else
{
PWM_UpdatePwmDutycycle(BOARD_PWM_BASEADDR, kPWM_Module_0, kPWM_PwmA,
kPWM_SignedCenterAligned, 0);
}
PWM_SetPwmLdok(BOARD_PWM_BASEADDR, kPWM_Control_Module_0, true);
}
int main(void)
{
gpio_pin_config_t p_config = {kGPIO_DigitalOutput, 1U};
pwm_config_t pwmConfig;
pwm_fault_param_t faultConfig;
char cmdBuffer[CMD_BUFFER_SIZE] = {0};
int cmdIndex = 0;
uint8_t receivedChar;
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitBootPeripherals();
#ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL
BOARD_InitDebugConsole();
#endif
// 初始化SysTick定时器 (1ms)
if (SysTick_Config(SystemCoreClock / 1000))
{
PRINTF("SysTick配置失败!\r\n");
while (1)
;
}
// 初始化LED引脚
GPIO_PinInit(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PIN, &p_config);
GPIO_PinInit(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PIN, &p_config);
// 初始化PWM
PWM_GetDefaultConfig(&pwmConfig);
pwmConfig.prescale = DEMO_PWM_CLOCK_DEVIDER;
pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle;
pwmConfig.pairOperation = kPWM_Independent;
pwmConfig.enableDebugMode = true;
if (PWM_Init(BOARD_PWM_BASEADDR, kPWM_Module_0, &pwmConfig) == kStatus_Fail)
{
PRINTF("PWM initialization failed\n");
return 1;
}
PWM_FaultDefaultConfig(&faultConfig);
faultConfig.faultLevel = DEMO_PWM_FAULT_LEVEL;
PWM_SetupFaults(BOARD_PWM_BASEADDR, kPWM_Fault_0, &faultConfig);
PWM_SetupFaults(BOARD_PWM_BASEADDR, kPWM_Fault_1, &faultConfig);
PWM_SetupFaults(BOARD_PWM_BASEADDR, kPWM_Fault_2, &faultConfig);
PWM_SetupFaults(BOARD_PWM_BASEADDR, kPWM_Fault_3, &faultConfig);
PWM_DRV_InitSinglePwm();
PWM_SetPwmLdok(BOARD_PWM_BASEADDR, kPWM_Control_Module_0, true);
PWM_StartTimer(BOARD_PWM_BASEADDR, kPWM_Control_Module_0);
task1();
PRINTF("\r\n=== Motor Control Ready ===\r\n");
PRINTF("Enter speed (-100 to 100) or 'stop':\r\n");
PRINTF("Speed: ");
while (1)
{
if (LPUART_GetStatusFlags((LPUART_Type *)BOARD_DEBUG_UART_BASEADDR) & kLPUART_RxDataRegFullFlag)
{
receivedChar = LPUART_ReadByte((LPUART_Type *)BOARD_DEBUG_UART_BASEADDR);
LPUART_WriteByte((LPUART_Type *)BOARD_DEBUG_UART_BASEADDR, receivedChar);
if (receivedChar == '\r' || receivedChar == '\n')
{
// 处理命令:支持 -100~100 数值 或 "stop"
if (cmdBuffer[0] != '\0')
{
// 转换为小写判断stop
char temp[CMD_BUFFER_SIZE];
strncpy(temp, cmdBuffer, CMD_BUFFER_SIZE - 1);
temp[CMD_BUFFER_SIZE - 1] = '\0';
for (int i = 0; temp[i]; i++)
{
if (temp[i] >= 'A' && temp[i] <= 'Z')
temp[i] = temp[i] - 'A' + 'a';
}
if (strcmp(temp, "stop") == 0)
{
task2(0, 0);
PRINTF("Motor stopped.\r\n");
}
else
{
char *endptr;
long val = strtol(cmdBuffer, &endptr, 10);
// 跳过尾部空格
while (*endptr == ' ') endptr++;
if (*endptr != '\0' || val < -100 || val > 100)
{
PRINTF("Invalid input. Use -100~100 or 'stop'.\r\n");
}
else
{
if (val > 0)
{
task2(1, (int)val);
PRINTF("Forward %ld%%\r\n", val);
}
else if (val < 0)
{
task2(2, (int)(-val));
PRINTF("Backward %ld%%\r\n", -val);
}
else
{
task2(0, 0);
PRINTF("Motor stopped.\r\n");
}
}
}
}
// 清空缓冲区并显示新提示符
memset(cmdBuffer, 0, CMD_BUFFER_SIZE);
cmdIndex = 0;
PRINTF("Speed: ");
}
else if (receivedChar == '\b' || receivedChar == 127)
{
// 退格处理(同步更新显示)
if (cmdIndex > 0)
{
cmdIndex--;
cmdBuffer[cmdIndex] = '\0';
// 重绘当前行:回车 + 提示符 + 当前内容
PRINTF("\rSpeed: %s", cmdBuffer);
// 擦除残留字符
int len = strlen(cmdBuffer);
for (int i = len; i < CMD_BUFFER_SIZE - 1; i++)
{
PRINTF(" ");
}
PRINTF("\rSpeed: %s", cmdBuffer);
}
}
else
{
if (cmdIndex < CMD_BUFFER_SIZE - 1)
{
cmdBuffer[cmdIndex++] = (char)receivedChar;
}
}
}
}
return 0;
}该代码主要参考了下面这位大佬的帖子
【2025Let'sdo第4期】基于单片机的直流电机控制-开箱和过程帖-电子产品世界论坛

视频