你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32外设的L298N经验分享

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

微信图片_20231023235238.jpg

L298N


二、L298N电路图
L298N的电路图如下

微信图片_20231023235234.png

L298N电路图



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

三、L298N使用方法

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

微信图片_20231023235230.png

L298N控制电机转动状态逻辑功能表



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

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

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

微信图片_20231023235226.png

麦克纳姆轮



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

4.2 定时器PWM配置
使用TIM2和TIM3的四个PWM通道(共8路PWM)来控制车速,这里配置了固定的预分频系数和自动重装载值。对于定时器的内容,可见博主STM32速成笔记的定时器介绍部分。TIM2和TIM3初始化程序如下
  1. /*
  2. *==============================================================================
  3. *函数名称:TIM2_PWM_Init
  4. *函数功能:初始化定时器2的PWM
  5. *输入参数:无
  6. *返回值:无
  7. *备  注:预分频系数和自动重装载值固定
  8. *==============================================================================
  9. */
  10. void TIM2_PWM_Init (void)
  11. {
  12.     // 结构体定义
  13.     GPIO_InitTypeDef GPIO_InitStructure;
  14.     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  15.     TIM_OCInitTypeDef TIM_OCInitStructure;

  16.     // 开启时钟
  17.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO
  18.                            | RCC_APB1Periph_TIM2,ENABLE);

  19.     // 配置GPIO
  20.     GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
  21.     GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  22.     GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;   // 复用推挽输出
  23.     GPIO_Init(GPIOA,&GPIO_InitStructure);
  24.    
  25.     // 配置TIM2
  26.     TIM_TimeBaseInitStructure.TIM_Period = 899;
  27.     TIM_TimeBaseInitStructure.TIM_Prescaler = 0;
  28.     TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;
  29.     TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
  30.     TIM_TimeBaseInit(TIM2, & TIM_TimeBaseInitStructure);


  31.     // 配置PWM通道1
  32.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  33.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  34.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  35.   TIM_OCInitStructure.TIM_Pulse = 899;
  36.   TIM_OC1Init(TIM2 , &TIM_OCInitStructure);
  37.   TIM_OC1PreloadConfig(TIM2 , TIM_OCPreload_Enable);
  38.   
  39.   // 配置PWM通道2
  40.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  41.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  42.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  43.   TIM_OCInitStructure.TIM_Pulse = 899;
  44.   TIM_OC2Init(TIM2 , &TIM_OCInitStructure);
  45.   TIM_OC2PreloadConfig(TIM2 , TIM_OCPreload_Enable);
  46.   
  47.   // 配置PWM通道3
  48.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  49.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  50.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  51.   TIM_OCInitStructure.TIM_Pulse = 899;
  52.   TIM_OC3Init(TIM2 , &TIM_OCInitStructure);
  53.   TIM_OC3PreloadConfig(TIM2 , TIM_OCPreload_Enable);
  54.   
  55.   // 配置PWM通道4
  56.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  57.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  58.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  59.   TIM_OCInitStructure.TIM_Pulse = 899;
  60.   TIM_OC4Init(TIM2 , &TIM_OCInitStructure);
  61.   TIM_OC4PreloadConfig(TIM2 , TIM_OCPreload_Enable);
  62.   
  63.     // 使能TIM2
  64.   TIM_Cmd(TIM2 , ENABLE);
  65. }
  66. /*
  67. *==============================================================================
  68. *函数名称:TIM3_PWM_Init
  69. *函数功能:初始化定时器3的PWM
  70. *输入参数:无
  71. *返回值:无
  72. *备  注:预分频系数和自动重装载值固定
  73. *==============================================================================
  74. */
  75. void TIM3_PWM_Init (void)
  76. {
  77.     // 结构体定义
  78.   GPIO_InitTypeDef GPIO_InitStructure;
  79.   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  80.   TIM_OCInitTypeDef TIM_OCInitStructure;
  81.    
  82.     // 开启时钟
  83.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO
  84.                            | RCC_APB1Periph_TIM3, ENABLE);
  85.    
  86.     // 配置GPIO
  87.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  88.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  89.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   // 复用推挽式输出
  90.   GPIO_Init(GPIOA, &GPIO_InitStructure);   
  91.   
  92.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
  93.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  94.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  95.   GPIO_Init(GPIOB, &GPIO_InitStructure);   
  96.   
  97.     // 配置TIM3
  98.   TIM_TimeBaseStructure.TIM_Period = 899;
  99.   TIM_TimeBaseStructure.TIM_Prescaler = 0;
  100.   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  101.   TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  102.   TIM_TimeBaseInit(TIM3 , &TIM_TimeBaseStructure);
  103.   
  104.   // 配置PWM通道1
  105.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  106.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  107.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  108.   TIM_OCInitStructure.TIM_Pulse = 900;
  109.   TIM_OC1Init(TIM3 , &TIM_OCInitStructure);
  110.   TIM_OC1PreloadConfig(TIM3 , TIM_OCPreload_Enable);
  111.   
  112.   // 配置PWM通道2
  113.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  114.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  115.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  116.   TIM_OCInitStructure.TIM_Pulse = 900;
  117.   TIM_OC2Init(TIM3 , &TIM_OCInitStructure);
  118.   TIM_OC2PreloadConfig(TIM3 , TIM_OCPreload_Enable);
  119.   
  120.   // 配置PWM通道3
  121.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  122.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  123.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  124.   TIM_OCInitStructure.TIM_Pulse = 900;
  125.   TIM_OC3Init(TIM3 , &TIM_OCInitStructure);
  126.   TIM_OC3PreloadConfig(TIM3 , TIM_OCPreload_Enable);
  127.   
  128.   // 配置PWM通道3
  129.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  130.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  131.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  132.   TIM_OCInitStructure.TIM_Pulse = 900;
  133.   TIM_OC4Init(TIM3 , &TIM_OCInitStructure);
  134.   TIM_OC4PreloadConfig(TIM3 , TIM_OCPreload_Enable);
  135.   
  136.     // 使能TIM3
  137.   TIM_Cmd(TIM3 , ENABLE);
  138. }
复制代码

4.3 智能车行驶控制
这里简单阐述一下麦克纳姆轮的全向移动原理。

微信图片_20231023235222.png

麦克纳姆轮受力分析



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

微信图片_20231023235218.png

运动状态与电机转向对应表




下面是控制程序
  1. // 差值决定快慢,差值越大越快
  2. // 1、2差值代表左后轮和右前轮的速度;3、4差值代表左前轮和右后轮的速度
  3. // 1-2为正代表正转,为负代表反转,差值代表速度
  4. /*
  5. *==============================================================================
  6. *函数名称:Med_Motor_CarGo
  7. *函数功能:智能车前进
  8. *输入参数:无
  9. *返回值:无
  10. *备  注:无
  11. *==============================================================================
  12. */
  13. void Med_Motor_CarGo (void)
  14. {
  15.     TIM_SetCompare1(TIM2 , 899);
  16.   TIM_SetCompare2(TIM2 , 300);
  17.   TIM_SetCompare3(TIM2 , 899);  
  18.   TIM_SetCompare4(TIM2 , 300);
  19.    
  20.   TIM_SetCompare1(TIM3 , 899);
  21.   TIM_SetCompare2(TIM3 , 300);
  22.   TIM_SetCompare3(TIM3 , 899);  
  23.   TIM_SetCompare4(TIM3 , 300);
  24. }
  25. /*
  26. *==============================================================================
  27. *函数名称:Med_Motor_CarStop
  28. *函数功能:智能车停止
  29. *输入参数:无
  30. *返回值:无
  31. *备  注:无
  32. *==============================================================================
  33. */
  34. void Med_Motor_CarStop (void)
  35. {
  36.     TIM_SetCompare1(TIM2 , 0);
  37.   TIM_SetCompare2(TIM2 , 0);
  38.   TIM_SetCompare3(TIM2 , 0);  
  39.   TIM_SetCompare4(TIM2 , 0);
  40.    
  41.   TIM_SetCompare1(TIM3 , 0);
  42.   TIM_SetCompare2(TIM3 , 0);
  43.   TIM_SetCompare3(TIM3 , 0);
  44.   TIM_SetCompare4(TIM3 , 0);
  45. }
  46. /*
  47. *==============================================================================
  48. *函数名称:Med_Motor_CarBack
  49. *函数功能:智能车后退
  50. *输入参数:无
  51. *返回值:无
  52. *备  注:无
  53. *==============================================================================
  54. */
  55. void Med_Motor_CarBack (void)
  56. {
  57.     TIM_SetCompare1(TIM2 , 300);
  58.   TIM_SetCompare2(TIM2 , 899);
  59.   TIM_SetCompare3(TIM2 , 300);
  60.   TIM_SetCompare4(TIM2 , 899);
  61.    
  62.   TIM_SetCompare1(TIM3 , 300);
  63.   TIM_SetCompare2(TIM3 , 899);
  64.   TIM_SetCompare3(TIM3 , 300);
  65.   TIM_SetCompare4(TIM3 , 899);
  66. }
  67. /*
  68. *==============================================================================
  69. *函数名称:Med_Motor_CarLe
  70. *函数功能:智能车向左平移
  71. *输入参数:无
  72. *返回值:无
  73. *备  注:无
  74. *==============================================================================
  75. */
  76. void Med_Motor_CarLeft (void)
  77. {
  78.     TIM_SetCompare1(TIM2 , 899);
  79.   TIM_SetCompare2(TIM2 , 300);
  80.   TIM_SetCompare3(TIM2 , 899);
  81.   TIM_SetCompare4(TIM2 , 300);
  82.    
  83.   TIM_SetCompare1(TIM3 , 300);
  84.   TIM_SetCompare2(TIM3 , 899);
  85.   TIM_SetCompare3(TIM3 , 300);
  86.   TIM_SetCompare4(TIM3 , 899);
  87. }
  88. /*
  89. *==============================================================================
  90. *函数名称:Med_Motor_CarRight
  91. *函数功能:智能车向右平移
  92. *输入参数:无
  93. *返回值:无
  94. *备  注:无
  95. *==============================================================================
  96. */
  97. void Med_Motor_CarRight (void)
  98. {
  99.     TIM_SetCompare1(TIM2 , 300);
  100.   TIM_SetCompare2(TIM2 , 899);
  101.   TIM_SetCompare3(TIM2 , 300);
  102.   TIM_SetCompare4(TIM2 , 899);
  103.    
  104.   TIM_SetCompare1(TIM3 , 899);
  105.   TIM_SetCompare2(TIM3 , 300);
  106.   TIM_SetCompare3(TIM3 , 899);
  107.   TIM_SetCompare4(TIM3 , 300);
  108. }
  109. /*
  110. *==============================================================================
  111. *函数名称:Med_Motor_ClockwiseRotate
  112. *函数功能:智能车顺时针自转
  113. *输入参数:无
  114. *返回值:无
  115. *备  注:无
  116. *==============================================================================
  117. */
  118. void Med_Motor_ClockwiseRotate (void)
  119. {
  120.     TIM_SetCompare1(TIM2 , 300);
  121.   TIM_SetCompare2(TIM2 , 899);
  122.   TIM_SetCompare3(TIM2 , 899);
  123.   TIM_SetCompare4(TIM2 , 300);
  124.    
  125.   TIM_SetCompare1(TIM3 , 300);
  126.   TIM_SetCompare2(TIM3 , 899);
  127.   TIM_SetCompare3(TIM3 , 899);
  128.   TIM_SetCompare4(TIM3 , 300);
  129. }
  130. /*
  131. *==============================================================================
  132. *函数名称:Med_Motor_CounterClockwiseRotate
  133. *函数功能:智能车逆时针自转
  134. *输入参数:无
  135. *返回值:无
  136. *备  注:无
  137. *==============================================================================
  138. */
  139. void Med_Motor_CounterClockwiseRotate (void)
  140. {
  141.     TIM_SetCompare1(TIM2 , 899);
  142.   TIM_SetCompare2(TIM2 , 300);
  143.   TIM_SetCompare3(TIM2 , 300);
  144.   TIM_SetCompare4(TIM2 , 899);
  145.    
  146.   TIM_SetCompare1(TIM3 , 899);
  147.   TIM_SetCompare2(TIM3 , 300);
  148.   TIM_SetCompare3(TIM3 , 300);
  149.   TIM_SetCompare4(TIM3 , 899);
  150. }
复制代码

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



转载自:二土电子
如有侵权请联系删除
收藏 评论0 发布时间:2023-10-23 23:52

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版