基于小凌派RK2206开发板:OpenHarmony如何使用IoT接口控制PWM外设 原创

福州市凌睿智捷电子有限公司
发布于 2025-4-9 09:40
9016浏览
0收藏

1、案例简介

本案例是在小凌派-RK2206开发板上使用IoT库PWM接口,进行PWM编程开发。

例程将创建一个任务,每隔5秒将PWM0~10依次启用,输出1000Hz。

例程源代码:https://gitee.com/Lockzhiner-Electronics/lockzhiner-rk2206-openharmony3.0lts/tree/master/vendor/lockzhiner/rk2206/samples/b16_iot_pwm

2、基础知识

PWM在日常设备中非常常见,以下我们将演示IoT库的PWM接口如何进行PWM控制。

2.1、头文件

base/iot_hardware/peripheral/interfaces/kits/iot_pwm.h
  • 1.

2.2、初始化PWM设备:IoTPwmInit

unsigned int IoTPwmInit(unsigned int port);
  • 1.

描述:

初始化PWM设备。

参数:

参数 类型 描述
port unsigned int PWM端口号

其中,port对应于如下表所示:

port GPIO
0 GPIO_PB4
1 GPIO_PB5
2 GPIO_PB6
3 GPIO_PC0
4 GPIO_PC1
5 GPIO_PC2
6 GPIO_PC3
7 GPIO_PC4
8 GPIO_PC5
9 GPIO_PC6
10 GPIO_PC7

返回值:

返回值 描述
IOT_SUCCESS 成功
IOT_FAILURE 失败

实现:

hal_iot_pwm.c文件在device/rockchip/rk2206/adapter/hals/iot_hardware/wifiiot_lite目录下。

unsigned int IoTPwmInit(unsigned int port)
{
    unsigned int ret = 0;

    if (port >= EPWMDEV_MAX) {
        PRINT_ERR("port(%d) >= EPWMDEV_MAX(%d)\n", port, EPWMDEV_MAX);
        return IOT_FAILURE;
    }

    PinctrlSet(m_pwm_bus_info[port].pwm_bus.pwm.gpio,
        m_pwm_bus_info[port].pwm_bus.pwm.func,
        m_pwm_bus_info[port].pwm_bus.pwm.type,
        m_pwm_bus_info[port].pwm_bus.pwm.drv);
    PwmIoInit(m_pwm_bus_info[port].pwm_bus);
    LzPwmInit(m_pwm_bus_info[port].port);

    return IOT_SUCCESS;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

2.3、取消初始化PWM设备:IoTPwmDeinit

unsigned int IoTPwmDeinit(unsigned int port);
  • 1.

描述:

取消初始化PWM设备。

参数:

参数 类型 描述
port unsigned int PWM端口号

其中,port对应于如下表所示:

port GPIO
0 GPIO_PB4
1 GPIO_PB5
2 GPIO_PB6
3 GPIO_PC0
4 GPIO_PC1
5 GPIO_PC2
6 GPIO_PC3
7 GPIO_PC4
8 GPIO_PC5
9 GPIO_PC6
10 GPIO_PC7

返回值:

返回值 描述
IOT_SUCCESS 成功
IOT_FAILURE 失败

实现:

hal_iot_pwm.c文件在device/rockchip/rk2206/adapter/hals/iot_hardware/wifiiot_lite目录下。

unsigned int IoTPwmDeinit(unsigned int port)
{
    if (port >= EPWMDEV_MAX) {
        PRINT_ERR("port(%d) >= EPWMDEV_MAX(%d)\n", port, EPWMDEV_MAX);
        return IOT_FAILURE;
    }

    LzGpioDeinit(m_pwm_bus_info[port].pwm_bus.pwm.gpio);

    LzPwmDeinit(m_pwm_bus_info[port].port);
  
    return IOT_SUCCESS;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

2.4、开始PWM信号输出:IoTPwmStart

unsigned int IoTPwmStart(unsigned int port, unsigned short duty, unsigned int freq);
  • 1.

描述:

开始PWM信号输出。

参数:

参数 类型 描述
port unsigned int PWM端口号
duty unsigned short 高电平的占空比,范围为1~99
freq unsigned int 频率

其中,port对应于如下表所示:

port GPIO
0 GPIO_PB4
1 GPIO_PB5
2 GPIO_PB6
3 GPIO_PC0
4 GPIO_PC1
5 GPIO_PC2
6 GPIO_PC3
7 GPIO_PC4
8 GPIO_PC5
9 GPIO_PC6
10 GPIO_PC7

返回值:

返回值 描述
IOT_SUCCESS 成功
IOT_FAILURE 失败

实现:

hal_iot_pwm.c文件在device/rockchip/rk2206/adapter/hals/iot_hardware/wifiiot_lite目录下。

unsigned int IoTPwmStart(unsigned int port, unsigned short duty, unsigned int freq)
{
#define DUTY_MIN        1
#define DUTY_MAX        99
#define SEC_TO_NSEC     (1000000000UL)
    unsigned int duty_ns;
    unsigned int cycle_ns;
  
    if (port >= EPWMDEV_MAX) {
        PRINT_ERR("port(%d) >= EPWMDEV_MAX(%d)\n", port, EPWMDEV_MAX);
        return IOT_FAILURE;
    }
    if ((duty < DUTY_MIN) || (DUTY_MAX < duty)) {
        PRINT_ERR("duty(%d) out of the range(%d ~ %d)\n", duty, DUTY_MIN, DUTY_MAX);
        return IOT_FAILURE;
    }
    if (freq == 0) {
        PRINT_ERR("freq(%d) is invalid!\n", freq);
        return IOT_FAILURE;
    }
    if (freq > SEC_TO_NSEC) {
        PRINT_ERR("freq(%d) > SEC_TO_NSEC(%d)\n", freq, SEC_TO_NSEC);
        return IOT_FAILURE;
    }

    cycle_ns = SEC_TO_NSEC / freq;
    duty_ns = cycle_ns * duty / 100;

    LzPwmStart(m_pwm_bus_info[port].port, duty_ns, cycle_ns);

    return IOT_SUCCESS;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.

2.5、停止PWM信号输出:IoTPwmStop

unsigned int IoTPwmStop(unsigned int port);
  • 1.

描述:

停止PWM信号输出。

参数:

参数 类型 描述
port unsigned int PWM端口号

其中,port对应于如下表所示:

port GPIO
0 GPIO_PB4
1 GPIO_PB5
2 GPIO_PB6
3 GPIO_PC0
4 GPIO_PC1
5 GPIO_PC2
6 GPIO_PC3
7 GPIO_PC4
8 GPIO_PC5
9 GPIO_PC6
10 GPIO_PC7

返回值:

返回值 描述
IOT_SUCCESS 成功
IOT_FAILURE 失败

实现:

hal_iot_pwm.c文件在device/rockchip/rk2206/adapter/hals/iot_hardware/wifiiot_lite目录下。

unsigned int IoTPwmStop(unsigned int port)
{
    if (port >= EPWMDEV_MAX) {
        PRINT_ERR("port(%d) >= EPWMDEV_MAX(%d)\n", port, EPWMDEV_MAX);
        return IOT_FAILURE;
    }

    LzPwmStart(m_pwm_bus_info[port].port, 0, 0);

    return IOT_SUCCESS;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

3、程序设计

pwm_example函数中,创建一个任务。

void pwm_example()
{
    unsigned int thread_id;
    TSK_INIT_PARAM_S task = {0};
    unsigned int ret      = LOS_OK;

    task.pfnTaskEntry = (TSK_ENTRY_FUNC)pwm_thread;
    task.uwStackSize  = 2048;
    task.pcName       = "pwm_thread";
    task.usTaskPrio   = 20;
    ret               = LOS_TaskCreate(&thread_id, &task);
    if (ret != LOS_OK) {
        printf("Falied to create pwm_thread ret:0x%x\n", ret);
        return;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

pwm_thread任务中调用IOT库的PWM接口控制PWM。

void pwm_thread()
{
    unsigned int ret;
    /* PWM端口号对应于参考文件:
     * device/rockchip/rk2206/adapter/hals/iot_hardware/wifiiot_lite/hal_iot_pwm.c
     */
    unsigned int port = 0;

    while (1) {
        printf("===========================\n");
        printf("PWM(%d) Init\n", port);
        ret = IoTPwmInit(port);
        if (ret != 0) {
            printf("IoTPwmInit failed(%d)\n");
            continue;
        }

        printf("PWM(%d) Start\n", port);
        ret = IoTPwmStart(port, 50, 1000);
        if (ret != 0) {
            printf("IoTPwmStart failed(%d)\n");
            continue;
        }

        LOS_Msleep(5000);

        printf("PWM(%d) end\n", port);
        ret = IoTPwmStop(port);
        if (ret != 0) {
            printf("IoTPwmStop failed(%d)\n");
            continue;
        }

        ret = IoTPwmDeinit(port);
        if (ret != 0) {
            printf("IoTPwmInit failed(%d)\n");
            continue;
        }

        printf("\n");

        port++;
        if (port >= 11) {
            port = 0;
        }
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.

4、编译调试

修改 vendor/lockzhiner/rk2206/sample 路径下 BUILD.gn 文件,指定 iot_pwm_example 参与编译。

"./b16_iot_pwm:iot_pwm_example",
  • 1.

修改 device/lockzhiner/rk2206/sdk_liteos 路径下 Makefile 文件,添加 -liot_pwm_example 参与编译。

hardware_LIBS = -lhal_iothardware -lhardware -lshellcmd -liot_pwm_example
  • 1.

5、运行结果

示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,任务每隔5s控制不同PWM输出。

entering kernel init...
hilog will init.
[MAIN:D]Main: LOS_Start ...
Entering scheduler
OHOS # hiview init success.===========================
PWM(0) Init
[GPIO:D]LzGpioInit: id 12 is initialized successfully
PWM(0) Start
PWM(0) end
[GPIO:D]LzGpioDeinit: id 12 is released successfully

===========================
PWM(1) Init
[GPIO:D]LzGpioInit: id 13 is initialized successfully
PWM(1) Start
PWM(1) end
[GPIO:D]LzGpioDeinit: id 13 is released successfully
...
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
收藏
回复
举报
回复
    相关推荐
    这个用户很懒,还没有个人简介
    觉得TA不错?点个关注精彩不错过
    帖子
    视频
    声望
    粉丝
    社区精华内容