【单片机入门】(四)应用层软件开发的单片机学习之路-----ESP32开发板PWM控制电机以及中断的使用
引言
各位大佬,晚上好啊,在上一篇博客中,我们讲了什么是UART串口通讯,以及使用USB转TTL使得单片机可以和c#上位机做一个串口通讯,接下来,为大家带来PWM的概念原理,以及实际案例,使用PWM对电机进行速度调制,因为本课程的最后是做一个红外遥控的智能小车,所以是需要电机四个,驱动四个,轮胎四个,所以PWM对于最后的成果也是极为重要,并且在实际开发中,PWM也是比较常用的调速方式。
概念
PWM全称Pulse width modulation,中文翻译为脉冲宽度调制,其基本原理为控制方式就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等但宽度不一致的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输出波形的半个周期中产生多个脉冲,使各脉冲的等值电压为正弦波形,所获得的输出平滑且低次谐波少。按一定的规则对各脉冲的宽度进行调制,既可改变逆变电路输出电压的大小,也可改变输出频率。
可能上面对于原理的解释过于官方,大家可能看不懂,通俗易懂的来说,就是通过对电子元器件的电路进行高低电平进行控制,在一段时间内,高低电平在输出会形成一段波动,这个波动可以成为PWM波形,而我们需要使用代码去控制PWM的输出波形,高电平在这一段波动中,通电时间即高电平时间是占了总时间多少,同时在这一段PWM波形中,高低电平来回切换的频率又是多少,形成了这么一段波形,这就引入了两个概念,占空比(Duty Ratio)和频率,占空比代表着,高电平通电总时和总时的一个占比(这段波形中,高低电平的总共占用时间),而频率则是高低电平在这段波形中,来回切换的一个频率。
如下图,下方在Arduino串口绘图器中,展示了一段锯齿波形,看下方的GIF我们可以看到对应的电机运动也是有快到慢的一个运动状态。
代码解析
void setup() {
Serial.begin(9600);
ledcSetup(0, 5000, 8);
ledcAttachPin(12, 0);
}
// the loop function runs over and over again forever
void loop() {
for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {
ledcWrite(0, dutyCycle);
delay(7);
Serial.println(dutyCycle);
}
}
在Arduino中我们可以使用LEDC来实现对PWM的控制,而在纯c乐鑫的开发板中,是可以使用MCPWM进行控制,但是由于Arduino在此处不能使用MCPWM,则就有了LEDC作为替代品,ESP32带有一个16通道的一个LED PWM控制器,对应使用的是乐鑫的LED PWM控制,ESP32 LED PWM,分为8路高速通道和8路低速通道,然后我们使用不同的频率,和占空比来实现控制电机转速的控制。
在上面的代码中,我们先设置了ledc的通道为0,频率为5000,第八个低速LED控制器,即代码为 ledcSetup(0, 5000, 8);然后需要将通道和引脚进行管理使用ledcAttachPin(12, 0);将引脚12和第0个通道关联起来,在loop代码中,可以看到,我们写入的最大的占空比为255,而0-255总数为256,那是因为,占空比是和通道是有关系的,上文提到,LED的PWM控制器一共有16个,此处我们使用8,而256则为2的8次方的值,所以占空比最大为256,如果取值为10,占空比的最大值则为1024-1;ledcwrite(0,dutyCycle);则是将占空比写入对应的通道,便完成了PWM对电机进行调速设置。
Arduino针对ESP32 乐鑫PWM的封装,目前已知的有LEDC,不需要安装,默认就可以使用,而其他的也有对于PWM的封装,个人测试了一两个倒也没有这个好用,后续各位朋友也可以继续探索其他好用的PWM库进行开发。
中断
在上面讲完PWM之后,我们再来讲一下中断,以及中断的一个实际案例。中断,顾名思义,是在程序执行期间,遇到某一个事件的时候,将暂停手上的工作先去执行某一件事情,这个事情则是我们中断当下工作,去执行的事情,这个动作,称之为中断。虽然在代码中,可以注册一个后台任务(在纯c中),进行不停的while,但是这样在性能上还是无法发挥单片机的功效,所以这种场景下我们便需要使用中断,来实现我们的某种功能,例如使用按钮,来判断是否需要打开LED,或者是其他的行为。
在Arduino中,我们可以使用attachInterrupt函数来进行对引脚增加中断以及使用detachInterrupt来移除中断,
attachInterrupt函数需要三个参数,第一个为中断需要使用的引脚pin,第二个为中断触发的函数,第三个为中断的类型,对于ESP32的中断,在Arduino中,其方法名前面必须加一个IRAM_ATTR标记其为中断函数,第一个函数中的digitalPinToInterrupt为将27和中断进行一个绑定,同时还有其他方法,但是官方均不推荐,
在下方的代码中,我们定义了一个change的函数用来处理ESP32 27引脚的中断,用27引脚的电平控制LED引脚2的电平,以此来控制是否点亮LED灯,先设置引脚2为输出模式,27引脚为上拉输入模式,可以理解为上拉电阻的一般都需要用到这种模式,然后我们将引脚27和中断进行关联,设置中断函数为change,模式为CHANGE。然后在LOOP函数中,我们给引脚2写入state的值,当进入change中断函数中,会将state取反,然后进入loop写入值。以此实现控制LED的显示和不显示,在这里,提醒一下,由于在单片机中,中断以及定时器都是非阻塞模式,而Serial.println函数是阻塞写入缓冲区,会导致中断函数会不断的输出错误,错误:Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1).
这是因为println函数阻塞导致定时器无法继续执行,所过非要使用此函数,可以尝试设置中间变量,然后在loop函数中判断是否改变值,然后进行输出信息到串口。
可以在下方GIF看到,我们使用按钮进行控制LED的显示和不显示。
volatile byte state = LOW;
void IRAM_ATTR change()
{
state=!state;
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(2, OUTPUT);
pinMode(27, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(27), change, CHANGE);
}
void loop() {
digitalWrite(2, state);// put your main code here, to run repeatedly:
}
可以看到第二个方法是传入一个interrupt的中断编号,但是ESP32上面的中断编号,不在官方资料中,所以我们只有需要第一个方法来进行引脚和中断函数的关联,当然了可能最后一个也是可以,只是此处我没有尝试,感兴趣的可以进行尝试,
在mode中,Arduino是支持五种模式,第一种为LOW,,看翻译我们知道,这个是在电平处于低电平时会触发中断函数,
第二个CHANGE是不管是高到低,还是低到高,都会触发
第三种是引脚在由低电平到高电平时触发,而不是已经到了高电平触发,
第四种是下降,当电平由高到低时会触发中断函数,
第五种是电平处于高电平时会触发中断函数。
结语
今天讲了PWM还有中断的使用,可能一次性讲的有点多,有点难以消化,有什么不懂的可以及时问我,以及后面我更新的时间会稍微慢一点,防止讲的过快,一时间不明白,后面还会有对于IIC,SPI的一个案例讲解,在这些讲完后,我会开始准备最终极的目标,做一个智能小车,其中会需要的配件,这两天我会总结好发到群里,以及购买链接。有感兴趣的同学可以加QQ群,一起学习,一起讨论,博主也是一个刚开始玩单片机的学徒,后面也会研究stm32系列单片机,欢迎大家加入讨论,学习。
【单片机入门】(四)应用层软件开发的单片机学习之路-----ESP32开发板PWM控制电机以及中断的使用的更多相关文章
- 微信开发+百度AI学习:微信网页开发环境搭建
参考微信官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 两步即可获取微信网页开发能力 STEP1: ...
- 2021年正确的Android逆向开发学习之路
2021年正确的Android逆向开发学习之路 说明 文章首发于HURUWO的博客小站,本平台做同步备份发布.如有浏览或访问异常或者相关疑问可前往原博客下评论浏览. 原文链接 2021年正确的Andr ...
- 8_陀螺仪MPU6050和PWM控制在STM32F4-Discovery开发板上的实现
非常早曾经就把圆点博士的程序从STM32F103移植到STM32F4_Discovery (STM32F407), battery.陀螺仪和PWM电机控制的程序都已经測试完成,执行有一段时间,正常.以 ...
- 【单片机入门】(三)应用层软件开发的单片机学习之路-----UART串口通讯和c#交互
引言 在第一章博客中,我们讲了Arduino对Esp32的一个环境配置,以及了解到了常用的一个总线通讯协议,其中有SPI,IIC,UART等,今天我为大家带来UART串口通讯和c#串口进行通讯的一个案 ...
- Linux下开发STM32单片机
一开始学习51单片机就是用的MDK这个IDE软件,IDE软件虽然看起来直观好像更加容易入门(因为有界面看起来很形象),但是实际上IDE却是向我们这些入门人员隐藏了背后真实存在的过程,让我们以为编译就是 ...
- SaaS系列介绍之十四: SaaS软件开发分析
1 引言 真正的问题,不是电脑是否具备思考能力,而是人类是否具备这种能力 ________B.F.Skinner<计算机科学> SaaS模式不同于传 ...
- Spring Boot入门(四):开发Web Api接口常用注解总结
本系列博客记录自己学习Spring Boot的历程,如帮助到你,不胜荣幸,如有错误,欢迎指正! 在程序员的日常工作中,Web开发应该是占比很重的一部分,至少我工作以来,开发的系统基本都是Web端访问的 ...
- 四种软件开发模式:tdd、bdd、atdd和ddd的概念
看一些文章会看到TDD开发模式,搜索后发现有主流四种软件开发模式,这里对它们的概念做下笔记. TDD:测试驱动开发(Test-Driven Development) 测试驱动开发是敏捷开发中的一项核心 ...
- AndroidStudio快速入门四:打造你的开发工具,settings必备
http://blog.csdn.net/jf_1994/article/details/50085825 前言:这里是使用AS的基本设置,适合新入手的朋友阅读,将这里介绍的设置完基本使用无忧啦. 1 ...
随机推荐
- MySQL数据库授权的两种方式
方法一:grant命令创建用户并授权(针对只修改权限) grant命令简单语法如下: grant all privileges on dbname.* to username@localhost id ...
- 轻松月薪过万,NISP证书含金量有多重|NISP管理中心|网安伴|nisp
nisp一级证书含金量 NISP一级证书是面向各个行业工作人员信息安全意识普及化和网络信息安全基础培训的国家级验证.持NISP一级证书可以从信息安全保密较高的单位得到加分.证书由中国信息安全测评中心授 ...
- 【NOI P模拟赛】华莱士CNHLS(容斥,数论分块)
题意 出题人吃华 莱 士拉肚子了,心情不好,于是出了一道题面简单的难题. 共 T T T 组数据,对正整数 n n n 求 F ( n ) = ∑ i = 1 n μ 2 ( i ) i F(n)=\ ...
- 免杀手法-tcp套字节传递shellcode学习
免杀手法-tcp套字节传递shellcode学习
- FR801xH开发
一.空间分配 二.代码流程 1)user_custom_parameters 函数 __jump_table 结构体中保存了一些配置信息: void user_custom_parameters(vo ...
- ASP.NET Core 6框架揭秘实例演示[35]:利用Session保留语境
客户端和服务器基于HTTP的消息交换就好比两个完全没有记忆能力的人在交流,每次单一的HTTP事务体现为一次"一问一答"的对话.单一的对话毫无意义,在在同一语境下针对某个主题进行的多 ...
- HTTP 优缺点
HTTP 最凸出的优点是「简单.灵活和易于扩展.应用广泛和跨平台」. 1. 简单HTTP 基本的报文格式就是 header + body ,头部信息也是 key-value 简单文本的形式,易于理解, ...
- 读完 RocketMQ 源码,我学会了如何优雅的创建线程
RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时.高可靠的消息发布与订阅服务. 这篇文章,笔者整理了 RocketMQ 源码中创建线程的几点技巧,希望大家读完之后,能 ...
- 【设计模式】Java设计模式 - 适配器模式
[设计模式]Java设计模式 - 适配器模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一 ...
- 企业运维实践-丢弃手中的 docker build , 使用Kaniko直接在Kubernetes集群或Containerd环境中快速进行构建推送容器镜像
关注「WeiyiGeek」公众号 设为「特别关注」每天带你玩转网络安全运维.应用开发.物联网IOT学习! 希望各位看友[关注.点赞.评论.收藏.投币],助力每一个梦想. 本章目录 目录 首发地址: h ...