本文档提供将PWM功能移植到新系统的完整流程指南,基于CSK6系列芯片的PWM实现。CSK6总共有8组pwm输出口。
本节将通过示例演示如何配置 MCU 的 gptchannel1 的 PWM 功能移植内容包括设备树配置、驱动接口调用和硬件连接注意事项。
运行该代码后, 会在开发板的 PA01 引脚输出频率为1 HZ,占空比为50%的波形,并且能够运行大模型系统。
static int pwm_set_dt ( const struct pwm_dt_spec * spec,
uint32_t period,
uint32_t pulse
)
{SDK}\duomotai_ap\apps\LLM_pic
目标开发板:大模型开发套件
编译版型:csk6_duomotai_devkit
示波器(用于波形验证)
首先我们需要查询本开发板还剩余哪些空闲的可用引脚,可通过聆思文档(https://docs2.listenai.com/x/nTn9kMMCU)进行查询如图:
打开开发板配套的引脚功能分配表 60xx_iomux_v1.0.xlsx (鼠标右键链接另存为)即可查看
查找表中标注为PWM功能的引脚,找到本实例的引脚描述,如图:
查看该引脚的列确定通道号:
PWM1
→ 通道1也就是后续下面代码头需使用的&gptchannel1
其中的 1 就指向通道1
在工程目录 prj.conf
文件中需使能以下模块:
CONFIG_PWM=y
CONFIG_PWM_CSK6=y
在apps\LLM_pic\boards\csk6_duomotai_devkit.overlay
目录下增加这段代码:
&gptchannel1 {
compatible = "listenai,csk-pwm";
status = "okay";
channel_mode = <1>; /* 0: timer; 1:pwm */
clock-prescaler = <128>;
pinctrl-0 = <&pinctrl_pwm1_default>;
pinctrl-names = "default";
};
/{
pwms {
compatible = "pwm-leds";
inter_pwm: inter_pwm {
/* PWM LED will conflict with User LED1 since using the same gpio pin */
pwms = <&gptchannel1 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
};
};
};
pinctrl_pwm1_default
的定义在.sdk\csk\boards\arm\csk6_duomotai_devkit\csk6_duomotai_devkit_pinctrl.dtsi
中:
pinctrl_pwm1_default: pwm1_default {
pinctrls = <GPT_PWM_1_GPIOA_01>; // PA01对应PWM通道1
};
如果需要修改pwm引脚或通道,可在SDK的.sdk\csk\dts\arm\csk\csk6-pinctrl.h
文件中查看可使用的IO口,该文件定义了芯片所有IO口可用外设功能,开发者仅需要选择对应的IO即可,例如:
// pwm
#define GPT_PWM_0_GPIOA_00 CSK6_PINMUX(a, 0, 11)
#define GPT_PWM_1_GPIOA_01 CSK6_PINMUX(a, 1, 11)
#define GPT_PWM_2_GPIOA_02 CSK6_PINMUX(a, 2, 11)
#define GPT_PWM_3_GPIOA_03 CSK6_PINMUX(a, 3, 11)
#define GPT_PWM_4_GPIOA_04 CSK6_PINMUX(a, 4, 11)
#define GPT_PWM_5_GPIOA_05 CSK6_PINMUX(a, 5, 11)
#define GPT_PWM_6_GPIOA_06 CSK6_PINMUX(a, 6, 11)
#define GPT_PWM_7_GPIOA_07 CSK6_PINMUX(a, 7, 11)
#define GPT_PWM_0_GPIOA_08 CSK6_PINMUX(a, 8, 11)
#define GPT_PWM_1_GPIOA_09 CSK6_PINMUX(a, 9, 11)
#define GPT_PWM_2_GPIOA_10 CSK6_PINMUX(a, 10, 11)
#define GPT_PWM_3_GPIOA_11 CSK6_PINMUX(a, 11, 11)
#define GPT_PWM_4_GPIOA_12 CSK6_PINMUX(a, 12, 11)
#define GPT_PWM_5_GPIOA_13 CSK6_PINMUX(a, 13, 11)
#define GPT_PWM_6_GPIOA_14 CSK6_PINMUX(a, 14, 11)
#define GPT_PWM_7_GPIOA_15 CSK6_PINMUX(a, 15, 11)
#define GPT_PWM_0_GPIOA_16 CSK6_PINMUX(a, 16, 11)
#define GPT_PWM_1_GPIOA_17 CSK6_PINMUX(a, 17, 11)
#define GPT_PWM_2_GPIOA_18 CSK6_PINMUX(a, 18, 11)
#define GPT_PWM_3_GPIOA_19 CSK6_PINMUX(a, 19, 11)
#define GPT_PWM_4_GPIOA_20 CSK6_PINMUX(a, 20, 11)
#define GPT_PWM_0_GPIOB_00 CSK6_PINMUX(b, 0, 11)
#define GPT_PWM_7_GPIOB_01 CSK6_PINMUX(b, 1, 11)
#define GPT_PWM_6_GPIOB_02 CSK6_PINMUX(b, 2, 11)
#define GPT_PWM_5_GPIOB_03 CSK6_PINMUX(b, 3, 11)
#define GPT_PWM_4_GPIOB_04 CSK6_PINMUX(b, 4, 11)
#define GPT_PWM_3_GPIOB_05 CSK6_PINMUX(b, 5, 11)
#define GPT_PWM_2_GPIOB_06 CSK6_PINMUX(b, 6, 11)
#define GPT_PWM_1_GPIOB_07 CSK6_PINMUX(b, 7, 11)
#define GPT_PWM_0_GPIOB_08 CSK6_PINMUX(b, 8, 11)
#define GPT_PWM_7_GPIOB_09 CSK6_PINMUX(b, 9, 11)
#define GPT_PWM_6_GPIOB_10 CSK6_PINMUX(b, 10, 11)
#define GPT_PWM_5_GPIOB_11 CSK6_PINMUX(b, 11, 11)
找到主函数路径.sdk\apps\LLM_pic\src\main.c
增加第一段代码,此代码作用是从设备树中获取标签为inter_pwm的节点所配置的PWM信息(包括使用哪个PWM控制器、哪个通道、初始周期和极性等),并将这些信息保存到一个结构体变量spec中,以便后续使用(例如,调用pwm_set_dt()函数时直接传入这个结构体)。
/*pwm函数结构体定义 */
#define max_period PWM_MSEC(1U)
const struct pwm_dt_spec spec = PWM_DT_SPEC_GET(DT_NODELABEL(inter_pwm));
增加第二段代码到主函数main(void)中:
if (!device_is_ready(spec.dev)) {
printk("device: %s is not ready\n", spec.dev->name);
return 0;
}
printk("name: %s \n", spec.dev->name);
printk("channel: %d \n", spec.channel);
printk("period: %d \n", spec.period);
printk("flag: %d \n", spec.flags);
if(pwm_set_dt(&spec, max_period, max_period / 2U) == 0){
printk("pwm_set_dt success\n");
}
//k_sleep(K_SECONDS(4U));
//while(1){}
k_sleep(K_FOREVER);
return 0;
模块 | 功能描述 | 关键接口 | 实现效果 |
---|---|---|---|
设备就绪检查 | 验证PWM硬件是否可用 | device_is_ready() |
防止操作未初始化硬件导致系统崩溃 |
配置信息输出 | 调试设备树参数 | printk() |
输出设备名、通道号、周期值和标志位 |
PWM参数设置 | 配置波形参数 | pwm_set_dt() |
设置1Hz周期和50%占空比 |
系统挂起 | 维持PWM持续输出 | k_sleep(K_FOREVER) |
低功耗状态下保持PWM输出 |
在 SDK 根目(duomotai_ap
)下可通过执行以下指令进行对该示例工程的编译:
lisa zep build -b csk6_duomotai_devkit apps\LLM_pic -p
编译完成后,编译产物二进制文件位于 build\zephyr\zephyr.bin
使用 Type-C 数据线连接开发套件的DAP_USB
接口,选中以下其中一种方式对固件进行烧录:
cskburn desktop
是一款聆思推出的桌面烧录工具,在下载并安装 cskburn desktop
烧录工具后,双击图标运行软件:
1.点击串口下拉框,选择连接开发套件后识别到的串口编号;
2.将编译输出的.bin文件拖拽进烧录区域;
3.点击开始烧录,等待烧录完成。