本帖最后由 Ai-Thinker小泽 于 2023-8-5 17:39 编辑
一、工程搭建
1.工程文件搭建
这里我建的文件夹名称是AiPi_Eyes_DU,刚建立的工程是没有工程文件的,我们需要进入芯片的SDK拉取examples中的demo文件来进行二次开发。本示例使用PWM来作为演示,所以我们需要拉取PWM的demo文件。
依次打开如下文件夹aithinker_Ai-M6X_SDK——>examples——>peripherals——>pwm_v2——>pwm_basic
复制pwm_basic下的所有文件,可以按住ctrl依次点击所有文件,复制并粘贴到我们刚刚建立的文件夹当中。
2.工程编译环境搭建
将工程文件复制过来只是第一步,还需要修改编译和烧录的工作路径。
(1)修改CmakeLists.txt
将project后的括号中的参数改成我们工程文件夹的名字
(2)修改flash_prog_cfg.ini
添加如下信息,注意[FW]中的编译名称,与工程文件夹一致
[boot2]
filedir = ./build/build_out/boot2_*.bin
address = 0x000000
[partition]
filedir = ./build/build_out/partition*.bin
address = 0xE000
[FW]
filedir = ./build/build_out/AiPi_Eyes_DU_$(CHIPNAME).bin
address = @partition
(3)修改Makefile
这一步最为关键,需要设置正确的编译路径到SDK,这里的路径要根据当前文件位置设置,在后期的工程文件复杂的情况下,要确保能最终链接到芯片的SDK
至此,工程文件夹和编译环境就已经搭建完成了,我们的功能初始化和功能都在main文件中实现。
二、PWM呼吸灯功能实现
1.查看原理图和规格书
AiPi_Eyes_DU的原理图可以在嘉立创开源工程中查看:AiPi-Eyes-DU - 嘉立创EDA开源硬件平台
看到RGB三色灯分别由IO15、IO12和IO14控制。
在M61芯片的模组规格书中可以看到这三个IO口都支持PWM0
安信可官网Ai-M61-32S模组规格书:ai-m61-32s_v1.1.0.pdf
2.初始化PWM和GPIO
首先在头文件中添加bflb_gpio.h头文件
创建两个句柄为pwm和gpio,方便后续初始化函数的传参。
定义pwm_v2类型的结构体。
/*创建两个句柄*/
struct bflb_device_s *pwm;
struct bflb_device_s *gpio;
/*句柄赋值相应的类型,这些类型的芯片已经提供好,gpio为gpio,pwm使用pwm-v2*/
pwm = bflb_device_get_by_name("pwm_v2_0");
gpio = bflb_device_get_by_name("gpio");
/*初始化RGB灯,IO15、12、14,对应蓝灯、红灯、绿灯*/
bflb_gpio_init(gpio, GPIO_PIN_15, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
bflb_gpio_init(gpio, GPIO_PIN_12, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
bflb_gpio_init(gpio, GPIO_PIN_14, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
/*该结构体为pwm_v2,成员分别为选择时钟类型,分频因子,计数值*/
struct bflb_pwm_v2_config_s cfg = {
.clk_source = BFLB_SYSTEM_XCLK,
.clk_div = 40,
.period = 255,
};
3.改变占空比调节RBG灯亮度
先认识一个函数,该函数可以调节占空比,第一个参数为任务句柄,这里是"pwm",第二个参数为输出的通道,第三个参数为减数,设为0方便后续调节百分比,第四个参数为被减数。该函数的作用是,(被减数-减数)/计数值 100。如减数设置为0,被减数设置为500,计数值设置为1000,得到的占空比为(500-0)/1000 100%,既为50%的占空比。
void bflb_pwm_v2_channel_set_threshold(struct bflb_device_s *dev, uint8_t ch, uint16_t low_threhold, uint16_t high_threhold)
了解该函数后,可以在while里做逻辑处理实现呼吸灯效果。
这里附上完整的main.c代码。
#include "bflb_mtimer.h"
#include "bflb_pwm_v2.h"
#include "bflb_clock.h"
#include "bflb_gpio.h"
#include "board.h"
struct bflb_device_s *pwm;
struct bflb_device_s *gpio;
#define PWM_PERIOD_MAX 255
int main(void)
{
int i;
board_init();
pwm = bflb_device_get_by_name("pwm_v2_0");
gpio = bflb_device_get_by_name("gpio");
/*初始化RGB灯,IO15、12、14,对应蓝灯、红灯、绿灯*/
bflb_gpio_init(gpio, GPIO_PIN_15, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
bflb_gpio_init(gpio, GPIO_PIN_12, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
bflb_gpio_init(gpio, GPIO_PIN_14, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
/* period = .XCLK / .clk_div / .period = 40MHz / 40 / 1000 = 1KHz */
struct bflb_pwm_v2_config_s cfg = {
.clk_source = BFLB_SYSTEM_XCLK,
.clk_div = 40,
.period = PWM_PERIOD_MAX ,
};
/*初始化PWM输出*/
bflb_pwm_v2_init(pwm, &cfg);
bflb_pwm_v2_start(pwm);
/*功能实现,红、绿、蓝灯依次呼吸循环亮灭*/
while (1) {
//红灯呼吸亮灭
bflb_pwm_v2_channel_positive_start(pwm, PWM_CH0);//使能红灯通道
for(i=0;i<PWM_PERIOD_MAX ;i++)
{
bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH0, 0, i);
bflb_mtimer_delay_ms(5);
}
for(i=PWM_PERIOD_MAX ;i>0;i--)
{
bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH0, 0, i);
bflb_mtimer_delay_ms(5);
}
bflb_pwm_v2_channel_positive_stop(pwm, PWM_CH0);//失能红灯通道
//绿灯呼吸亮灭
bflb_pwm_v2_channel_positive_start(pwm, PWM_CH2);//使能绿灯通道
for(i=0;i<PWM_PERIOD_MAX ;i++)
{
bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH2, 0, i);
bflb_mtimer_delay_ms(5);
}
for(i=PWM_PERIOD_MAX ;i>0;i--)
{
bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH2, 0, i);
bflb_mtimer_delay_ms(5);
}
bflb_pwm_v2_channel_positive_stop(pwm, PWM_CH2);//失能绿灯通道
//蓝灯循环亮灭
bflb_pwm_v2_channel_positive_start(pwm, PWM_CH3);//使能蓝灯通道
for(i=0;i<PWM_PERIOD_MAX ;i++)
{
bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH3, 0, i);
bflb_mtimer_delay_ms(5);
}
for(i=PWM_PERIOD_MAX ;i>0;i--)
{
bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH3, 0, i);
bflb_mtimer_delay_ms(5);
}
bflb_pwm_v2_channel_positive_stop(pwm, PWM_CH3);//失能蓝灯通道
}
}
效果展示
编译和烧录
//编译命令
make
//每次进入工程时,需要cd进入aithinker_Ai-M6X_SDK里输入. /export.sh 确保编译路径正确
//下载命令
make flash COMX=/dev/ttyUSB0
//使用Type-C线连接TTL-USB进入烧录模式方法如下:
//命令下发后,长按Burn键(S2),烧录开始后即可松开Burn键(S2)
效果展示