esp8266学习笔记(4)——pwm(呼吸灯)

流水灯就不搞了,直接呼吸灯吧,8266有现成的pwm驱动文件,直接调用他的接口就可以了。有一个要注意的是不能和硬件定时器同时用,因为它们共⽤了同⼀个硬件定时器。PWM 不⽀持进⼊ Deep sleep 模式,也请勿调用wifi_set_sleep_type(LIGT_SLEEP); 将⾃动睡眠模式设置为 Light-sleep。因为 Lightsleep 在睡眠期间会停 CPU,停 CPU 期间不能响应 NMI 中断。
这里是用pwm接口和软件定时器实现一个呼吸灯。

pwm 模块

  • pwm各通道的 GPIO 硬件参数配置
uint32	io_info[][3]	= {{PERIPHS_IO_MUX_MTDI_U,FUNC_GPIO12,12},};//可同时配置多通道,这里就用一个通道。
  • 各通道初始pwm
uint32 pwm_duty[1]= {0};
  • pwm初始化
pwm_init(1000,pwm_duty,1,io_info);//周期1000us,也就是1khz的频率,单通道初始占空比0

定时器回调函数

void pwm_run(void)
{
	static uint16 duty=0;//占空比
	static flag=false;//变化标志位
	if(duty<=0)
	{
		duty=0;
		flag=false;
	}
	else if(duty>=22200)
	{
		duty=22200;
		flag=true;
	}
	if(!flag)
	{
		duty+=555;
	}
	else
		duty-=555;
	os_printf("duty=%d\n",duty);
	pwm_set_duty(duty,0);//设置占空比,通道0
	pwm_start();//设置完成后,需要调用 pwm_start
}

说明一下这个占空比的算法,8266里面 duty 的范围随PWM 周期改变,最⼤值为: Period * 1000 /45。例如, 1KHz PWM, duty 范围是: 0 ~ 22222。这里一个定时器周期是50ms,呼吸灯一个周期为2s。
整个程序

//==================================================================================
#include "user_config.h"		// 用户配置
#include "driver/uart.h"  		// 串口
#include "c_types.h"			// 变量类
#include "eagle_soc.h"			// GPIO函数、宏定义
#include "ets_sys.h"			// 回调函数
#include "os_type.h"			// os_XXX
#include "osapi.h"  			// os_XXX、软件定时器
#include "user_interface.h" 	// 系统接口、system_param_xxx接口、WIFI、RateContro
#include "pwm.h"
//==================================================================================

os_timer_t timer;
// 毫秒延时函数
//===========================================
void ICACHE_FLASH_ATTR delay_ms(u32 C_time)
{	for(;C_time>0;C_time--)
		os_delay_us(1000);
}
//===========================================
void pwm_run(void)
{
	static uint16 duty=0;
	static flag=false;
	if(duty<=0)
	{
		duty=0;
		flag=false;
	}
	else if(duty>=22200)
	{
		duty=22200;
		flag=true;
	}
	if(!flag)
	{
		duty+=555;
	}
	else
		duty-=555;
	os_printf("duty=%d\n",duty);
	//设置占空比
	pwm_set_duty(duty,0);
  //设置完成后,需要调用 pwm_start
	pwm_start();
}

void ICACHE_FLASH_ATTR user_init(void)
{
	//uart_init(115200,115200);	// 初始化串口波特率
	//os_delay_us(10000);			// 等待串口稳定
	os_printf("download time:%s %s",__DATE__,__TIME__);
	//pwm硬件配置及占空比初始化设置
	uint32 pwm_duty[1]= {0};
	uint32	io_info[][3]	= {{PERIPHS_IO_MUX_MTDI_U,FUNC_GPIO12,12},};
	//pwm初始化
	pwm_init(1000,pwm_duty,1,io_info);
	
    os_timer_disarm(&timer);
    //定时器回调函数
	os_timer_setfn(&timer,(ETSTimerFunc *)pwm_run,NULL);
    //定时器开始。
	os_timer_arm(&timer,50,1);

}
//=================================================================================================


/******************************************************************************
 * FunctionName : user_rf_cal_sector_set
 * Description  : SDK just reversed 4 sectors, used for rf init data and paramters.
 *                We add this function to force users to set rf cal sector, since
 *                we don't know which sector is free in user's application.
 *                sector map for last several sectors : ABCCC
 *                A : rf cal
 *                B : rf init data
 *                C : sdk parameters
 * Parameters   : none
 * Returns      : rf cal sector
*******************************************************************************/
uint32 ICACHE_FLASH_ATTR user_rf_cal_sector_set(void)
{
    enum flash_size_map size_map = system_get_flash_size_map();
    uint32 rf_cal_sec = 0;

    switch (size_map) {
        case FLASH_SIZE_4M_MAP_256_256:
            rf_cal_sec = 128 - 5;
            break;

        case FLASH_SIZE_8M_MAP_512_512:
            rf_cal_sec = 256 - 5;
            break;

        case FLASH_SIZE_16M_MAP_512_512:
        case FLASH_SIZE_16M_MAP_1024_1024:
            rf_cal_sec = 512 - 5;
            break;

        case FLASH_SIZE_32M_MAP_512_512:
        case FLASH_SIZE_32M_MAP_1024_1024:
            rf_cal_sec = 1024 - 5;
            break;

        case FLASH_SIZE_64M_MAP_1024_1024:
            rf_cal_sec = 2048 - 5;
            break;
        case FLASH_SIZE_128M_MAP_1024_1024:
            rf_cal_sec = 4096 - 5;
            break;
        default:
            rf_cal_sec = 0;
            break;
    }

    return rf_cal_sec;
}

void ICACHE_FLASH_ATTR user_rf_pre_init(void){}

你可能感兴趣的:(esp8266学习笔记)