ESP-12S学习(4)--PWM呼吸灯

一、PWM接口函数的解析
函数1:pwm_init()
初始化PWM,包括GPIO 选择,周期和占空比。目前仅支持调用一次
void pwm_init(
	uint32 period, 
	uint8 *duty, 
	uint32 pwm_channel_num, 
	uint32 (*pin_info_list)[3]
)
参数解释
period周期,单位是us,计算:1KHZ–1s变化1000次,1s/1000 = 1ms = 1000us
duty这是一个指针变量,数组存放PWM的占空比,初始化几个PWM通道,数组就多大
pwm_channel_num初始化的PWM的通道数目
pin_info_list一个n*3的数组指针,数组里面存放了GPIO的寄存器值,PIN脚的IO复用值,GPIO的序列号

看一下pin_info_list数组,例如需要初始化一个PWM通道,是映射在GPIO5

uint32 io_info[1][3] ={PERIPHS_IO_MUX_GPIO5_U,FUNC_GPIO5,5};

PERIPHS_IO_MUX_GPIO5_U:是GPIO5的寄存器地址

可以在EclipseCtrl点击跳转查看,很显然0x40PIN5的偏移地址
在这里插入图片描述
然后对PERIPHS_IO_MUX点击跳转
在这里插入图片描述
IO外设复用基地址,地址有了,接着就是复用功能的选择


FUNC_GPIO5:是复用功能的选择
在这里插入图片描述
同样的在Eclipse里面对FUNC_GPIO5点击跳转
在这里插入图片描述
FUNC_GPIO50,也就是代表着第一个功能,也可以查看一下GPIO12
在这里插入图片描述
FUNC_GPIO123,也就是代表着第4个功能,按照这样的规则,需要复用其他的功能是同样的选择


GPIO5的序列号是GPIO_ID_PIN(5),也就是5


然后调用pwm_init(1000, duty, 1, io_info); 1KHz周期,初始化占空比的数组duty,1通道PWM,和GPIO复用


上述是对一个PWM通道的初始化,如果是需要初始化两个通道,假设是GPIO5GPIO12那么

uint32	duty[2] = {0};
uint32 io_info[2][3] ={
						{PERIPHS_IO_MUX_GPIO5_U,FUNC_GPIO5,5},
						{PERIPHS_IO_MUX_MTDI_U,FUNC_GPIO12,12}
						};

pwm_init(1000, duty, 2, io_info);

函数2:pwm_start()

PWM开始函数,每次对PWM更新(周期、占空比)后都需要调用,初始化之后也是同样的


函数3:pwm_set_duty()

占空比设置函数:duty的值是随PWM周期变化的,SDK手册上说占空比的计算是duty = period*1000/45
在这里插入图片描述
1KHz的周期是1000us,按照计算的公式结果是1000*1000/45 = 22222


函数4:pwm_set_period()

在这里插入图片描述
周期的计算T = 1/f,单位是us


函数5:pwm_get_duty()

获取占空比值
在这里插入图片描述


函数6:pwm_get_period()

获取PWM的周期值
在这里插入图片描述


函数7:get_pwm_version()

获取PWM的版本
在这里插入图片描述


二、PWM呼吸灯

PWM初始化的时候已经将PWM所用的IO口初始化了所以不需要另外去初始化IO

硬件定时器和PWM是冲突的
在这里插入图片描述
所以使用软件定时器,ms级别的软件定时器最小都是5ms,但是我这里使用的是us级别的延时
在这里插入图片描述
us级别的定时器需要宏定义一个USE_US_TIMER,并且在user_main(),的开头调用system_timer_reinit()函数
在这里插入图片描述
USE_US_TIMER宏定义需要在osapi.h的导入之前,否则是会报错没有定义的
在这里插入图片描述
这里是空宏都可以
在这里插入图片描述
可以看到这里使用的是#ifdef,而不是#if


user_main()代码:

void ICACHE_FLASH_ATTR user_main()
{
	system_timer_reinit();

	/*软件定时器*/
	os_timer_disarm(&ledtimer);									// 关闭定时器
	os_timer_setfn(&ledtimer, (os_timer_func_t *)Pwm_Led, (void*)0);	// 设置定时器的回调函数
	os_timer_arm_us(&ledtimer, 1000, 1);					// 打开定时器,1ms,重复

	/*PWM初始化*/
	pwm_init(1000, duty, 1, io_info);
	pwm_start();
}

Pwm_Led代码

/*
 * @name:	Pwm_Led[PwmLED]
 */
void Pwm_Led(void)
{
	if (down_flag == 0)
		led_value += 22;
	if (down_flag)
		led_value -= 22;
	pwm_set_duty(led_value, 0);
	pwm_start();

	if (led_value >= 22220)
		down_flag = 1;
	if (led_value == 0)
			down_flag = 0;
}

为什么是定时1ms,结合起两部分代码来看,首先呼吸灯的话我控制的大概就是10ms增加1%的占空比,0~22222的范围值,1%的占空比是222,我这里一次加22,一次1ms,也就是10ms220这样子

2020.5.28
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值