这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » Let'sdo2025年第4期—电机控制

共1条 1/1 1 跳转至

Let'sdo2025年第4期—电机控制

工程师
2026-01-31 12:57:13     打赏

本文将基于FRDM-MCXA153实现直流电机控制,包括电机的启动、正反转和停止,以及使用串口完成电机转速的控制

根据TB6612的文档,可以看到如果希望控制一路直流电机,例如控制A路电机,可以通过向PWMA引脚输入PWM信号,利用调整占空比来控制电机转速,INA1和INA2可以控制电机的转动状态

image.png

INA和电机转动方式关系如下


INA1=0INA1=1
INA2=0电机滑行电机正转
INA2=1电机反转电机刹车

在MCUXpresso中定义引脚如下,LPUART用于串口收发,GPIO用于电机运行方式控制,FlexPWM用于电机转速控制image.png

其中FlexPWM0对应开发板上的P3_0,连接电机驱动板的PWMA,P2_4和P2_5分别连接电机驱动板的INA1和INA2

电源的正负极分别连接电机驱动板的VM和GND,开发板上的3.3V引脚连接电机驱动板的Vcc,同时保证开发板和电源共地

直流电机的正负引脚连接MOT.A的两个引脚

代码实现如下

对PWM进行初始化

static void PWM_DRV_InitPwm(void)
{
uint16_t deadTimeVal;
pwm_signal_param_t pwmSignal;
uint32_t pwmSourceClockInHz;
uint32_t pwmFrequencyInHz = APP_DEFAULT_PWM_FREQUENCY;

pwmSourceClockInHz = PWM_SRC_CLK_FREQ;

/* Set deadtime count, we set this to about 650ns */
deadTimeVal = ((uint64_t)pwmSourceClockInHz * 650) / 1000000000;

pwmSignal.pwmChannel       = kPWM_PwmA;
pwmSignal.level            = kPWM_HighTrue;
pwmSignal.dutyCyclePercent = 0; /* 1 percent dutycycle */
pwmSignal.deadtimeValue    = deadTimeVal;
pwmSignal.faultState       = kPWM_PwmFaultState0;
pwmSignal.pwmchannelenable = true;

PWM_SetupPwm(
   				FLEXPWM0,
   				kPWM_Module_0,
					&pwmSignal,
					1,
					kPWM_SignedCenterAligned,
					pwmFrequencyInHz,
                	pwmSourceClockInHz
				);
}

定义电机运行状态

// 电机滑行
static inline void motor_slid(void)
{
GPIO_PinWrite(AIN_GPIO, AIN1_PIN, 0);
GPIO_PinWrite(AIN_GPIO, AIN2_PIN, 0);
}
// 电机正转
static inline void motor_forward(void)
{
GPIO_PinWrite(AIN_GPIO, AIN1_PIN, 1);
GPIO_PinWrite(AIN_GPIO, AIN2_PIN, 0);
}
// 电机反转
static inline void motor_reverse(void)
{
GPIO_PinWrite(AIN_GPIO, AIN1_PIN, 0);
GPIO_PinWrite(AIN_GPIO, AIN2_PIN, 1);
}
// 电机刹车
static inline void motor_coast(void)
{
GPIO_PinWrite(AIN_GPIO, AIN1_PIN, 1);
GPIO_PinWrite(AIN_GPIO, AIN2_PIN, 1);
}

设置PWM更新函数

/* 占空比 0~100% 更新 */
static void motor_set_duty(uint8_t duty)
{
if (duty > 100U) {
duty = 100U;
}

PWM_UpdatePwmDutycycle(FLEXPWM0,
kPWM_Module_0,         /* 子模块0 */
kPWM_PwmA,             /* 通道A = PWM0_A0 */
kPWM_SignedCenterAligned,
duty);
PWM_SetPwmLdok(FLEXPWM0, kPWM_Control_Module_0, true);
}

在主函数中,完成外设初始化,并实现串口输入控制PWM以及电机反复正转加速-减速-反转加速-反转减速

int main(void) {
/* Init board hardware. */
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitBootPeripherals();
BOARD_InitDebugConsole();

pwm_config_t pwmConfig;
pwm_fault_param_t faultConfig;
uint32_t duty = 0;

motor_coast();

pwmConfig.enableDebugMode = false;
	pwmConfig.reloadSelect = kPWM_LocalReload;
	pwmConfig.clockSource = kPWM_BusClock;
	pwmConfig.prescale = kPWM_Prescale_Divide_1;
	pwmConfig.initializationControl = kPWM_Initialize_LocalSync;
	pwmConfig.forceTrigger = kPWM_Force_Local;
	pwmConfig.reloadFrequency = kPWM_LoadEveryOportunity;
	pwmConfig.reloadLogic = kPWM_ReloadImmediate;
	pwmConfig.pairOperation = kPWM_Independent;

PWM_GetDefaultConfig(&pwmConfig);
#ifdef DEMO_PWM_CLOCK_DEVIDER
pwmConfig.prescale = DEMO_PWM_CLOCK_DEVIDER;
#endif
pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle;
pwmConfig.pairOperation   = kPWM_ComplementaryPwmA;
pwmConfig.enableDebugMode = true;

if (PWM_Init(FLEXPWM0, kPWM_Module_0, &pwmConfig) == kStatus_Fail ||
PWM_Init(FLEXPWM0, kPWM_Module_1, &pwmConfig) == kStatus_Fail)
{
PRINTF("PWM initialization failed\n");
return 1;
}

pwmConfig.clockSource           = kPWM_Submodule0Clock;
pwmConfig.prescale              = kPWM_Prescale_Divide_1;
pwmConfig.initializationControl = kPWM_Initialize_MasterSync;

PWM_FaultDefaultConfig(&faultConfig);

#ifdef DEMO_PWM_FAULT_LEVEL
faultConfig.faultLevel = DEMO_PWM_FAULT_LEVEL;
#endif

/* Sets up the PWM fault protection */
PWM_SetupFaults(FLEXPWM0, kPWM_Fault_0, &faultConfig);
PWM_SetupFaults(FLEXPWM0, kPWM_Fault_1, &faultConfig);
PWM_SetupFaults(FLEXPWM0, kPWM_Fault_2, &faultConfig);
PWM_SetupFaults(FLEXPWM0, kPWM_Fault_3, &faultConfig);

/* Set PWM fault disable mapping for submodule 0/1/2 */
PWM_SetupFaultDisableMap(FLEXPWM0, kPWM_Module_0, kPWM_PwmA, kPWM_faultchannel_0,
kPWM_FaultDisable_0 | kPWM_FaultDisable_1 | kPWM_FaultDisable_2 | kPWM_FaultDisable_3);

PWM_DRV_InitPwm();

/* Set the load okay bit for all submodules to load registers from their buffer */
PWM_SetPwmLdok(FLEXPWM0, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2, true);
/* Start the PWM generation from Submodules 0, 1 and 2 */
PWM_StartTimer(FLEXPWM0, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2);

while(1) {
#if UART_CONTROL
   	motor_forward();
   	if (SCANF("%d", &duty) == 1) {
   		if (duty < 0) {
   			duty = 0;
   		}
   		if (duty > 100) {
   			duty = 100;
   		}
   		motor_set_duty(duty);
   		PRINTF("duty=%d\r\n", duty);
   	} else {
			int ch;
			while (1)
			{
				ch = GETCHAR();
				if (ch == '\r' || ch == '\n') break;
			}
   	}
#else
   	motor_forward();
   	for (duty = 0; duty < 100; duty++) {
   		motor_set_duty(duty);
   		SDK_DelayAtLeastUs((200000U / APP_DEFAULT_PWM_FREQUENCY) * 100, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
   	}

		SDK_DelayAtLeastUs((10000000U / APP_DEFAULT_PWM_FREQUENCY) * 100, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
		for (duty = 100; duty > 0; duty--) {
			motor_set_duty(duty);
			SDK_DelayAtLeastUs((200000U / APP_DEFAULT_PWM_FREQUENCY) * 100, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
		}
		SDK_DelayAtLeastUs((10000000U / APP_DEFAULT_PWM_FREQUENCY) * 100, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
		motor_coast();
		motor_reverse();
		for (duty = 0; duty < 100; duty++) {
			motor_set_duty(duty);
			SDK_DelayAtLeastUs((200000U / APP_DEFAULT_PWM_FREQUENCY) * 100, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
		}

		SDK_DelayAtLeastUs((10000000U / APP_DEFAULT_PWM_FREQUENCY) * 100, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
		for (duty = 100; duty > 0; duty--) {
			motor_set_duty(duty);
			SDK_DelayAtLeastUs((200000U / APP_DEFAULT_PWM_FREQUENCY) * 100, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
		}
		SDK_DelayAtLeastUs((10000000U / APP_DEFAULT_PWM_FREQUENCY) * 100, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
		motor_coast();
#endif
}
return 0 ;
}

具体实现效果和代码汇总详见成果帖




关键词: Let's do     电机控制     直流电机    

共1条 1/1 1 跳转至

回复

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