AiPi-Eyes-S1是安信可开源团队专门为Ai-M61-32S设计的一款开发板,支持WiFi6、BLE5.3。所搭载的Ai-M61-32S 模组具有丰富的外设接口,具体包括 DVP、MJPEG、Dispaly、AudioCodec、USB2.0、SDU、以太网 (EMAC)、SD/MMC(SDH)、SPI、UART、I2C、I2S、PWM、GPDAC、GPADC、ACOMP 和 GPIO 等。
AiPi-Eyes-S1集成了SPI屏幕接口,DVP摄像头接口,外置ES8388音频编解码芯片以及预留TF卡座,并且引出USB接口,可接入USB摄像头。
从零开始学习小安派:
PWM 是英文“Pulse Width Modulation”的缩写,简称脉宽调制。一般 IO 口输出是高低电平,是数字信号,电压是以 1 或 0 的重复脉冲来模拟负载,我们可以通过对一个脉冲信号的高低电平时间控制来将数字信号模拟成模拟电压信号,这也是 PWM 最大的用处。总结下来就是,通过一个周期内改变占空比的方式来改变输出的有效电压。下面普及几个 PWM 的概念。
PWM 频率: 一秒钟内,信号完整的从高电平到低电平的次数(完整的一个脉冲周期),单位是 Hz。1Hz 也就是一秒钟一个脉冲周期,周期是 1000ms。
PWM 周期: 周期=1/频率,也就是周期与频率互为倒数,单位一般是 ms,若频率为 5Hz,周期也就是 1/5=0.2S=200ms。
PWM 占空比: 一个脉冲周期内,高电平的时间占整个周期时间的比例。单位是 %,高电平时间是 50ms,周期是 100ms。占空比就是 50/100*100%=50%。
小安派使用的 M61 模组是 BL618 芯片,基于 LHAL 库只支持 PWM_V2,该 PWM 版本支持四个 PWM 通道。
PWM V2 版本输出有效极性。当正向通道阈值位于设置的低阈值和高阈值之间,为有效极性,如果设置有效极性为高,则输出高电平,反之输出低电平。反向通道相反,阈值位于设置的低阈值和高阈值之外,为有效极性,如果设置有效极性为高,则输出高电平,反之输出低电平。
#define PWM_POLARITY_ACTIVE_LOW 0
#define PWM_POLARITY_ACTIVE_HIGH 1
1.struct bflb_pwm_v2_config_s
说明:pwm_v2 初始化配置结构体
struct bflb_pwm_v2_config_s {
uint8_t clk_source;
uint16_t clk_div;
uint16_t period;
};
parameter | description |
clk_source | 时钟源选择:PBCLK or XCLK or 32K_CLK |
clk_div | 分频值 |
period | 周期值 |
PWM 最终产生的频率为 clk_source/clk_div/period
2.struct bflb_pwm_v2_channel_config_s
说明:pwm_v2 通道初始化配置结构体
struct bflb_pwm_v2_channel_config_s {
uint8_t positive_polarity;
uint8_t negative_polarity;
uint8_t positive_stop_state;
uint8_t negative_stop_state;
uint8_t positive_brake_state;
uint8_t negative_brake_state;
uint8_t dead_time;
};
parameter | description |
positive_polarity | 正向输出极性 |
negative_polarity | 反向输出极性 |
positive_stop_state | 正向输出空闲状态 |
negative_stop_state | 反向输出空闲状态 |
positive_brake_state | 正向输出刹车状态 |
negative_brake_state | 反向输出刹车状态 |
dead_time | 死区时间 |
3.bflb_pwm_v2_init
说明:初始化 pwm。使用之前需要选择 gpio 为 pwm 功能。
void bflb_pwm_v2_init(struct bflb_device_s *dev, const struct bflb_pwm_v2_config_s *config);
parameter | description |
dev | 设备句柄 |
config | 配置项 |
4.bflb_pwm_v2_deinit
说明: 复位 pwm。
void bflb_pwm_v2_deinit(struct bflb_device_s *dev);
parameter | description |
dev | 设备句柄 |
5.bflb_pwm_v2_start
说明: 启动 pwm 输出。
void bflb_pwm_v2_start(struct bflb_device_s *dev);
parameter | description |
dev | 设备句柄 |
6.bflb_pwm_v2_stop
说明: 关闭 pwm 输出。
void bflb_pwm_v2_stop(struct bflb_device_s *dev);
parameter | description |
dev | 设备句柄 |
7.bflb_pwm_v2_set_period
说明: 修改 pwm 周期值,从而更改 pwm 输出的频率。
void bflb_pwm_v2_set_period(struct bflb_device_s *dev, uint16_t period);
parameter | description |
dev | 设备句柄 |
period | 周期值 |
8.bflb_pwm_v2_channel_init
说明: PWM 通道初始化。
void bflb_pwm_v2_channel_init(struct bflb_device_s *dev, uint8_t ch, struct bflb_pwm_v2_channel_config_s *config);
parameter | description |
dev | 设备句柄 |
ch | 通道号 |
config | 通道配置 |
9.bflb_pwm_v2_channel_set_threshold
说明: 设置 PWM 占空比。
void bflb_pwm_v2_channel_set_threshold(struct bflb_device_s *dev, uint8_t ch, uint16_t low_threhold, uint16_t high_threhold);
parameter | description |
dev | 设备句柄 |
ch | 通道号 |
low_threhold | 低阈值 |
high_threhold | 高阈值,需要大于 low_threhold,并且小于等于 period |
PWM 占空比=(high_threhold - low_threhold)/period
10.bflb_pwm_v2_channel_positive_start
说明: PWM 正向通道使能输出。
void bflb_pwm_v2_channel_positive_start(struct bflb_device_s *dev, uint8_t ch);
parameter | description |
dev | 设备句柄 |
ch | 通道号 |
11.bflb_pwm_v2_channel_negative_start
说明: PWM 反向通道使能输出。
void bflb_pwm_v2_channel_negative_start(struct bflb_device_s *dev, uint8_t ch);
parameter | description |
dev | 设备句柄 |
ch | 通道号 |
12.bflb_pwm_v2_channel_positive_stop
说明: PWM 正向通道停止输出。
void bflb_pwm_v2_channel_positive_stop(struct bflb_device_s *dev, uint8_t ch);
parameter | description |
dev | 设备句柄 |
ch | 通道号 |
13.bflb_pwm_v2_channel_negative_stop
说明: PWM 反向通道停止输出。
void bflb_pwm_v2_channel_negative_stop(struct bflb_device_s *dev, uint8_t ch);
parameter | description |
dev | 设备句柄 |
ch | 通道号 |
14.bflb_pwm_v2_int_enable
说明: PWM 中断使能和关闭。
void bflb_pwm_v2_int_enable(struct bflb_device_s *dev, uint32_t int_en, bool enable);
parameter | description |
dev | 设备句柄 |
int_en | 中断使能位 |
enable | 是否开启中断 |
int_en 可以填入以下值,多个中断可以使用 | 连接:
#define PWM_INTEN_CH0_L (1 << 0)
#define PWM_INTEN_CH0_H (1 << 1)
#define PWM_INTEN_CH1_L (1 << 2)
#define PWM_INTEN_CH1_H (1 << 3)
#define PWM_INTEN_CH2_L (1 << 4)
#define PWM_INTEN_CH2_H (1 << 5)
#define PWM_INTEN_CH3_L (1 << 6)
#define PWM_INTEN_CH3_H (1 << 7)
#define PWM_INTEN_PERIOD (1 << 8)
#define PWM_INTEN_BRAKE (1 << 9)
#define PWM_INTEN_REPT (1 << 10)
15.bflb_pwm_v2_get_intstatus
说明:获取 PWM 中断标志。
uint32_t bflb_pwm_v2_get_intstatus(struct bflb_device_s *dev);
parameter | description |
dev | 设备句柄 |
return | 返回中断标志 |
返回值如下:
#define PWM_INTSTS_CH0_L (1 << 0)
#define PWM_INTSTS_CH0_H (1 << 1)
#define PWM_INTSTS_CH1_L (1 << 2)
#define PWM_INTSTS_CH1_H (1 << 3)
#define PWM_INTSTS_CH2_L (1 << 4)
#define PWM_INTSTS_CH2_H (1 << 5)
#define PWM_INTSTS_CH3_L (1 << 6)
#define PWM_INTSTS_CH3_H (1 << 7)
#define PWM_INTSTS_PERIOD (1 << 8)
#define PWM_INTSTS_BRAKE (1 << 9)
#define PWM_INTSTS_REPT (1 << 10)
16.bflb_pwm_v2_int_clear
说明: 清除 PWM 中断标志。
void bflb_pwm_v2_int_clear(struct bflb_device_s *dev, uint32_t int_clear);
parameter | description |
dev | 设备句柄 |
int_clear | 清除值 |
int_clear 可以填入以下参数:
#define PWM_INTCLR_CH0_L (1 << 0)
#define PWM_INTCLR_CH0_H (1 << 1)
#define PWM_INTCLR_CH1_L (1 << 2)
#define PWM_INTCLR_CH1_H (1 << 3)
#define PWM_INTCLR_CH2_L (1 << 4)
#define PWM_INTCLR_CH2_H (1 << 5)
#define PWM_INTCLR_CH3_L (1 << 6)
#define PWM_INTCLR_CH3_H (1 << 7)
#define PWM_INTCLR_PERIOD (1 << 8)
#define PWM_INTCLR_BRAKE (1 << 9)
#define PWM_INTCLR_REPT (1 << 10)
17.bflb_pwm_v2_feature_control
说明: PWM 其他特性相关控制,一般不常用。
int bflb_pwm_v2_feature_control(struct bflb_device_s *dev, int cmd, size_t arg);
parameter | description |
dev | 设备句柄 |
cmd | 控制字 |
arg | 控制参数 |
return | 负值表示不支持此命令 |
cmd 可以填入以下参数:
#define PWM_CMD_SET_TRIG_ADC_SRC (0x01)
#define PWM_CMD_SET_EXT_BRAKE_POLARITY (0x02)
#define PWM_CMD_SET_EXT_BRAKE_ENABLE (0x03)
#define PWM_CMD_SET_SW_BRAKE_ENABLE (0x04)
#define PWM_CMD_SET_STOP_ON_REPT (0x05)
#define PWM_CMD_SET_REPT_COUNT (0x06)
呼吸灯是 PWM 最常见的例子,非常的简单,首先将频率调好,人眼识别的频率大于 50Hz 时,由于识别不了这么高的闪烁频率,看起来就像常亮一样。总结起来就是:
频率很高时,看不到闪烁,占空比越大,LED 越亮;频率很低时,可看到闪烁,占空比越大,LED 越亮。
所以我们只需要调好频率,在改变占空比的情况下就可以看到 LED 灯亮度变化过程。在一个 while 函数里实现即可。
Main
#include "bflb_mtimer.h"
#include "bflb_pwm_v2.h"
#include "bflb_clock.h"
#include "board.h"
#include