电机驱动模块TC1508:2路直流电机驱动模块 正反转 PWM调速。非常适合在电池供电的智能小车、玩具小车、机器人等上面使用,供电电压2V~10V,可同时驱动两个直流电机或者1个4线2相式步进电机,可实现正反转和调速的功能,每路电流能到1.5A持续电流,峰值电流可达2.5A,有热保护并且能够自动恢复。
本文采用PWM方式驱动该电机驱动模块。
一、连线
PB14 <--------> IN1
PB15 <--------> IN2
二、软件部分
1、PWM初始化
PWM:TIM1
通道:CH1、CH2
输出引脚:PB14、PB15
// 初始化PWM
void PWM_Init(void)
{
// 配置TIM1通道1和通道2为PWM输出
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
// 使能TIM1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
// 时基配置
TIM_TimeBaseStruct.TIM_Prescaler = 72 - 1; // 72MHz/72 = 1MHz
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStruct.TIM_Period = 1000 - 1; // 1MHz/1000 = 1kHz PWM频率
TIM_TimeBaseStruct.TIM_ClockDivision = 0;
TIM_TimeBaseStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);
// PWM模式配置
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStruct.TIM_Pulse = 0; // 初始占空比0%
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStruct.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
// 通道1和通道2配置
TIM_OC1Init(TIM1, &TIM_OCInitStruct);
TIM_OC2Init(TIM1, &TIM_OCInitStruct);
// 使能预装载
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_7); /* TIM1_CH1 */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_7); /* TIM1_CH2 */
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStruct);
// 使能TIM1
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
2、设置电机速度和方向
speed为正数,电机正转
speed为负数,电机反转
speed为0,停止运行
// 设置电机速度和方向
void Motor_Control(int16_t speed) // speed: -1000到+1000
{
if(speed > 0) {
// 正转
TIM_SetCompare1(TIM1, speed); // IN1 = PWM
TIM_SetCompare2(TIM1, 0); // IN2 = 0
} else if(speed < 0) {
// 反转
TIM_SetCompare1(TIM1, 0); // IN1 = 0
TIM_SetCompare2(TIM1, -speed); // IN2 = PWM
} else {
// 停止
TIM_SetCompare1(TIM1, 0); // IN1 = 0
TIM_SetCompare2(TIM1, 0); // IN2 = 0
}
}
3、刹车功能
设置PB14、PB15高电平
void Motor_Brake(void)
{
GPIO_WriteBit(GPIOB, GPIO_Pin_14, Bit_SET); // IN1 = 1
GPIO_WriteBit(GPIOB, GPIO_Pin_15, Bit_SET); // IN2 = 1
}
4、EXTI外部中断
用外部中断做为控制。EXTI0中断,设置标志为正转;EXTI12中断,设置标志为反转
uint8_t directory=1; //方向控制。1:正转;2:反转。
uint8_t enChange=0; //是否发生方向改变。
EXTI初始化
PA0下拉,PB12上拉
void EXTI_Configure(void)
{
EXTI_InitTypeDef EXTI_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_EXTI, ENABLE);
/* K1->PA0->EXTI_Line0 */
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOA, &GPIO_InitStruct);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
EXTI_StructInit(&EXTI_InitStruct);
EXTI_InitStruct.EXTI_Line = EXTI_Line0;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);
/* EXTI Interrupt */
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
/* K2->PB2->EXTI_Line12 */
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStruct);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource12);
EXTI_StructInit(&EXTI_InitStruct);
EXTI_InitStruct.EXTI_Line = EXTI_Line12;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);
/* EXTI Interrupt */
NVIC_InitStruct.NVIC_IRQChannel = EXTI4_15_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
中断处理
改变方向
void EXTI0_1_IRQHandler(void)
{
/* K1 */
if (RESET != EXTI_GetITStatus(EXTI_Line0))
{
PLATFORM_LED_Toggle(LED1);
directory=1;
enChange=1;
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
void EXTI4_15_IRQHandler(void)
{
/* K2 */
printf("EXTI4_15_IRQHandler\r\n");
if (RESET != EXTI_GetITStatus(EXTI_Line12))
{
PLATFORM_LED_Toggle(LED2);
directory=2;
enChange=1;
EXTI_ClearITPendingBit(EXTI_Line12);
}
}
5、示例
void motor_Sample(void)
{
// 初始化PWM
PWM_Init();
// 电机控制示例
while(1) {
if(enChange==1)
{
Motor_Brake();
PLATFORM_DelayMS(500);
enChange=0;
}
if(directory==1)
{
Motor_Control(500);
}
else if(directory==2)
{
Motor_Control(-500);
}
三、运行效果
|