AliOS-Things--ESP8266--PWM输出(三)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28877125/article/details/82901929

本文基于:https://github.com/alibaba/AliOS-Things
在这里插入图片描述
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里面添加

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 blink@esp8266
搞定!下载程序之后就可以看到效果了! 注意是引脚是: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
blink@esp8266 0x01000

在这里插入图片描述

在目录这里:AliOS-Things-master\AliOS-Things-master\out\blink@esp8266\binary有编译出来的主文件。
在这里插入图片描述

改进

 其实,不用那个定时器的效果也是可以的,就如下面这样写,pwm初始化之后就固定输出一个PWM波:

/** 初始化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_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 );

    // 输出一个固定的PWM波
    pwm_set_duty(80, 0 );
    pwm_start();
}

然后还做了一系列的测试:

period(配置) duty(配置) 频率(实际输出) 周期(实际输出) 高脉冲 低脉冲
50 80 19.16KHz 51us 50us 1us
100 80 10KHz 100us 80us 20us
200 80 5KHz 200us 80us 120us
300 80 3.33KHz 300us 80us 220us

经过比较, pwm_config_t.period = 100;是最好的配置参数。

猜你喜欢

转载自blog.csdn.net/qq_28877125/article/details/82901929