STM32外设系列—L298N

文章目录

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

一、L298N简介

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

L298N

二、L298N电路图

L298N的电路图如下

L298N电路图

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

三、L298N使用方法

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

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

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

四、L298N驱动电机实例

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

4.1 麦克纳姆轮简介

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

麦克纳姆轮

麦克纳姆轮主要是由轮毂和辊子两部分组成,辊子轴线和轮毂轴线夹角为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);// 配置GPIOGPIO_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);// 配置TIM2TIM_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通道1TIM_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通道2TIM_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通道3TIM_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通道4TIM_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);// 使能TIM2TIM_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);// 配置GPIOGPIO_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);   // 配置TIM3TIM_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通道1TIM_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通道2TIM_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通道3TIM_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通道3TIM_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);// 使能TIM3TIM_Cmd(TIM3 , ENABLE);
}

4.3 智能车行驶控制

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

麦克纳姆轮受力分析

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

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

下面是控制程序

// 差值决定快慢,差值越大越快
// 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的控制和调速方法,我们就能做许多事情。比如利用蓝牙来调整智能车行驶速度。实际原理就是通过蓝牙给配置占空比的函数传入数值,改变占空比,从而达到遥控调节车速的目的。这个在后续的实战项目系列中会有相关介绍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/2945.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【spring】spring是什么?详解它的特点与模块

作者:Insist-- 个人主页:insist--个人主页 作者会持续更新网络知识和python基础知识,期待你的关注 目录 一、spring介绍 二、spring的特点(七点) 1、简化开发 2、AOP的支持 3、声明式事务的支持 4、方便测试 5、…

C++静态和动态链接库导出和使用

1、简介 代码开发过程中会遇到很多已有的函数库,这些函数库是现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。 本质上来说库是一种…

机器学习笔记 - Facebook AI Similarity Search(Faiss)简介

一、概述 Facebook AI Similarity Search (Faiss)是高效相似性搜索最受欢迎的轮子之一。给定一组向量,我们可以使用 Faiss 对它们进行索引——然后使用另一个向量(查询向量),我们在索引中搜索最相似的向量。 它包含搜索任何大小的向量集的算法,除非超出RAM的大小。它还包…

【完美复现】面向配电网韧性提升的移动储能预布局与动态调度策略【IEEE33节点】(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

EFS文件夹加密属性灰色不能勾选怎么办?

EFS加密是Windows自带的文件夹加密方式,对于用户而言,它的加密是无感的。但是有些时候我们会发现EFS的加密选项为灰色,且无法勾选,那么这时该怎么办呢? 使用EFS加密的条件 首先,要使用EFS加密功能并不是没…

华为智能高校出口安全解决方案(1)

华为智能高校出口安全解决方案(1) 视频链接方案背景需求分析高校园区网概述高校园区网全景高校出口场景介绍高校出口整体需求分析业务安全需求攻击防御需求运维审计需求 方案规划华为智能高校出口安全解决方案架构华为智能高校出口安全解决方案功能划分业…

总结vue3 的一些知识点:​Vue3 起步

目录 引言 Vue3 混入 实例 选项合并 实例 实例 全局混入 实例 Vue3 起步 Vue 3.0 实例 data 选项 实例 方法 总结 引言 Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨…

Linux终端与进程的关系 ( 1 ) -【Linux通信架构系列】

系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 期待你的关注哦!!! 现在的一切都是为将来的梦想编织翅膀,让梦想在现实中展翅高飞。 Now everything is for the…

CleanMyMac X中文版Mac电脑系统清理工具使用测评

有些人可能会说,mac系统根本就不需要清理,但是真正到你磁盘快满的时候就不是这种想法了,不管什么系统,它都会缓存一些系统、用户等文件,可能当时能够帮上大忙,能够在操作的时候更快、更便捷,但是…

『 MySQL篇 』:MySQL 锁机制介绍

目录 一. 概述 二. 全局锁 三 . 表级锁 三. 行级锁 一. 概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据…

【八股】【C++】函数与类

这里写目录标题 形参与实参的区别函数调用过程指针和引用当函数参数引用作为函数参数有哪些好处回调函数友元函数重载匹配运算符重载直接初始化与拷贝初始化函数指针C中struct(结构)和class(类)的区别C有哪几种构造函数构造函数的…

云HIS是什么?HIS系统为什么要上云?云HIS有哪些优点?

一、当前医疗行业HIS的现状与发展趋势 1.医院信息系统(HIS)经历了从手工到单机再到局域网的两个阶段,随着云计算、大数据新技术迅猛发展,基于云计算的医院信息系统将逐步取代传统局域网HIS , 以适应人们对医疗卫生服务越来越高的要…