ESP8266_07基于PWM的呼吸灯

ESP8266_01搭建开发环境

ESP8266_02程序的编译与下载

ESP8266_03SDK与Makefile的基本用法

ESP8266_04管脚控制与软件定时器

ESP8266_05 ESP8266有几个串口?

ESP8266_06硬件定时器与IO中断

ESP8266_07基于PWM的呼吸灯

ESP8266_08基于flash的数据掉电保护

ESP8266_09基于IIC控制的OLED屏幕

ESP8266_10 ESP8266的STATION模式

ESP8266_11 ESP8266的UDP广播

ESP8266_12 ESP8266客户端模式下的TCP通信

ESP8266_13服务器端模式下的TCP通信

ESP8266_14 SOFTAP模式下的服务器端和客户端

ESP8266_15天气预报之TCP的GET操作

ESP8266_16天气预报之JSON数据的生成与解析

ESP8266_17简单网络时间协议-SNTP

ESP8266_18 MQTT协议接入ONENET平台

ESP8266_19MQTT协议接入ONENET平台_订阅主题

ESP8266_20 基于ONENET平台的数据上传之TCP的POST操作

ESP8266_21基于ESP8266的一键配网

ESP8266_22基于自身ADC的电压采样

ESP8266_23基于硬件定时器的红外遥控器解码

       这一节主要就是一个内容: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做演示,做一个呼吸灯。

ESP8266_07基于PWM的呼吸灯_第1张图片

 

       最终实现的效果,上电后,三个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的硬件参数,也就是前面定义的那个数组。

 

       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页。

 

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

ESP8266_07基于PWM的呼吸灯_第2张图片

       到此,PWM的用法说完了。

       链接:https://pan.baidu.com/s/1GVoVZqLI1gbRv58qTCtG_w

        提取码:bldn

你可能感兴趣的:(ESP8266)