ESP8266_12 ESP8266客戶端模式下的TCP通信
ESP8266_19MQTT協議接入ONENET平臺_訂閱主題
ESP8266_20 基於ONENET平臺的數據上傳之TCP的POST操作
這一節主要就是一個內容: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