请选择 进入手机版 | 继续访问电脑版
论坛
登录 | 立即注册 设为首页收藏本站 切换到宽版
查看: 202|回复: 3

ESP8266_07基于PWM的呼吸灯

[复制链接]

16

主题

34

帖子

116

积分

注册会员

Rank: 2

积分
116
发表于 5 天前 | 显示全部楼层 |阅读模式
本帖最后由 lazyduck 于 2019-12-2 13:37 编辑

这一节主要就是一个内容:PWM的用法。
先看手册上对PWM功能的介绍(以下内容转自乐鑫手册):

ESP8266系统的PWM( Pulse Width Modulation)由FRC1在软件上实现,可实现同频
率、不同占空比的多路PWM,可用来控制彩灯、蜂鸣器和电机等设备。
说明:FRC1是一个23bts的硬件定时器。
PWM的特性如下所示。
使用NM( Non Maskable Interrupt)中断,更加精确。
可扩展最多8路PVM信号
>14bit分辨率,最小分辨率45ns。
无需配置寄存器,调用函数接口即可完成配置。
注意:PWM驱动接口不能跟硬件定时器(hw_timer)接口函数同时使用,因为二者共用一个硬件定时器。
参数说明
最小分辨率:45ns(近似对应于硬件 PWM 的输入时钟频率为22.72 MHZ ) :>14 bit PWM @1 KHZ
PWM 周期:1000 us (1 KHz )~10000 us (100 Hz)
先说频率范围,100HZ~1KHZ,这个频率实在是有些低。不过据说有些人能用到二三十K,不知道真的假的。由于本人比较懒,没有测,所以上面的说法仅供参考。
然后是用法,依然使用万能的三色LED做演示,做一个呼吸灯
最终实现的效果,上电后,三个LED依次从暗到亮,熄灭,下一个~~~
另外,官方的SDK里面,提供了一个IoT_Demo的例程,里面有用PWM实现呼吸灯的代码。所以这里参考例程,进行一定的修改。
使用之前包含下面的头文件,同时把user_light.c文件拷到user目录下:
#include "user_light.h"
#include "pwm.h"
先说PWM的用法,很简单,只有三步。但因为我用了user_light.c里面的结构体,所以多加一步,先定义一个结构体。
1、定义一个结构体,存放PWM相关参数。
struct light_saved_param light_param;
结构体类型定义如下:
struct  light_saved_param {
uint32 pwm_period;
uint32 pwm_duty[PWM_CHANNEL];
};
PWM_CHANNEL是一个宏定义,定义PWM通道个数,这里是3.结构体里面可以设置PWM的周期,以及每个通道的占空比。
2、定义一个二维数组
uint32 io_info[][3] = {
{PWM_0_OUT_IO_MUX,PWM_0_OUT_IO_FUNC,PWM_0_OUT_IO_NUM},
{PWM_1_OUT_IO_MUX,PWM_1_OUT_IO_FUNC,PWM_1_OUT_IO_NUM},
{PWM_2_OUT_IO_MUX,PWM_2_OUT_IO_FUNC,PWM_2_OUT_IO_NUM},};
这一步的意义在于,你要让哪几个IO输出PWM。数组的格式要记住,但凡用到PWM,都要以这样的格式进行定义。举例来说,第一行:
PWM_0_OUT_IO_MUX,PWM_0_OUT_IO_FUNC,PWM_0_OUT_IO_NUM
分别是:管脚名、管脚功能、管脚编号。直接看肯定看不懂,因为都是宏定义,如下:
#define PWM_0_OUT_IO_MUX PERIPHS_IO_MUX_MTDI_U
#define PWM_0_OUT_IO_NUM 12
#define PWM_0_OUT_IO_FUNC FUNC_GPIO12
有人会觉得烦,说你搞这么多宏定义累不累?
但其实不是我搞的,IoT_Demo的例程里已经写好了,直接用就可以。而且,这个格式相对比较规范,所以还是建议使用。
3、PWM初始化
pwm_init(light_param.pwm_period, light_param.pwm_duty ,PWM_CHANNEL,io_info);
共有四个参数:
第一个参数:PWM的周期,这里写的是1000,单位是us。所有通道的周期都是一样的。
第二个参数:PWM的占空比,上面周期是1000,那占空比的最大值是多少?
如果答1000,那你就太年轻了!它这里有个计算公式,也需要记住(别记了,还是查手册吧)
duty = period*1000/45
period是1000,带入计算的到22222.所以占空比的取值范围是0~22222.
第三个参数:通道个数,也就是说,你要输出几路PWM?
第四个参数:PWM各个通道的GPIO的硬件参数,也就是前面定义的那个数组。


回复

使用道具 举报

16

主题

34

帖子

116

积分

注册会员

Rank: 2

积分
116
 楼主| 发表于 5 天前 | 显示全部楼层
4、启动PWM

pwm_start();

看函数名就能看懂了,不解释。

注意事项:手册里对该函数的描述是参数更新,所以但凡涉及到更新的(周期、占空比),改完之后,一定要调用一下这个函数。

经过前面四步,PWM就开始输出了。但是,咱们要做的是呼吸灯,呼吸灯是要定时修改PWM的占空比的,怎么改?再来一次pwm_init?

NO!

pwm_init只能初始化的时候调用一次,严禁多次调用。修改占空比使用下面的函数:

pwm_set_duty(duty, channel);

函数名如此简单,我已经懒得解释了。第一个参数略过,直接看第二个,channel,要写多少?

首先,这里定义了三个通道,定义的时候在数组里按照从0开始的规则,对三个通道自动进行了编号,分别是:0,1,2.

所以,你想改哪个通道,写入哪个编号即可。

注:参考手册2c-esp8266_non_os_sdk_api_reference_cn的157页,和esp8266-technical_reference_cn的100页。

保存、清理、编译、下载一条龙,然后重新上电,你会发现呼吸灯开始变化。



到此,PWM的用法说完了。

完整工程源码,请关注公众号:单片机爱好者,回复关键字:ESP8266,即可获取。
回复

使用道具 举报

1

主题

95

帖子

494

积分

中级会员

Rank: 3Rank: 3

积分
494
发表于 5 天前 | 显示全部楼层
图片上还有一个读取 AD 的功能没说呢,左 AD 右 PWM
回复

使用道具 举报

16

主题

34

帖子

116

积分

注册会员

Rank: 2

积分
116
 楼主| 发表于 3 天前 | 显示全部楼层
本帖最后由 lazyduck 于 2019-12-4 13:02 编辑
abcrazy 发表于 2019-12-2 20:59
图片上还有一个读取 AD 的功能没说呢,左 AD 右 PWM

还有件事,新版本的安信可一体化工具AThinkerIDE_V1.0  编译AThinkerIDE_V0.5的下的工程会报错,问题很多,你们多会统一给个回复啊?
../../include/ets_sys.h:117:5: error: implicit declaration of function 'ETS_INTR_DISABLE' [-Werror=implicit-function-declaration]
     ETS_INTR_DISABLE(ETS_GPIO_INUM)

又测了一下,目前结果是,必须使用你们提供的安装包内部的SDK,编译才正常。但是使用注意事项里面并没有提到。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|安信可论坛    

GMT+8, 2019-12-7 08:03 , Processed in 0.020789 second(s), 12 queries , Redis On.

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表