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

[复制链接]
 楼主| sujingliang 发表于 2025-6-26 10:55 | 显示全部楼层 |阅读模式
电机驱动模块TC1508:2路直流电机驱动模块 正反转 PWM调速。非常适合在电池供电的智能小车、玩具小车、机器人等上面使用,供电电压2V~10V,可同时驱动两个直流电机或者1个4线2相式步进电机,可实现正反转和调速的功能,每路电流能到1.5A持续电流,峰值电流可达2.5A,有热保护并且能够自动恢复。

功能图.jpg

逻辑真值表.jpg

本文采用PWM方式驱动该电机驱动模块。
一、连线

14.png

PB14  <-------->  IN1
PB15  <-------->  IN2


二、软件部分

1、PWM初始化

PWM:TIM1
通道:CH1、CH2
输出引脚:PB14、PB15
  1. // 初始化PWM
  2. void PWM_Init(void)
  3. {
  4.    
  5.    
  6.     // 配置TIM1通道1和通道2为PWM输出
  7.     TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
  8.     TIM_OCInitTypeDef TIM_OCInitStruct;
  9.                 GPIO_InitTypeDef        GPIO_InitStruct;
  10.    
  11.        
  12.          // 使能TIM1时钟
  13.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  14.        
  15.     // 时基配置
  16.     TIM_TimeBaseStruct.TIM_Prescaler = 72 - 1;  // 72MHz/72 = 1MHz
  17.     TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
  18.     TIM_TimeBaseStruct.TIM_Period = 1000 - 1;   // 1MHz/1000 = 1kHz PWM频率
  19.     TIM_TimeBaseStruct.TIM_ClockDivision = 0;
  20.     TIM_TimeBaseStruct.TIM_RepetitionCounter = 0;
  21.     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);
  22.    
  23.     // PWM模式配置
  24.     TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
  25.     TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
  26.     TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Disable;
  27.     TIM_OCInitStruct.TIM_Pulse = 0;  // 初始占空比0%
  28.     TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
  29.     TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCNPolarity_High;
  30.     TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;
  31.     TIM_OCInitStruct.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
  32.    
  33.     // 通道1和通道2配置
  34.     TIM_OC1Init(TIM1, &TIM_OCInitStruct);
  35.     TIM_OC2Init(TIM1, &TIM_OCInitStruct);
  36.    
  37.     // 使能预装载
  38.     TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
  39.     TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
  40.                
  41.                
  42.                
  43.                 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
  44.                
  45.                 GPIO_PinAFConfig(GPIOB, GPIO_PinSource14,  GPIO_AF_7);   /* TIM1_CH1 */
  46.     GPIO_PinAFConfig(GPIOB, GPIO_PinSource15,  GPIO_AF_7);   /* TIM1_CH2 */
  47.                
  48.                 GPIO_StructInit(&GPIO_InitStruct);
  49.     GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_14 | GPIO_Pin_15;
  50.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
  51.     GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF_PP;
  52.     GPIO_Init(GPIOB, &GPIO_InitStruct);

  53.    
  54.     // 使能TIM1
  55.     TIM_Cmd(TIM1, ENABLE);
  56.     TIM_CtrlPWMOutputs(TIM1, ENABLE);
  57. }


2、设置电机速度和方向

speed为正数,电机正转
speed为负数,电机反转
speed为0,停止运行

  1. // 设置电机速度和方向
  2. void Motor_Control(int16_t speed)  // speed: -1000到+1000
  3. {
  4.     if(speed > 0) {
  5.         // 正转
  6.         TIM_SetCompare1(TIM1, speed);  // IN1 = PWM
  7.         TIM_SetCompare2(TIM1, 0);      // IN2 = 0
  8.     } else if(speed < 0) {
  9.         // 反转
  10.         TIM_SetCompare1(TIM1, 0);      // IN1 = 0
  11.         TIM_SetCompare2(TIM1, -speed); // IN2 = PWM
  12.     } else {
  13.         // 停止
  14.         TIM_SetCompare1(TIM1, 0);      // IN1 = 0
  15.         TIM_SetCompare2(TIM1, 0);      // IN2 = 0
  16.     }
  17. }


3、刹车功能

设置PB14、PB15高电平
  1. void Motor_Brake(void)
  2. {
  3.     GPIO_WriteBit(GPIOB, GPIO_Pin_14, Bit_SET);  // IN1 = 1
  4.     GPIO_WriteBit(GPIOB, GPIO_Pin_15, Bit_SET);  // IN2 = 1
  5. }


4、EXTI外部中断

用外部中断做为控制。EXTI0中断,设置标志为正转;EXTI12中断,设置标志为反转

uint8_t directory=1;    //方向控制。1:正转;2:反转。
uint8_t enChange=0;  //是否发生方向改变。



EXTI初始化
PA0下拉,PB12上拉
  1. void EXTI_Configure(void)
  2. {
  3.     EXTI_InitTypeDef EXTI_InitStruct;
  4.     GPIO_InitTypeDef GPIO_InitStruct;
  5.     NVIC_InitTypeDef NVIC_InitStruct;

  6.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  7.                 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
  8.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  9.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_EXTI, ENABLE);
  10.                

  11.     /* K1->PA0->EXTI_Line0 */
  12.     GPIO_StructInit(&GPIO_InitStruct);
  13.     GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_0;
  14.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
  15.     GPIO_Init(GPIOA, &GPIO_InitStruct);

  16.     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

  17.     EXTI_StructInit(&EXTI_InitStruct);
  18.     EXTI_InitStruct.EXTI_Line    = EXTI_Line0;
  19.     EXTI_InitStruct.EXTI_Mode    = EXTI_Mode_Interrupt;
  20.     EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
  21.     EXTI_InitStruct.EXTI_LineCmd = ENABLE;
  22.     EXTI_Init(&EXTI_InitStruct);
  23.    
  24.     /* EXTI Interrupt */
  25.     NVIC_InitStruct.NVIC_IRQChannel = EXTI0_1_IRQn;
  26.     NVIC_InitStruct.NVIC_IRQChannelPriority = 0x00;
  27.     NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  28.     NVIC_Init(&NVIC_InitStruct);
  29.                
  30.                
  31.                  /* K2->PB2->EXTI_Line12 */
  32.     GPIO_StructInit(&GPIO_InitStruct);
  33.     GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_12;
  34.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
  35.     GPIO_Init(GPIOB, &GPIO_InitStruct);

  36.     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource12);

  37.     EXTI_StructInit(&EXTI_InitStruct);
  38.     EXTI_InitStruct.EXTI_Line    = EXTI_Line12;
  39.     EXTI_InitStruct.EXTI_Mode    = EXTI_Mode_Interrupt;
  40.     EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
  41.     EXTI_InitStruct.EXTI_LineCmd = ENABLE;
  42.     EXTI_Init(&EXTI_InitStruct);
  43.    
  44.     /* EXTI Interrupt */
  45.     NVIC_InitStruct.NVIC_IRQChannel = EXTI4_15_IRQn;
  46.     NVIC_InitStruct.NVIC_IRQChannelPriority = 0x00;
  47.     NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  48.     NVIC_Init(&NVIC_InitStruct);
  49. }
中断处理
改变方向
  1. void EXTI0_1_IRQHandler(void)
  2. {
  3.     /* K1 */
  4.     if (RESET != EXTI_GetITStatus(EXTI_Line0))
  5.     {
  6.         PLATFORM_LED_Toggle(LED1);
  7.                                 directory=1;
  8.                                 enChange=1;
  9.         EXTI_ClearITPendingBit(EXTI_Line0);
  10.     }
  11. }

  12. void EXTI4_15_IRQHandler(void)
  13. {
  14.     /* K2 */
  15.                 printf("EXTI4_15_IRQHandler\r\n");
  16.     if (RESET != EXTI_GetITStatus(EXTI_Line12))
  17.     {
  18.         PLATFORM_LED_Toggle(LED2);
  19.                                 directory=2;
  20.                                 enChange=1;
  21.         EXTI_ClearITPendingBit(EXTI_Line12);
  22.     }
  23. }


5、示例

  1. void motor_Sample(void)
  2. {
  3.    
  4.     // 初始化PWM
  5.     PWM_Init();
  6.    
  7.     // 电机控制示例
  8.     while(1) {
  9.                        
  10.                         if(enChange==1)
  11.                         {
  12.                                 Motor_Brake();
  13.         PLATFORM_DelayMS(500);
  14.                                 enChange=0;
  15.                         }
  16.                         if(directory==1)
  17.                         {
  18.                                 Motor_Control(500);
  19.                         }
  20.                         else if(directory==2)
  21.                         {
  22.                                 Motor_Control(-500);
  23. }



三、运行效果
tutieshi_640x360_9s.gif


AdaMaYun 发表于 2025-7-31 17:46 | 显示全部楼层
外挂电机驱动模块驱动电机运行
您需要登录后才可以回帖 登录 | 注册

本版积分规则

84

主题

146

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部

84

主题

146

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部