Driver: PWM & RGB¶
1 功能概述¶
本文主要介绍PAN1080 EVB板RGB灯控制,定时改变RGB灯的颜色,演示外设PWM的使用。
2 环境要求¶
board: pan1080a_afld_evb
uart (option): 显示串口log
3 编译和烧录¶
项目位置:zephyr\samples_panchip\drivers\pwm\pwm_rgb
统一的配置、编译、下载工具正在开发中,当前可以使用脚本进行编译和下载。
脚本位置:quick_build_samples\drivers\pwm_rgb.bat
。
打开脚本后默认会编译项目,编译完成时,可输入字符进行后续下载等操作:
Input the keyword to continue:
'b' build 编译项目
'r' make clean and rebuild 重新编译项目
'f' flash download 下载
'e' erase chip 擦除芯片
'o' open project by VS Code 打开 `VS Code`,可查看源码,执行编译下载等
others exit 退出
wait input:
4 演示说明¶
PAN1080 EVB板GPIO P10、P11、P16与RGB电路用跳线帽连接。
EVB板上电灯的颜色默认是白色,然后灯在红、绿、蓝三种颜色1s间隔切换一次 。
5 开发说明¶
5.2 初始PWM¶
if (!device_is_ready(led_red)) {
printk("PWM_0 device is not ready\n");
}
if (!device_is_ready(led_green)) {
printk("PWM_1 device is not ready\n");
}
if (!device_is_ready(led_blue)) {
printk("PWM_2 device is not ready\n");
}
5.3 配置PWM¶
在“pan1080a_afld_evb.overlay”文件中添加PWM参数配置:
pwmleds {
compatible = "pwm-leds";
pwm_led_red: pwm_led_r {
pwms = <&pwm0 4 PWM_POLARITY_NORMAL>;
label = "RGB_LED_RED";
};
pwm_led_green: pwm_led_g {
pwms = <&pwm0 5 PWM_POLARITY_NORMAL>;
label = "RGB_LED_GREEN";
};
pwm_led_blue: pwm_led_b {
pwms = <&pwm0 6 PWM_POLARITY_NORMAL>;
label = "RGB_LED_BLUE";
};
};
使用PWM0的4、5、6通道,正向极性,高电平1为有效状态*(active),低电平0为无效状态(inactive)*。
PWM PIN脚配置:
&pwm0 {
pinctrl-0 = <&p1_0_pwm0_ch4 &p1_1_pwm0_ch5 &p1_6_pwm0_ch6>;
status = "okay";
};
配置P10、P11、P16三个引脚为PWM功能。
5.4 PWM输出¶
PWM输出接口
/**
* @brief Set the period and pulse width for a single PWM output.
*
* @param dev Pointer to the device structure for the driver instance.
* @param pwm PWM pin.
* @param period Period (in microseconds) set to the PWM.
* @param pulse Pulse width (in microseconds) set to the PWM.
* @param flags Flags for pin configuration (polarity).
*
* @retval 0 If successful.
* @retval Negative errno code if failure.
*/
static inline int pwm_pin_set_usec(const struct device *dev, uint32_t pwm,
uint32_t period, uint32_t pulse,
pwm_flags_t flags)
{
uint64_t period_cycles, pulse_cycles, cycles_per_sec;
if (pwm_get_cycles_per_sec(dev, pwm, &cycles_per_sec) != 0) {
return -EIO;
}
period_cycles = (period * cycles_per_sec) / USEC_PER_SEC;
if (period_cycles >= ((uint64_t)1 << 32)) {
return -ENOTSUP;
}
pulse_cycles = (pulse * cycles_per_sec) / USEC_PER_SEC;
if (pulse_cycles >= ((uint64_t)1 << 32)) {
return -ENOTSUP;
}
return pwm_pin_set_cycles(dev, pwm, (uint32_t)period_cycles,
(uint32_t)pulse_cycles, flags);
}
配置PWM设备(PWM0、PWM1、PWM2)、通道(0~7)、频率、占空比、极性模式。
调用这个接口后,对应的pin脚就能输出PWM了。