打印
[MM32硬件]

【灵动微电子MM32F0121测评】12、外挂电机驱动模块驱动电机运行

[复制链接]
1448|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
电机驱动模块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);
}



三、运行效果



使用特权

评论回复
沙发
AdaMaYun| | 2025-7-31 17:46 | 只看该作者
外挂电机驱动模块驱动电机运行

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

84

主题

147

帖子

3

粉丝