ESP8266 PMW介紹

前言

呼吸燈是常見的LED應用。LED呼吸燈的流程是緩緩點亮LED燈,再緩緩熄滅LED燈。在夜色下,緩慢閃爍的LED顯得格外迷人。

一、PWM單元介紹

ESP8266有四個PWM輸出接口,分別是:PWM0(GPIO12)、PWM1(GPIO15)、PWM2(GPIO14)、PWM3(GPIO4)。由於PWM接口是由軟件來實現的,因此用戶可自行拓展(最大可拓展8個,詳細請參考ESP8266 SDK的pwm.h文件)。

PWM可調節的週期在1000us~10000us,即100HZ~1KHZ之間。

有關PWM的介紹請自行上網查閱資料。

二、PWM配置流程介紹

1.首先對PWM的佔空比、週期以及PWM通道進行配置。

2.配置系統定時器,將呼吸燈運行程序配置成每30ms運行一次,以刷新PWM的佔空比。

三、相關API介紹

1、pwm_init

API 介紹 - -
功能介紹 初始化PWM配置 -
函數原型 void pwm_init(uint32 period, uint32 *duty, uint32 pwm_channel_num, uint32 (*pin_info_list)[3]); -
參數介紹 period PWM週期
- *duty 各PWM通道的佔空比
- pwm_channel_num 需要使用的PWM通道數量
- (*pin_info_list)[3] 使用的PWM通道的GPIO參數

示例:

uint32_t io_info[ ][ 3 ] =
{
/** 該參數在ESP8266 SDK的user_light.h中 */
{ PWM_1_OUT_IO_MUX, PWM_1_OUT_IO_FUNC, PWM_1_OUT_IO_NUM }, 
};

uint32_t duty[] = {0};

/** 配置PWM的週期爲1000us,佔空比爲0,PWM通道數量爲1 */
pwm_init( 1000, duty, 1, io_info );

2、pwm_start

API 介紹 - -
功能介紹 更新PWM配置
函數原型 void pwm_start(void)
註釋 在PWM參數配置完成後需要調用該函數

3、pwm_set_duty

API 介紹 - -
功能介紹 設置某PWM通道的佔空比 -
函數原型 void pwm_set_duty(uint32 duty, uint8 channel) -
參數介紹 duty 新的PWM通道佔空比
- channel 需要設置的PWM通道(從零開始算)

示例:

/** 設置PWM通道1的佔空比爲100 */
pwm_set_duty( 100, 0 );

/** 使PWM配置生效 */
pwm_start();

4、pwm_get_duty

API 介紹 - -
功能介紹 獲取某通道的佔空比的數值 -
函數原型 uint32 pwm_get_duty(uint8 channel) -
參數介紹 channel 需要設置的PWM通道(從零開始算)
返回值 該通道的佔空比 -

5、pwm_set_period

API 介紹 - -
功能介紹 設置某PWM通道的週期 -
函數原型 void pwm_set_period(uint32 period, uint8 channe) -
參數介紹 period 新的PWM通道週期
- channel 需要設置的PWM通道(從零開始算)

示例:

/** 設置PWM通道1的週期爲100us */
pwm_set_period( 100, 0 );

/** 使PWM配置生效 */
pwm_start();

6、pwm_get_period

API 介紹 - -
功能介紹 獲取某通道的週期 -
函數原型 uint32 pwm_get_period(uint8 channel) -
參數介紹 channel 需要設置的PWM通道(從零開始算)
返回值 某通道的週期 -

注:詳細的介紹詳見ESP8266 SDK說明文檔。

四、例程

   #include "ets_sys.h"
   #include "osapi.h"

   #include "user_light.h"
   #include "gpio.h"

   #include "user_interface.h"

   static os_timer_t os_timer;

   /** 呼吸燈運行程序 */
   void ESP8266_PWM_RUN( void )
   {
       /** PWM佔空比變量 */
       static u8 set_duty = 0;

       /** 佔空比加減標誌 */
       static bool f = true;
       if ( f == true )
       {
           if ( ++set_duty >= 100 )
           {
               f = false;
           }
       }
       else
       {
           if ( --set_duty <= 0 )
           {
               f = true;
           }
       }

       /** 更新PWM通道0的佔空比 */
       pwm_set_duty( set_duty, 0 );
       pwm_start();
   }

   /** 初始化PWM配置、系統定時器配置 */
   void ESP8266_PWM_Init( void )
   {
   //    struct pwm_param pwm_config;
       uint32_t io_info[ ][ 3 ] =
       {
           { PWM_1_OUT_IO_MUX, PWM_1_OUT_IO_FUNC, PWM_1_OUT_IO_NUM }, 
       };

       uint32_t duty[ ] = { 0 };

   //    pwm_config.duty[ 0 ] = 0;
   //    pwm_config.freq = 0;
   //    pwm_config.period = 1000;

       pwm_init( 1000, duty, 1, io_info );

       /** 配置定時器每30ms執行一次ESP8266_PWM_RUN()函數 */
       os_timer_disarm( &os_timer );
       os_timer_setfn( &os_timer, (ETSTimerFunc *) ( ESP8266_PWM_RUN ), NULL );
       os_timer_arm( &os_timer, 30, true );
   }

   /** 用戶初始化程序,根據測試該程序只運行一次 */
   void user_init(void)
   {
       ESP8266_PWM_Init();
   }

參考資料

[1]. ESP8266技術參考
[2]. ESP8266Non-OS SDK API參考

發佈了44 篇原創文章 · 獲贊 54 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章