【STM32】STM32F103C8T6+L298N通过PWM控制直流电机转速

2023-05-16

系列文章目录 

·【STM32】新建工程模板及配置

·【STM32】STM32与PC端、HC-06、ROS进行USART串口通信

·【ROS】ROS上位机使用Serial库和boost::asio库与STM32进行USART通讯

·【STM32】STM32F103C8T6+L298N通过PWM控制直流电机转速

·【STM32】STM32F103C8T6使用外部中断法和输入捕获法进行编码器测速

·【STM32】STM32F103C8T6实现直流电机速度PID控制


目录

系列文章目录

前言

一、PWM调速原理

二、STM32编程实现

总结


前言

原来做的差速小车是基于Arduino控制的,感觉有些简单,也有些基础,Arduino方便简单的同时,可操作性感觉也少了很多,所以想将控制器换成STM32,然后将树莓派作为上位机,STM32作为下位机,通过树莓派和STM32进行通讯,实现对差速移动小车的控制,本人也是寒假期间初学STM32,也是奔着应用去的,所以对于STM32编程原理方面可能不太精通,这里偏重于记录应用层面的知识。


一、PWM调速原理

直流电机驱动是最简单的,给电机通上电就能转,根据电机的公式:

E = C_{e} \phi n

U = E + R_{a}I

n = \frac{U}{C_{e}\phi } - \frac{R_{a}}{C_{e}C_{t}\phi ^{2}} T_{em}

可知:当提高电压时,反电势升高,进而转速升高,电压与转速大致有如图所示的关系

所以我们只要控制给电机通电的电压即可控制电机的转速,但是在实际的控制中,控制直流电机需要通过H桥控制电机的正反转,如图,当T1和T4二极管导通时,有粉色通路;当T2和T3二极管导通时,有蓝色通路,这样我们就可以实现弱电控制强电,通过二极管的通断来控制电机的转向。

但是这样电机通电时电压就是Us,我们如果想自由的控制Us的电压值基本是不能实现的,因为电机是接到单片机的引脚上的,引脚的供电电压值是确定的,我们就要使用控制二极管的通断时间对电机的转速进行控制,即PWM控制。

图中的D1~D4二极管为续流的作用,因为电机中有绕组,在断电后,电感的电流不能瞬时变为0,所以在断电后电流沿棕色和绿色的通路放点。

       

 在一个周期内,我们通过控制通电的时间就可以调控平均电压,而平均电压的高低直接控制电机的转速,通电时间/周期,就可以得到占空比,我们也就是通过控制电机的占空比来控制电机的转速的。

 在实际应用过程中,我们不用自己搭建H桥,而是使用电机驱动板(如:L298N)对直流电机进行驱动,L298N内搭载两个H桥电路,可以实现对两个电机的转向和转速进行控制。

 这是淘宝商家提供的电机驱动板控制表,将IN1~4接到单片机的引脚,我们就可以通过引脚输出PWM控制信号,对直流电机进行控制。

二、STM32编程实现

在STM32中如果想输出PWM信号,需要借助定时器,通过定时器的捕获/比较通道的PWM输出

 当我们对定时器设置了预装载值arr和比较值ccr后,可以通过配置PWM模式,使定时器CNT计数值超过ccr后产生有效信号,并通过配置相应寄存器设置有效信号是1还是0,而配置PWM的输出方式,具体原理信息可以参考原子哥的视频,也可以参考中文参考手册的14.4.7内容。

 在程序中,我们使用库函数进行配置,配置步骤如下:

  1.  使能定时器和相关外设引脚时钟 :RCC_APBxPeriphClockCmd()
  2. 配置IO口为复用输出模式(查手册8.1.11)配置成相应的模式(复用推挽输出)
  3. 初始化定时器:TIM_TimeBaseInit()
  4. 初始化TIM2 Channe1234 PWM模式:TIM_OCxInit()
  5. 使能OCx通道的预装载寄存器:TIM_OC1PreloadConfig()
  6. 使能时钟:TIM_Cmd()
  7. 在主函数中配置占空比进行调速:TIM_SetCompare1()
#include "sys.h"

/********************
功能:通用时钟2用来产生通道1234四路PWM信号
函数:TIM2_PWM_Init(u16 arr,u16 psc)
作者:K.Fire
日期:2022.01.30
引脚:PA0 PA1 PA2 PA3
参数:arr:自动重装值 psc:时钟预分频数
*****************/

void TIM2_PWM_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	//使能GPIOA外设模块时钟  
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   
 
	//设置引脚为复用输出功能,输出TIM2 CH1的PWM脉冲波形	GPIOA.0
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //TIM2_CH1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
	
	//设置引脚为复用输出功能,输出TIM2 CH2的PWM脉冲波形	GPIOA.1
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //TIM2_CH2
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
	
    //设置引脚为复用输出功能,输出TIM2 CH3的PWM脉冲波形	GPIOA.2
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //TIM2_CH3
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
	
	//设置引脚为复用输出功能,输出TIM2 CH4的PWM脉冲波形	GPIOA.3
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //TIM2_CH4
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
 
	//使能定时器2时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	
    //初始化TIM2
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
	
	//初始化TIM2 Channe1234 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC1
	TIM_OC2Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC2
	TIM_OC3Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC3
	TIM_OC4Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC4

	TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR1上的预装载寄存器
	TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR2上的预装载寄存器
	TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR3上的预装载寄存器
	TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR4上的预装载寄存器
 
	TIM_Cmd(TIM2, ENABLE);  //使能TIM2
	
}


总结

原理部分我讲的很简略,我也是看原子哥的视频学,如果大家对单片机控制原理有学习需要,可以去B站看原子哥的视频,博主主要是做控制和上位机的,所以这部分只需要会用即可 

 


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【STM32】STM32F103C8T6+L298N通过PWM控制直流电机转速 的相关文章

  • FreeRTOS任务(动态)创建与删除(一)

    FreeRTOS学习总结 文章目录 前言一 浅浅了解二 创建任务1 动态任务创建2 动态实践 总结 前言 听朋友说 xff0c FreeRTOS很好用 xff0c 就在无聊的上网课期间浅学一下 提示 xff1a 以下是本篇文章正文内容 xf

随机推荐

  • FreeRTOS操作系统队列及队列API函数(五)

    FreeRTOS学习总结 文章目录 前言一 队列功能1 数据存储2 多任务访问3 出队阻塞4 入队阻塞 二 队列操作过程图示1 创建队列2 向队列发送第一个消息3 向队列发送第二个消息4 从队列中读取消息 二 API函数1 队列创建函数2
  • php导出word文件,打开损坏或者乱码

    下载Word文件 fileinfo 61 pathinfo fullname ob end clean header 39 Content type application x 39 fileinfo 39 extension 39 hea
  • FreeRTOS操作系统优先级翻转问题(八)

    FreeRTOS总结 文章目录 前言一 浅浅了解优先级翻转二 模拟 优先级翻转实验1 代码 总结 前言 在使用二值信号量的时候会遇到很常见的一个问题 优先级翻转 xff0c 优先级翻转在可剥夺 内核中是非常常见的 xff0c 在实时系统中不
  • 伽马分布,指数分布,卡方分布三者关系

    1 伽马分布是一个连续概率分布 xff0c 具有两个参数 alpha 和 lambda xff0c 记为
  • 数据结构 马踏棋盘 栈应用 C++

    include lt iostream gt 包含其它头文件 using namespace std const int StackInitSize 61 10 const int StackInc 61 10 typedef int SE
  • STM32智能小车------红外遥控

    文章目录 一 原理讲解1 实物图2 工作原理 xff1a 3 接线 xff1a 二 软件驱动代码1 驱动函数2 获取键值 总结最终效果 大家好哇 xff01 我是小光 xff0c 嵌入式爱好者 xff0c 一个想要成为系统架构师的普通大学生
  • UCOS学习(一)——前后台系统、RTOS系统

    大家好哇 xff01 我是小光 xff0c 嵌入式爱好者 xff0c 一个想要成为系统架构师的大二学生 最近开始学习UCOS操作系统 xff0c 后面会更新一些关于UCOS学习笔记 今天了解了UCOS操作系统 xff0c 总结一下知识点 感
  • UCOS学习(二)——UCOS-II、UCOS-III移植到STM32F103

    大家好哇 xff01 我是小光 xff0c 嵌入式爱好者 xff0c 一个想要成为系统架构师的大二学生 最近开始学习UCOS操作系统 xff0c 后面会更新一些关于UCOS学习笔记 今天学习了如何将UCOS II和UCOS III移植到ST
  • UCOS学习(三)——任务管理基础

    大家好哇 xff01 我是小光 xff0c 嵌入式爱好者 xff0c 一个想要成为系统架构师的大二学生 最近开始学习UCOS操作系统 xff0c 后面会更新一些关于UCOS学习笔记 今天学习了任务管理基础知识 感谢你的阅读 xff0c 不对
  • UCOS学习(七)——信号量详解

    信号量 信号量简介信号量保护共享资源举个栗子 xff1a 如果不使用信号量信号量解决公共资源问题创建信号量 xff1a 信号量实现任务同步总结 信号量简介 信号量像是一种上锁机制 xff0c 代码必须获得对应的钥匙才能继续执行 xff0c
  • Altium Designer(AD)的简易使用

    一 绘制原理图 原理图库 首先来说明原理图的概念 根据百度百科 xff0c 原理图 xff0c 顾名思义就是表示电路板上各器件之间连接原理的图表 也就是表示芯片上的引脚连接什么元件 xff0c 各个元件谁和谁相连 xff0c 电源电压的大小
  • STM32CubeIDE---HAL库PWM使用速记

    一 如何计算 理论分析 xff1a HAL库函数之呼吸灯 PWM波 简书 jianshu com 预分频系数 PSC 自动重装载值 ARR 捕获 比较寄存器值 CCR 频率计算 xff1a 定时器频率 PSC 43 1 ARR 43 1 占
  • mac常用命令

    mac清除电脑DNS缓存 sudo dscacheutil flushcache
  • IMU初介绍及里程计相关补充

    IMU原理 xff1a 以牛顿力学定律为基础 xff0c 通过测量载体在惯性参考系的加速度 xff0c 将它对时间进行积分 xff0c 且把它变换到导航坐标系中 xff0c 就能够得到在导航坐标系中的速度 偏航角和位置等信息 IMU xff
  • C语言变量的定义与声明,为什么全局变量不能赋值

    文章目录 一 对C语言程序的一些补充二 定义域声明2 1 什么是变量2 2 如何定义变量2 3 为什么要定义变量2 4 定义变量的本质2 5 变量声明的本质2 6 定义和声明的区别 三 全局变量无法赋值 一 对C语言程序的一些补充 对于一个
  • 野火PID上位机通信移植

    野火PID上位机通信移植 一 简介 在调试pid参数的时候 xff0c 需要用到上位机 xff0c 这里选用 野火多功能调试助手 使用调试助手 xff0c 需要下位机与上位机之间的通信协议 xff0c 下载野火关于电机的相关例程 xff0c
  • 实验报告数字图像的基本操作

    一 实验目的 了解Matlab的基本功能及操作方法练习图像读写和显示函数的使用方法掌握如何利用MATLAB来获取图像的大小 颜色 高度 宽度等等相关信息熟悉常用的图像文件格式与格式转换 xff1b 二 实验环境 PC计算机MatLab软件
  • 【meArm机械臂】第二篇·Arduino控制程序

    系列文章目录 meArm机械臂 第一篇 结构设计及搭建 meArm机械臂 第二篇 Arduino控制程序 文章目录 系列文章目录前言一 测试程序1 单个电机测试程序2 四舵机控制测试程序3 极限位置测量 二 基本控制程序三 最终控制程序总结
  • 【树莓派4B】安装Ubuntu Mate20.04+ROS Noetic+使用电脑自带的xrdp和VNC进行PC端远程控制

    目录 前言 一 烧录Ubuntu Mate20 04 1 下载Ubuntu Mate 20 04 2 格式化SD卡并烧录系统 3 打开SSH功能 二 配置Ubuntu环境 1 初次开机进行简单的配置 2 更换国内源 3 更新软件列表和软件
  • 【STM32】STM32F103C8T6+L298N通过PWM控制直流电机转速

    系列文章目录 STM32 新建工程模板及配置 STM32 STM32与PC端 HC 06 ROS进行USART串口通信 ROS ROS上位机使用Serial库和boost asio库与STM32进行USART通讯 STM32 STM32F1