1. 程式人生 > >AliOS-Things--ESP8266--Blink--PWM輸出

AliOS-Things--ESP8266--Blink--PWM輸出

ESP8266的PWM輸出是基於Blink工程來完成的。 必須的元件:

  • ESP8266的PWM庫,路徑為:AliOS-Things-master\AliOS-Things-master\platform\mcu\esp8266\bsp\lib\libpwm.a

使用ESP8266的SDK程式設計方法,偶然調通了!

SDK PWM程式設計

 沒有文件,沒有指導,只能從以前寫的ESP8266 SDK PWM程式設計裡面找靈感!如下是我以前寫的PWM輸出例程:  它的效果是,所有的PWM輸出引腳輸出佔空比為0然後慢慢增加到100,佔空比到100之後又緩慢遞減到0的PWM波。迴圈往復。

	#include "ets_sys.h"
#include "osapi.h" #include "user_light.h" #include "gpio.h" #include "user_interface.h" // 設定PWM通道:GPIO12、GPIO15、GPIO13、GPIO4、GPIO5(外加的) #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 #define PWM_1_OUT_IO_MUX PERIPHS_IO_MUX_MTDO_U
#define PWM_1_OUT_IO_NUM 15 #define PWM_1_OUT_IO_FUNC FUNC_GPIO15 #define PWM_2_OUT_IO_MUX PERIPHS_IO_MUX_MTCK_U #define PWM_2_OUT_IO_NUM 13 #define PWM_2_OUT_IO_FUN CFUNC_GPIO13 #define PWM_3_OUT_IO_MUX PERIPHS_IO_MUX_GPIO4_U #define PWM_3_OUT_IO_NUM 4 #define PWM_3_OUT_IO_FUNC FUNC_GPIO4 #define
PWM_4_OUT_IO_MUX PERIPHS_IO_MUX_GPIO5_U
#define PWM_4_OUT_IO_NUM 5 #define PWM_4_OUT_IO_FUNC FUNC_GPIO5 #define PWM_CHANNEL 5 // 設定5個PWM通道 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_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}, {PWM_3_OUT_IO_MUX,PWM_3_OUT_IO_FUNC,PWM_3_OUT_IO_NUM}, {PWM_4_OUT_IO_MUX,PWM_4_OUT_IO_FUNC,PWM_4_OUT_IO_NUM}, }; pwm_config.duty[ 0 ] = 0; pwm_config.freq = 0; pwm_config.period = 1000; pwm_init( pwm_config.period, pwm_config.duty, PWM_CHANNEL , 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(); }

思考:上面的例程中使用了定時器,但是,在AliOS-Things中完全不知道怎麼用定時器啊!

 想起,Blink例程中的LED閃爍那個操作的原理雖然不懂,但是效果和定時器的是一模一樣的!所以,就以Blink例程為基礎進行修改。  因為使用了ESP8266的資源所以需要在Blink.mk裡面新增

NAME := blink

$(NAME)_SOURCES := blink.c

$(NAME)_COMPONENTS += mcu/esp8266   # 新增ESP8266的資源

GLOBAL_DEFINES += AOS_NO_WIFI

$(NAME)_COMPONENTS := yloop cli

GLOBAL_INCLUDES += ./

為啥,是muc/esp8266?因為,mcu的目錄下沒有.mk的檔案,mcu的平級目錄中也沒有.mk檔案,但是mcu目錄下的子目錄esp8266目錄下是有.mk檔案的。根據AliOS-Things的MK規則,現在esp8266下的所有資源都可以使用了。  修改一波之後,如下: Blink.c

/*
 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
 */

#include <aos/aos.h>
#include <hal/soc/soc.h>
#include "stdio.h"
#include <../../../platform/mcu/esp8266/bsp/include/espressif/pwm.h>
#include <../../../platform/mcu/esp8266/bsp/include/driver/gpio.h>

/**
 * Brief:
 * This test code shows how to configure gpio and how to use gpio interrupt.
 *
 * GPIO status:
 * GPIO18: output
 * GPIO4: output
 * GPIO5:  input, pulled up, interrupt from rising edge and falling edge
 *
 * Test:
 * Connect GPIO18 with LED
 * Connect GPIO4 with GPIO5
 * Generate pulses on GPIO4, that triggers interrupt on GPIO5 to blink the led.
 *
 */

#define GPIO_LED_IO     13
#define GPIO_TRIGGER_IO 4
#define GPIO_INPUT_IO   5
// 暫時只使用0通道的PWM
#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
// #define PWM_1_OUT_IO_MUX PERIPHS_IO_MUX_MTDO_U
// #define PWM_1_OUT_IO_NUM 15
// #define PWM_1_OUT_IO_FUNC FUNC_GPIO15
// #define PWM_2_OUT_IO_MUX PERIPHS_IO_MUX_MTCK_U
// #define PWM_2_OUT_IO_NUM 13
// #define PWM_2_OUT_IO_FUNC FUNC_GPIO13
// #define PWM_3_OUT_IO_MUX PERIPHS_IO_MUX_GPIO4_U
// #define PWM_3_OUT_IO_NUM 4
// #define PWM_3_OUT_IO_FUNC FUNC_GPIO4
// #define PWM_4_OUT_IO_MUX PERIPHS_IO_MUX_GPIO5_U
// #define PWM_4_OUT_IO_NUM 5
// #define PWM_4_OUT_IO_FUNC FUNC_GPIO5
#define PWM_CHANNEL 1   // 只使用了一個通道的PWM

static void app_trigger_low_action(void *arg);
static void app_trigger_high_action(void *arg);

gpio_dev_t led;
gpio_dev_t trigger;
gpio_dev_t input;

static void gpio_isr_handler(void* arg)
{
    uint32_t gpio_num = (uint32_t) arg;
    uint32_t value = 0;
    hal_gpio_input_get(&input, &value);
    hal_gpio_output_toggle(&led);
    LOG("GPIO[%d] intr, val: %d\n", gpio_num, value);
} 

/** 呼吸燈執行程式 */
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的佔空比 */
    printf("set_duty>>>%d\r\n", set_duty);
    pwm_set_duty( set_duty, 0 );
    pwm_start();
}

static void app_trigger_low_action(void *arg)
{
    hal_gpio_output_low(&trigger);
    aos_post_delayed_action(100, app_trigger_high_action, NULL);

    ESP8266_PWM_RUN(); // 放到這裡,如同定時器的效果一樣。
}

static void app_trigger_high_action(void *arg)
{
    hal_gpio_output_high(&trigger);
    aos_post_delayed_action(100, app_trigger_low_action, NULL);
}


/** 初始化PWM配置、系統定時器配置 */
void ESP8266_PWM_Init( void )
{
    struct pwm_param pwm_config_t;

    uint32_t 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},
        // {PWM_3_OUT_IO_MUX,PWM_3_OUT_IO_FUNC,PWM_3_OUT_IO_NUM},
        // {PWM_4_OUT_IO_MUX,PWM_4_OUT_IO_FUNC,PWM_4_OUT_IO_NUM},
    };

   pwm_config_t.duty[ 0 ] = 0;
   pwm_config_t.freq = 0;
   pwm_config_t.period = 100;

    pwm_init( pwm_config_t.period, pwm_config_t.duty, PWM_CHANNEL, 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 );
}

int application_start(int argc, char *argv[])
{
    ESP8266_PWM_Init();  // PWM 初始化

    /* gpio port config */
    led.port = GPIO_LED_IO;
    /* set as output mode */
    led.config = OUTPUT_PUSH_PULL;
    /* configure GPIO with the given settings */
    hal_gpio_init(&led);

    /* gpio port config */
    trigger.port = GPIO_TRIGGER_IO;
    /* set as output mode */
    trigger.config = OUTPUT_PUSH_PULL;
    /* configure GPIO with the given settings */
    hal_gpio_init(&trigger);

    /* input pin config */
    input.port = GPIO_INPUT_IO;
    /* set as interrupt mode */
    input.config = IRQ_MODE;
    /* configure GPIO with the given settings */
    hal_gpio_init(&input);

    /* gpio interrupt config */
    hal_gpio_enable_irq(&input, IRQ_TRIGGER_BOTH_EDGES, gpio_isr_handler, (void *) GPIO_INPUT_IO);

    aos_post_delayed_action(1000, app_trigger_low_action, NULL);
    aos_loop_run();

    return 0;
}

報錯:是毫無意外的

1、PERIPHS_IO_MUX_MTDI_U 這個找不到,沒定義(賊多錯誤,滿屏都是)。。。。 解決辦法:在路徑:AliOS-Things-master\AliOS-Things-master\platform\mcu\esp8266\bsp\include\driver\gpio.h這個地方在gpio.h裡面新增如下包含標頭檔案,即可搞定:

#ifndef __GPIO_H__
#define __GPIO_H__

#ifdef __cplusplus
extern "C" {
#endif

/****開始複製****/
#include "c_types.h"
#include "../espressif/esp8266/gpio_register.h"
#include "../espressif/esp8266/pin_mux_register.h"
/*****結束複製****/

#define GPIO_Pin_0              (BIT(0))  /* Pin 0 selected */

編譯:aos make [email protected] 搞定!下載程式之後就可以看到效果了! 注意是引腳是:GPIO12

下載程式:

在路徑這裡系統自帶了三個檔案:AliOS-Things-master\AliOS-Things-master\platform\mcu\esp8266,需要同時下載到ESP8266裡面去,具體地址配置下面有截圖。

  • blank.bin
  • boot_v1.7.bin
  • esp_init_data_default.bin 在這裡插入圖片描述

對應地址:

檔名 下載地址
blank.bin 0xFE000
esp_init_data_default.bin 0xFC000
boot_v1.7.bin 0x00000
[email protected] 0x01000

在這裡插入圖片描述

在目錄這裡:AliOS-Things-master\AliOS-Things-master\out\[email protected]\binary有編譯出來的主檔案。 在這裡插入圖片描述