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做演示,做一個呼吸燈。

 

       最終實現的效果,上電後,三個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頁。

 

       保存、清理、編譯、下載一條龍,然後重新上電,你會發現呼吸燈開始變化。

       到此,PWM的用法說完了。

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

        提取碼:bldn

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章