STM32外设系列—L298N

2024-03-19 4849阅读

🎀 章作者:二土电子

🌸 关注文末公众号获取其他资料和工程文件!

🐸 期待大家一起学习交流!



文章目录

  • 一、L298N简介
  • 二、L298N电路图
  • 三、L298N使用方法
  • 四、L298N驱动电机实例
    • 4.1 麦克纳姆轮简介
    • 4.2 定时器PWM配置
    • 4.3 智能车行驶控制
    • 五、拓展应用

      一、L298N简介

      L298N是SGS公司生产的一款通用的电机驱动模块。其内部包含4路逻辑驱动电路,有两个H桥的高电压大电流全桥驱动器,接收TTL逻辑电平信号,一个模块可同时驱动两个直流电机工作,具有反馈检测和过热自断功能。利用L298N驱动电机时,主控芯片只需通过I/O口输出控制电平即可实现对电机转向的控制,编程简单,稳定性好。

      STM32外设系列—L298N 第1张

      二、L298N电路图

      L298N的电路图如下

      STM32外设系列—L298N 第2张

      OUT1、OUT2、OUT3和OUT4之间分别接两个电机。IN1、IN2、IN3和IN4引脚接STM32单片机,用来接收单片机发送来的控制电平,控制电机的转动方向,ENA和ENB为使能端。

      三、L298N使用方法

      L298N通常用于电机驱动,控制电机的转向,转速。电机转向通过IN1,IN2,IN3和IN4的逻辑电平控制,转向通过给输入引脚输入的PWM占空比控制。L298N控制电机转动状态的逻辑功能表如下

      STM32外设系列—L298N 第3张

      正如上面所说,电机的调速可以通过单片机给输入引脚发送PWM信号来实现。电机的转速与电机两端PWM信号的占空比成正比,占空比越大,电机转速越快。

      四、L298N驱动电机实例

      一个L298N可以驱动两个电机,博主使用时L298N用12V航模电池供电,L298N输出的5V给单片机供电。这里以利用两个L298N,驱动四个电机,搭配麦克纳姆轮实现车的前进,后退,平移和自转为例,展示一下L298N的配置和使用流程。同时,也对麦克纳姆轮做一个简单介绍。

      4.1 麦克纳姆轮简介

      麦克纳姆轮与传统轮胎相比可以实现全向移动,能够在较为狭小的空间内任意行进,更加灵活。虽然麦克纳姆轮相比于传统轮胎也有许多缺点,比如麦克纳姆轮的能耗高,成本也高,而且还容易受到地形限制,但是对于机器人大赛以及一些工业生产用的智能车来说,麦克纳姆轮的全向移动优势就表现得十分突出,避障时麦克纳姆轮小车可直接平移,无需提前预留转弯角度,也无需其他传感器辅助,编写程序时更加简洁,所以最终我选择使用麦克纳姆轮来实现小车的全向移动。

      STM32外设系列—L298N 第4张

      麦克纳姆轮主要是由轮毂和辊子两部分组成,辊子轴线和轮毂轴线夹角为45°,有互为镜像的A/B轮两种,安装时所有轮子辊子的轴线方向都要指向小车的中心,这是因为麦轮的全向移动是通过力的合成和分解来实现的,如果A/B轮混用或者没有按照上述要求安装会导致小车没法正常行驶。

      4.2 定时器PWM配置

      使用TIM2和TIM3的四个PWM通道(共8路PWM)来控制车速,这里配置了固定的预分频系数和自动重装载值。对于定时器的内容,可见博主STM32速成笔记的定时器介绍部分。TIM2和TIM3初始化程序如下

      /*
       *==============================================================================
       *函数名称:TIM2_PWM_Init
       *函数功能:初始化定时器2的PWM
       *输入参数:无
       *返回值:无
       *备  注:预分频系数和自动重装载值固定
       *==============================================================================
       */
      void TIM2_PWM_Init (void)
      {
      	// 结构体定义
      	GPIO_InitTypeDef GPIO_InitStructure;
      	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
      	TIM_OCInitTypeDef TIM_OCInitStructure;
      	// 开启时钟
      	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO
                             	| RCC_APB1Periph_TIM2,ENABLE);
      	// 配置GPIO
      	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
      	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
      	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;   // 复用推挽输出
      	GPIO_Init(GPIOA,&GPIO_InitStructure);
      	
      	// 配置TIM2
      	TIM_TimeBaseInitStructure.TIM_Period = 899;
      	TIM_TimeBaseInitStructure.TIM_Prescaler = 0;
      	TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;
      	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
      	TIM_TimeBaseInit(TIM2, & TIM_TimeBaseInitStructure);
      	// 配置PWM通道1
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OCInitStructure.TIM_Pulse = 899;
        TIM_OC1Init(TIM2 , &TIM_OCInitStructure);
        TIM_OC1PreloadConfig(TIM2 , TIM_OCPreload_Enable);
        
        // 配置PWM通道2
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OCInitStructure.TIM_Pulse = 899;
        TIM_OC2Init(TIM2 , &TIM_OCInitStructure);
        TIM_OC2PreloadConfig(TIM2 , TIM_OCPreload_Enable);
        
        // 配置PWM通道3
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OCInitStructure.TIM_Pulse = 899;
        TIM_OC3Init(TIM2 , &TIM_OCInitStructure);
        TIM_OC3PreloadConfig(TIM2 , TIM_OCPreload_Enable);
        
        // 配置PWM通道4
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OCInitStructure.TIM_Pulse = 899;
        TIM_OC4Init(TIM2 , &TIM_OCInitStructure);
        TIM_OC4PreloadConfig(TIM2 , TIM_OCPreload_Enable);
        
      	// 使能TIM2
        TIM_Cmd(TIM2 , ENABLE);
      }
      /*
       *==============================================================================
       *函数名称:TIM3_PWM_Init
       *函数功能:初始化定时器3的PWM
       *输入参数:无
       *返回值:无
       *备  注:预分频系数和自动重装载值固定
       *==============================================================================
       */
      void TIM3_PWM_Init (void)
      {
      	// 结构体定义
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
        TIM_OCInitTypeDef TIM_OCInitStructure; 
      	
      	// 开启时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO
      	                       | RCC_APB1Periph_TIM3, ENABLE);
      	
      	// 配置GPIO
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   // 复用推挽式输出
        GPIO_Init(GPIOA, &GPIO_InitStructure);   
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	
        GPIO_Init(GPIOB, &GPIO_InitStructure);   
        
      	// 配置TIM3
        TIM_TimeBaseStructure.TIM_Period = 899;
        TIM_TimeBaseStructure.TIM_Prescaler = 0;
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseStructure.TIM_ClockDivision = 0;
        TIM_TimeBaseInit(TIM3 , &TIM_TimeBaseStructure);
        
        // 配置PWM通道1
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OCInitStructure.TIM_Pulse = 900;
        TIM_OC1Init(TIM3 , &TIM_OCInitStructure);
        TIM_OC1PreloadConfig(TIM3 , TIM_OCPreload_Enable);
        
        // 配置PWM通道2
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OCInitStructure.TIM_Pulse = 900;
        TIM_OC2Init(TIM3 , &TIM_OCInitStructure);
        TIM_OC2PreloadConfig(TIM3 , TIM_OCPreload_Enable);
        
        // 配置PWM通道3
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OCInitStructure.TIM_Pulse = 900;
        TIM_OC3Init(TIM3 , &TIM_OCInitStructure);
        TIM_OC3PreloadConfig(TIM3 , TIM_OCPreload_Enable);
        
        // 配置PWM通道3
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OCInitStructure.TIM_Pulse = 900;
        TIM_OC4Init(TIM3 , &TIM_OCInitStructure);
        TIM_OC4PreloadConfig(TIM3 , TIM_OCPreload_Enable);
        
      	// 使能TIM3
        TIM_Cmd(TIM3 , ENABLE);
      }
      

      4.3 智能车行驶控制

      这里简单阐述一下麦克纳姆轮的全向移动原理。

      STM32外设系列—L298N 第5张

      图中实线为车轮转动产生的摩擦力,虚线是分力,合成后可知左侧智能车向前移动,右侧智能车向右移动。其他的移动操作,如自转、平移等原理与之相同,就不再赘述。下面列一下不同行驶状态下,各个电机的旋转状态

      STM32外设系列—L298N 第6张

      下面是控制程序

      // 差值决定快慢,差值越大越快
      // 1、2差值代表左后轮和右前轮的速度;3、4差值代表左前轮和右后轮的速度
      // 1-2为正代表正转,为负代表反转,差值代表速度
      /*
       *==============================================================================
       *函数名称:Med_Motor_CarGo
       *函数功能:智能车前进
       *输入参数:无
       *返回值:无
       *备  注:无
       *==============================================================================
       */
      void Med_Motor_CarGo (void)
      {
      	TIM_SetCompare1(TIM2 , 899); 
        TIM_SetCompare2(TIM2 , 300);
        TIM_SetCompare3(TIM2 , 899);  
        TIM_SetCompare4(TIM2 , 300);
      	
        TIM_SetCompare1(TIM3 , 899); 
        TIM_SetCompare2(TIM3 , 300);
        TIM_SetCompare3(TIM3 , 899);  
        TIM_SetCompare4(TIM3 , 300);	
      }
      /*
       *==============================================================================
       *函数名称:Med_Motor_CarStop
       *函数功能:智能车停止
       *输入参数:无
       *返回值:无
       *备  注:无
       *==============================================================================
       */
      void Med_Motor_CarStop (void)
      {
      	TIM_SetCompare1(TIM2 , 0); 
        TIM_SetCompare2(TIM2 , 0);
        TIM_SetCompare3(TIM2 , 0);  
        TIM_SetCompare4(TIM2 , 0);
      	
        TIM_SetCompare1(TIM3 , 0);
        TIM_SetCompare2(TIM3 , 0);
        TIM_SetCompare3(TIM3 , 0);	
        TIM_SetCompare4(TIM3 , 0);
      }
      /*
       *==============================================================================
       *函数名称:Med_Motor_CarBack
       *函数功能:智能车后退
       *输入参数:无
       *返回值:无
       *备  注:无
       *==============================================================================
       */
      void Med_Motor_CarBack (void)
      {
      	TIM_SetCompare1(TIM2 , 300);
        TIM_SetCompare2(TIM2 , 899);
        TIM_SetCompare3(TIM2 , 300);	
        TIM_SetCompare4(TIM2 , 899);
      	
        TIM_SetCompare1(TIM3 , 300);
        TIM_SetCompare2(TIM3 , 899);
        TIM_SetCompare3(TIM3 , 300);	
        TIM_SetCompare4(TIM3 , 899);
      }
      /*
       *==============================================================================
       *函数名称:Med_Motor_CarLe
       *函数功能:智能车向左平移
       *输入参数:无
       *返回值:无
       *备  注:无
       *==============================================================================
       */
      void Med_Motor_CarLeft (void)
      {
      	TIM_SetCompare1(TIM2 , 899);
        TIM_SetCompare2(TIM2 , 300);
        TIM_SetCompare3(TIM2 , 899);	
        TIM_SetCompare4(TIM2 , 300);
      	
        TIM_SetCompare1(TIM3 , 300);
        TIM_SetCompare2(TIM3 , 899);
        TIM_SetCompare3(TIM3 , 300);
        TIM_SetCompare4(TIM3 , 899);
      }
      /*
       *==============================================================================
       *函数名称:Med_Motor_CarRight
       *函数功能:智能车向右平移
       *输入参数:无
       *返回值:无
       *备  注:无
       *==============================================================================
       */
      void Med_Motor_CarRight (void)
      {
      	TIM_SetCompare1(TIM2 , 300);
        TIM_SetCompare2(TIM2 , 899);
        TIM_SetCompare3(TIM2 , 300);	
        TIM_SetCompare4(TIM2 , 899);
      	
        TIM_SetCompare1(TIM3 , 899);
        TIM_SetCompare2(TIM3 , 300);
        TIM_SetCompare3(TIM3 , 899);
        TIM_SetCompare4(TIM3 , 300);
      }
      /*
       *==============================================================================
       *函数名称:Med_Motor_ClockwiseRotate
       *函数功能:智能车顺时针自转
       *输入参数:无
       *返回值:无
       *备  注:无
       *==============================================================================
       */
      void Med_Motor_ClockwiseRotate (void)
      {
      	TIM_SetCompare1(TIM2 , 300);
        TIM_SetCompare2(TIM2 , 899);
        TIM_SetCompare3(TIM2 , 899);	
        TIM_SetCompare4(TIM2 , 300);
      	
        TIM_SetCompare1(TIM3 , 300);
        TIM_SetCompare2(TIM3 , 899);
        TIM_SetCompare3(TIM3 , 899);
        TIM_SetCompare4(TIM3 , 300);
      }
      /*
       *==============================================================================
       *函数名称:Med_Motor_CounterClockwiseRotate
       *函数功能:智能车逆时针自转
       *输入参数:无
       *返回值:无
       *备  注:无
       *==============================================================================
       */
      void Med_Motor_CounterClockwiseRotate (void)
      {
      	TIM_SetCompare1(TIM2 , 899);
        TIM_SetCompare2(TIM2 , 300);
        TIM_SetCompare3(TIM2 , 300);	
        TIM_SetCompare4(TIM2 , 899);
      	
        TIM_SetCompare1(TIM3 , 899);
        TIM_SetCompare2(TIM3 , 300);
        TIM_SetCompare3(TIM3 , 300);
        TIM_SetCompare4(TIM3 , 899);
      }
      

      五、拓展应用

      知道了L298N的控制和调速方法,我们就能做许多事情。比如利用蓝牙来调整智能车行驶速度。实际原理就是通过蓝牙给配置占空比的函数传入数值,改变占空比,从而达到遥控调节车速的目的。这个在后续的实战项目系列中会有相关介绍。


    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]