ESP8266 PWM 接口参考

1. 概述

    PWM 的特性如下所示。 

  • 使用 NMI (Non Maskable Interrupt) 中断,更加精确
  • 可扩展最多8路PWM信号
  • >14bit分辨率,最小分辨率45ns
  • 无需配置寄存器,调用函数接口即可完成配置。

    1.2 实现方式

ESP8266 系统提供了一种经过优化的软件算法,通过在FRC1定时器上挂载NMI,实现在 GPIO 端口输出多组 PWM 信号。PWM 的时钟源由高速系统时钟提供,其频率高达 80MHz。PWM 通过预分屏16分频,其输入时钟频率为 5MHz。PWM 通过 FRC1 来产生粗调定时,结合高速系统时钟的微调,可将分辨率提高到 45ns。

说明: NMI 拥有最高中断优先级,可以保证 PWM 输出波形的准确度。

    1.3 配置说明

  • 在定时中断内,为尽快退出程序只在每次PWM周期开始时载入下一个周期的定时参数
  • 设置完各个通道的占空比后,系统会调用 pwm_start() 函数来计算定时周期。在此之前系统会进行保护操作,即保存当前的各通道参数,并清除计算完成标志, PWM 周期到来会使用保存后的参数。
  • PWM 周期中断后会使用新的参数,因此计算完成后需要设置标志为。这样在实现占空比渐进(如控制RGB 彩灯)的过程中,能保证颜色平滑过渡。
  • 可在 user_light.h 中配置采用的 GPIO。SDK代码示例使用 5 路 PWM,实际可以自行扩展,最多扩展至 8  路 PWM。最小分辨率 45ns, 频率在 1KHz 时,占空比最小可以达到 1/22222。

  1.4 参数说明

  • 最小分辨率:45ns (近似对应于硬件 PWM 的输入时钟频率为 22.72MHz): >14bit PWM @ 1 KHz
  • PWM 周期:1000us (1KHz) ~ 10000us (100Hz)

2. PWM.h 详解

 

  2.1 代码示例

#ifndef __PWM_H__
#define __PWM_H__
#define PWM_CHANNEL_NUM_MAX    8        // 最多 8 路 PWM
struct pwm_single_param                 // 定义单个 PWM 通道参数结构体
{
    uint16 gpio_set;                    // 需要置位的 GPIO
    uint16 gpio_clear;                  // 需要清零的 GPIO
    uint32 h_time;                      // 需要写入 FRC1_LOAD 寄存器的计数值
};
struct pwm_param                        // 定义 PWM 参数结构体
{
    uint32 period;                      // PWM 周期
    uint32 freq;                        // PWM 频率
    uint32 duty[PWM_CHANNEL_NUM_MAX];   // PWM 占空比
};
void pwm_init(uint32 period, uint32 *duty, uint32 pwm_channel_num, uint32(*pin_info_list)[3]);
void pwm_start(void);
void pwm_set_duty(uint32 duty, uint8 channel);
uint32 pwm_get_duty(uint8 channel);
void pwm_set_freq(uint32 period);
uint32 pwm_get_freq(void);

  2.2 接口说明

名称:pwm_init
含义:PWM 初始化
示例:pwm_init(uint32 freq, uint32 *duty, uint32 pwm_channel_num, uint32 (*pin_info_list)[3]);
描述:PWM GPIO, 参数和定时器初始化
参数:
    uint32 freq: PWM 的周期
    uint32 *duty: 各通道占空比参数
    uint32 pwm_channel_num: PWM 通道数。
    uint32 (*pin_info_list)[3]: PWM 各通道的 GPIO 硬件参数,该参数是一个 n*3 的数组指针。数组中定义了 GPIO 的寄存器,对应 PIN 脚的 IO 复用值,和 GPIO 对应的序号。
例如:初始化一个 3 通道的 PWM。
    uint32 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_init(light_param.pwm_period, light_param.pwm_duty, 2, io_info);
调用:系统初始化时调用。目前只能调用一次。
返回值:无
名称:pwm_set_period
含义:设置 PWM 周期
示例:pwm_set_period(uint32 period)
描述:设置 PWM 周期,单位 us。
     例如:1KHz PWM, 参数为 1000us.
参数:uint32 period:PWM 周期
调用:设置完成后需要嗲用 pwm_start() 才起作用。
返回值:无
名称:pwm_set_duty
含义:设置 PWM 某个通道信号的占空比
代码示例:pwm_set_duty(uint32 duty, uint8 channel);
描述:设置 PWM 占空比。设置各路 PWM 信号高电平所占的时间,duty 的范围随 PWM 周期改变。最大值为:period * 1000 / 45 (以1KHz为例:duty 范围是 0 ~ 22222)。
参数说明:uint32 duty:设置高电平参数,占空比的值为(duty * 45) / (period * 1000).
         uint8 channel:当前要设置的 PWM 通道,在 PWM_CHANNEL 定义的范围内。
调用:设置完成后需要调用 pwm_start() 才起作用。
返回值:无
名称:pwm_get_period
描述:获取当前 PWM 周期
代码示例:pwm_get_period(void)
参数说明:无
返回值:PWM 周期,单位us.
名称:pwm_get_duty
描述:获取对应 channel 的当前 PWM 信号的 duty 参数。
代码示例:pwm_get_duty(uint8 channel)
参数说明:uint8 channel:当前要获取的 PWM 的通道,在 PWM_CHANNEL 定义的范围内
调用:设置完成后需要调用pwm_start()才起作用。
返回值:channel对应的通道的占空比,占空比的值为 (duty * 45) / (period * 1000)。
名称:pwm_start
描述:PWM 更新参数
代码示例:pwm_start(void);
参数说明:无
调用:PWM 相关参数设置完成后,需要调用 pwm_start() 才起作用
返回值:无

3. 自定义通道

用户还可以增加 PWM 通道,如增加 GPIO4 为 PWM 输出的第四通道,设置步骤如下所示。

1. 修改初始化参数。
    uint32 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_init(light_param.pwm_period, light_param.pwm_duty, PWM_CHANNEL, io_info);
2. 修改 user_light.h 文件
    #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             5

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值