PWM是我们常用的外设功能之一,csk6总共有8组pwm输出口。
本节将通过示例演示如何配置 MCU 的 gptchannel2 的 PWM 功能。
运行该代码后, 会在开发板的 PB06 引脚输出频率为1 HZ,占空比为50%的波形。
static int pwm_set_dt ( const struct pwm_dt_spec * spec,
uint32_t period,
uint32_t pulse
)
参数说明
参数 | 说明 |
---|---|
spec | 设备树中的pwm设备描述 |
period | PWM 周期(以纳秒为单位) |
pulse | PWM 脉冲宽度(以纳秒为单位) |
更多PWM Interface Driver API接口可查看Zephyr官网PWM Interface Driver APIs。
{SDK}\.sdk\csk\samples\driver\pwm
演示如何配置 MCU 的 gptchannel2 的 PWM 功能。运行该代码后, 会在开发板的 PB06 引脚输出频率为 1 HZ,占空比为50%的波形。
适用开发板:大模型开发套件
编译版型:csk6_duomotai_devkit
由于PB_06
引脚在本开发套件上同时复用于SD卡
与网络模组
,其中 SD卡
电路的引脚以排针的形式位于板子上,因此在配置 PWM 功能前,需先将SD_CARD
排针进行短接,如图:
在 SDK 根目录(duomotai_ap
)下可通过执行以下指令进行对该示例工程的编译:
lisa zep build -b csk6_duomotai_devkit .sdk/csk/samples/driver/pwm/ -p
编译完成后,编译产物二进制文件位于 build\zephyr\zephyr.bin
使用 Type-C 数据线连接开发套件的 DAP_USB
接口,选中以下其中一种方式对固件进行烧录:
cskburn desktop
是一款聆思推出的桌面烧录工具,在下载并安装 cskburn desktop 烧录工具后,双击图标运行软件:
1.点击串口下拉框,选择连接开发套件后识别到的串口编号;
2.将编译输出的.bin
文件拖拽进烧录区域;
3.点击开始烧录,等待烧录完成。
若您已按照 《环境搭建》 教程完成开发环境的安装,可在编译完成后执行 lisa zep exec cskburn
指令完成烧录。
lisa zep exec cskburn -s \\.\COMxx -C 6 -b 1500000 0x000000 --verify-all .\build\zephyr\zephyr.bin
请将命令行中的的 COMx 替换为开发套件在 PC 上对应的串口号(可通过设备管理器查看)。例如:
COM3
。
lisa zep exec cskburn -s PORT -C 6 0x000000 --verify-all ./build/zephyr/zephyr.bin -b 1500000
请将命令行中的 PORT 替换为开发套件连接在 PC 上对应的串口号。例如:
/dev/ttyUSB0
。
烧录并将SD_CARD
排针短接完成后,使用示波器连接 SD 卡槽上方排针座的 PB_06
引脚,可观察到该引脚输出的 PWM 波形。
连接 DAP_USB
并使用串口终端连接日志串口,在开发板复位后,也可以看到本示例的日志输出信息:
以下代码与注释已省略一部分非关键接口代码,主要呈现示例的主业务流程与主要接口的使用。
在工程目录 prj.conf
文件中需使能以下模块:
CONFIG_PWM=y
CONFIG_PWM_CSK6=y
boards
目录下设备树文件csk6_duomotai_devkit.overlay
配置如下:
/*
* SPDX-License-Identifier: Apache-2.0
*/
&gptchannel2 {
compatible = "listenai,csk-pwm";
status = "okay";
channel_mode = <1>; /* 0: timer; 1:pwm */
clock-prescaler = <128>;
pinctrl-0 = <&pinctrl_pwm2_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 = <&gptchannel2 2 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
};
};
};
pinctrl_pwm2_default
的定义在.sdk\csk\boards\arm\csk6_duomotai_devkit\csk6_duomotai_devkit_pinctrl.dtsi
中:
pinctrl_pwm2_default: pwm2_default{
pinctrls = <GPT_PWM_2_GPIOB_06>;
};
pwms 设备树配置说明:
字段 | 说明 |
---|---|
inter_pwm(第一个) | pwms 设备树的 node label,可通过 node label 获取 pwms设备树的配置信息 |
inter_pwm(第二个) | pwms 设备树的 node id,可通过 node id获取 pwms设备树的配置信息 |
pwms = <&gptchannel2 2 PWM_MSEC(20) PWM_POLARITY_NORMAL>; | &gptchannel2 :pwm_2 2:通道 PWM_POLARITY_NORMAL: pwm 引脚 flag |
如果需要修改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)
- 如果需要修改 pwm 对应引脚,可以在应用目录的
boards\csk6_duomotai_devkit.overlay
中添加 pwm 引脚定义,覆盖开发板版型(.sdk\csk\boards\arm\csk6_duomotai_devkit\csk6_duomotai_devkit.dts
)默认的pwm 引脚配置。- 此外,需要确定引脚定义是否跟其他的功能引脚有冲突,最直接的办法是在编译的结果产物中查看是否有重复的引脚定义:
build\zephyr\zephyr.dts
。
如果您想了解更多关于设备树的信息,请学习设备树章节。
1.从设备树中定义的 inter_pwm 节点获取 PWM 设备的配置信息
const struct pwm_dt_spec spec = PWM_DT_SPEC_GET(DT_NODELABEL(inter_pwm));
2.检查 PWM 设备是否就绪
device_is_ready()
3.调用 pwm_set_dt 函数设置 PWM 的周期和脉冲宽度为周期的一半,产生 50% 的占空比
pwm_set_dt(&spec, max_period, max_period / 2U);
按下开发板复位按钮,运行程序,可用示波器观察 PB06 引脚输出的波形。
int 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){}
return 0;
}