当前文档版本为 v0.8.0,您可以访问当前页面的 开发中 版本以获取最近可能的更新。

Driver: PWM & RGB

1 功能概述

本文主要介绍PAN1080 EVB板RGB灯控制,定时改变RGB灯的颜色,演示外设PWM的使用。

2 环境要求

  • PAN1080 EVB 一块

  • USB-TypeC 线一条(用于供电和查看串口打印 Log)

  • 硬件接线:

    • 使用 USB 线,将 PC USB 与 EVB USB-TypeC(USB->UART)相连

    • 根据 EVB 核心板芯片的封装不同,使用杜邦线将 EVB 底板上的:

      • TX0 与 P00 相连, RX0 与 P01 相连(若 EVB 板芯片为 QFN32 或 LQFP64 封装)

      • TX0 与 P30 相连, RX0 与 P31 相连(若 EVB 板芯片为 QFN48 封装)

  • PC 软件: 串口调试助手(UartAssist)或终端工具(SecureCRT),波特率921600

3 编译和烧录

例程位置:zephyr\samples_panchip\drivers\pwm\pwm_rgb

使用 ZAL 工具可以对其进行编译、烧录、打开 VS Code 调试等操作。关于 ZAL 工具的详细介绍请参考:Zephyr APP Launcher 工具介绍

4 演示说明

  1. PAN1080 EVB板GPIO P10、P11、P16与RGB电路用跳线帽连接。

  2. EVB板上电灯的颜色默认是白色,然后灯在红、绿、蓝三种颜色1s间隔切换一次 。

5 开发说明

5.1 启用PWM模块

在prj.conf文件中添加“CONFIG_PWM=y”启用pwm模块。

CONFIG_PWM=y

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

在“pan108xxb5_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了。

6 RAM/Flash资源使用情况

Memory region         Used Size  Region Size  %age Used
FLASH:       20796 B       256 KB      7.93%
SRAM:        4248 B        64 KB      6.48%