OpenHarmony(鸿蒙南向)——平台驱动指南【PWM】

news2024/9/27 5:29:59

往期知识点记录:

  • 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
  • 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~
  • 持续更新中……

概述

功能简介

PWM即脉冲宽度调制(Pulse Width Modulation)的缩写,是一种对模拟信号电平进行数字编码并将其转换为脉冲的技术。

PWM接口定义了操作PWM设备的通用方法集合,包括:

  • PWM设备句柄获取和释放
  • PWM周期、占空比、极性的设置
  • PWM使能和关闭
  • PWM配置信息的获取和设置

基本概念

脉冲是“电脉冲”的简称,指电路中电流或电压短暂起伏的现象,其特点是突变和不连续性。脉冲的种类很多,常见的脉冲波形有:三角脉冲、尖脉冲、矩形脉冲、方形脉冲、梯形脉冲及阶梯脉冲等。脉冲的主要参数包括重复周期T(T=1/F,F为重复频率)、脉冲幅度U、脉冲前沿上升时间ts、后沿下降时间t、脉冲宽度tk等。

运作机制

在HDF框架中,PWM接口适配模式采用独立服务模式(如图1所示)。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDF设备管理器的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。

独立服务模式下,核心层不会统一发布一个服务供上层使用,因此这种模式下驱动要为每个控制器发布一个服务,具体表现为:

  • 驱动适配者需要实现HdfDriverEntry的Bind钩子函数以绑定服务。

  • device_info.hcs文件中deviceNode的policy字段为1或2,不能为0。

PWM模块各分层作用:

  • 接口层提供打开PWM设备、设置PWM设备周期、设置PWM设备占空时间、设置PWM设备极性、设置PWM设备参数、获取PWM设备参数、使能PWM设备、禁止PWM设备、关闭PWM设备的接口。

  • 核心层主要提供PWM控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互。

  • 适配层主要是将钩子函数的功能实例化,实现具体的功能。

图 1 PWM独立服务模式结构图

使用指导

场景介绍

通常情况下,在使用马达控制、背光亮度调节时会用到PWM模块。

接口说明

PWM模块设备属性如表1所示,PWM模块提供的主要接口如表2所示,具体API详见//drivers/hdf_core/framework/include/platform/pwm_if.h。

表 1 PwmConfig结构体介绍

名称描述
dutyuint32_t类型,占空时间,以纳秒为单位。
perioduint32_t类型,PWM周期,以纳秒为单位。
numberuint32_t类型,要生成的方波数:
- 正值:表示将生成指定数量的方波
- 0:表示方波将不断产生
polarityuint8_t类型,极性:正极性/反极性。
statusuint8_t类型,状态:启用状态/禁用状态。

表 2 PWM驱动API接口功能介绍

接口名接口描述
DevHandle PwmOpen(uint32_t num)打开PWM设备
void PwmClose(DevHandle handle)关闭PWM设备
int32_t PwmSetPeriod(DevHandle handle, uint32_t period)设置PWM设备周期
int32_t PwmSetDuty(DevHandle handle, uint32_t duty)设置PWM设备占空时间
int32_t PwmSetPolarity(DevHandle handle, uint8_t polarity)设置PWM设备极性
int32_t PwmEnable(DevHandle handle)使能PWM设备
int32_t PwmDisable(DevHandle handle)禁用PWM设备
int32_t PwmSetConfig(DevHandle handle, struct PwmConfig *config)设置PWM设备参数
int32_t PwmGetConfig(DevHandle handle, struct PwmConfig *config)获取PWM设备参数

说明:
本文涉及PWM的所有接口,支持内核态及用户态使用。

开发步骤

使用PWM的一般流程如下图所示。

图 2 PWM使用流程图

获取PWM设备句柄

在操作PWM设备时,首先要调用PwmOpen获取PWM设备句柄,该函数会返回指定设备号的PWM设备句柄。

DevHandle PwmOpen(uint32_t num);

表 3 PwmOpen参数和返回值描述

参数参数描述
numuint32_t类型,PWM设备号

返回值返回值描述
handle打开PWM设备成功,返回PWM设备句柄
NULL打开PWM设备失败

假设系统中的PWM设备号为0,获取该PWM设备句柄的示例如下:

uint32_t num = 0;         // PWM设备号
DevHandle handle = NULL;

handle = PwmOpen(num);    // 打开PWM 0设备并获取PWM设备句柄
if (handle == NULL) {
    HDF_LOGE("PwmOpen: open pwm_%u failed.\n", num);
    return HDF_FAILURE;
}
销毁PWM设备句柄

关闭PWM设备,系统释放对应的资源。

void PwmClose(DevHandle handle);

表 4 PwmClose参数描述

参数参数描述
handleDevHandle类型,PWM设备句柄
PwmClose(handle);    // 关闭PWM设备销毁PWM设备句柄
使能PWM设备
int32_t PwmEnable(DevHandle handle);

表 5 PwmEnable参数和返回值描述

参数参数描述
handleDevHandle类型,PWM设备句柄

返回值返回值描述
HDF_SUCCESS使能PWM设备成功
负数使能PWM设备失败
int32_t ret;

ret = PwmEnable(handle);    // 启用PWM设备
if (ret != HDF_SUCCESS) {
    HDF_LOGE("PwmEnable: enable pwm failed, ret:%d\n", ret);
    return ret;
}
禁用PWM设备
int32_t PwmDisable(DevHandle handle);

表 6 PwmDisable参数和返回值描述

参数参数描述
handleDevHandle类型,PWM设备句柄

返回值返回值描述
HDF_SUCCESS禁用PWM设备成功
负数禁用PWM设备失败
int32_t ret;

ret = PwmDisable(handle);    // 禁用PWM设备
if (ret != HDF_SUCCESS) {
    HDF_LOGE("PwmDisable: disable pwm failed, ret:%d\n", ret);
    return ret;
}
设置PWM设备周期
int32_t PwmSetPeriod(DevHandle handle, uint32_t period);

表 7 PwmSetPeriod参数和返回值描述

参数参数描述
handleDevHandle类型,PWM设备句柄
perioduint32_t类型,要设置的周期,单位为纳秒

返回值返回值描述
HDF_SUCCESS设置PWM设备周期成功
负数设置PWM设备周期失败
int32_t ret;

ret = PwmSetPeriod(handle, 50000000);    // 设置周期为50000000纳秒
if (ret != HDF_SUCCESS) {
    HDF_LOGE("PwmSetPeriod: pwm set period failed, ret:%d\n", ret);
    return ret;
}
设置PWM设备占空时间
int32_t PwmSetDuty(DevHandle handle, uint32_t duty);

表 8 PwmSetDuty参数和返回值描述

参数参数描述
handleDevHandle类型,PWM设备句柄
dutyuint32_t类型,要设置的占空时间,单位为纳秒

返回值返回值描述
HDF_SUCCESS设置PWM设备占空时间成功
负数设置PWM设备占空时间失败
int32_t ret;

ret = PwmSetDuty(handle, 25000000);    // 设置占空时间为25000000纳秒
if (ret != HDF_SUCCESS) {
    HDF_LOGE("PwmSetDuty: pwm set duty failed, ret:%d\n", ret);
    return ret;
}
设置PWM设备极性
int32_t PwmSetPolarity(DevHandle handle, uint8_t polarity);

表 9 PwmSetPolarity参数和返回值描述

参数参数描述
handleDevHandle类型,PWM设备句柄
polarityuint8_t类型,要设置的极性,正/反

返回值返回值描述
HDF_SUCCESS设置PWM设备极性成功
负数设置PWM设备极性失败
int32_t ret;

ret = PwmSetPolarity(handle, PWM_INVERTED_POLARITY);    // 设置极性为反
if (ret != HDF_SUCCESS) {
    HDF_LOGE("PwmSetPolarity: pwm set polarity failed, ret:%d\n", ret);
    return ret;
}
设置PWM设备参数
int32_t PwmSetConfig(DevHandle handle, struct PwmConfig *config);

表 10 PwmSetConfig参数和返回值描述

参数参数描述
handleDevHandle类型,PWM设备句柄
config结构体指针类型,配置参数

返回值返回值描述
HDF_SUCCESS设置PWM设备参数成功
负数设置PWM设备参数失败
int32_t ret;
struct PwmConfig pcfg;

pcfg.duty = 25000000;                     // 占空时间为25000000纳秒
pcfg.period = 50000000;                   // 周期为50000000纳秒
pcfg.number = 0;                          // 不断产生方波
pcfg.polarity = PWM_INVERTED_POLARITY;    // 极性为反
pcfg.status = PWM_ENABLE_STATUS;          // 运行状态为启用

ret = PwmSetConfig(handle, &pcfg);        // 设置PWM设备参数
if (ret != HDF_SUCCESS) {
    HDF_LOGE("PwmSetConfig: pwm set config failed, ret:%d\n", ret);
    return ret;
}
获取PWM设备参数
int32_t PwmGetConfig(DevHandle handle, struct PwmConfig *config);

表 11 PwmGetConfig参数和返回值描述

参数参数描述
handleDevHandle类型,PWM设备句柄
config结构体指针类型,配置参数
返回值返回值描述
HDF_SUCCESS获取PWM设备参数成功
负数获取PWM设备参数失败
int32_t ret;
struct PwmConfig pcfg;

ret = PwmGetConfig(handle, &pcfg);    // 获取PWM设备参数
if (ret != HDF_SUCCESS) {
    HDF_LOGE("PwmGetConfig: pwm get config failed, ret:%d\n", ret);
    return ret;
}

使用实例

下面将基于Hi3516DV300开发板展示使用PWM完整操作,步骤主要如下:

  1. 传入PWM设备号,打开PWM设备并获得PWM设备句柄。

  2. 通过PWM设备句柄及待设置的周期,设置PWM设备周期。

  3. 通过PWM设备句柄及待设置的占空时间,设置PWM设备占空时间。

  4. 通过PWM设备句柄及待设置的极性,设置PWM设备极性。

  5. 通过PWM设备句柄及待获取的设备参数,获取PWM设备参数。

  6. 通过PWM设备句柄,使能PWM设备。

  7. 通过PWM设备句柄及待设置的设备参数,设置PWM设备参数。

  8. 通过PWM设备句柄,禁用PWM设备。

  9. 通过PWM设备句柄,关闭PWM设备。

#include "pwm_if.h"                                               // pwm标准接口头文件
#include "hdf_log.h"                                              // 标准日志打印头文件

static int32_t PwmTestSample(void)
{
    int32_t ret;
    uint32_t num;
    uint32_t period;
    uint32_t duty;
    DevHandle handle = NULL;

    struct PwmConfig pcfg;
    pcfg.duty = 20000000;                                         // 占空时间为20000000纳秒                 
    pcfg.period = 40000000;                                       // 周期为40000000纳秒
    pcfg.number = 100;                                            // 生成100个方波
    pcfg.polarity = PWM_NORMAL_POLARITY;                          // 极性为正
    pcfg.status = PWM_ENABLE_STATUS;                              // 运行状态为启用

    num = 1;                                                      // PWM设备编号,要填写实际平台上的编号

    handle = PwmOpen(num);                                        // 获取PWM设备句柄
    if (handle == NULL) {
        HDF_LOGE("PwmTestSample: open pwm_%u fail!\n", num);
        return HDF_FAILURE;
    }

    period = 50000000;                                            // 设置周期为50000000纳秒
    ret = PwmSetPeriod(handle, period);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("PwmTestSample: pwm set period fail, ret:%d\n", ret);
        goto ERR;
    }

    duty = 25000000;                                              // 设置占空时间为25000000纳秒
    ret = PwmSetDuty(handle, duty);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("PwmTestSample: pwm set duty fail, ret:%d\n", ret);
        goto ERR;
    }

    ret = PwmSetPolarity(handle, PWM_INVERTED_POLARITY);          // 设置极性为反
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("PwmTestSample: pwm set polarity fail, ret:%d\n", ret);
        goto ERR;
    }

    ret = PwmGetConfig(handle, &pcfg);                            // 获取PWM设备参数
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("PwmTestSample: get pwm config fail, ret:%d\n", ret);
        goto ERR;
    }

    ret = PwmEnable(handle);                                      // 启用PWM设备
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("PwmEnable: enable pwm fail, ret:%d\n", ret);
        goto ERR;
    }

    ret = PwmSetConfig(handle, &pcfg);                            // 设置PWM设备参数
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("PwmTestSample: set pwm config fail, ret:%d\n", ret);
        goto ERR;
    }

    ret = PwmDisable(handle);                                     // 禁用PWM设备
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("PwmTestSample: disable pwm fail, ret:%d\n", ret);
        goto ERR;
    }

    HDF_LOGD("PwmTestSample: all tests end.");
ERR:
    PwmClose(handle);                                             // 销毁PWM设备句柄
    return ret;
}

最后

经常有很多小伙伴抱怨说:不知道学习鸿蒙开发哪些技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?

为了能够帮助到大家能够有规划的学习,这里特别整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。

在这里插入图片描述

《鸿蒙 (Harmony OS)开发学习手册》(共计892页):https://gitcode.com/HarmonyOS_MN/733GH/overview

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……

鸿蒙开发面试真题(含参考答案):

在这里插入图片描述

《OpenHarmony源码解析》:

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……
  • 系统架构分析
  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

图片

OpenHarmony 设备开发学习手册:https://gitcode.com/HarmonyOS_MN/733GH/overview

图片
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2169003.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】部署 flask

文章目录 一、安装Python3环境二、将本地开发环境的依赖项目生成清单文件三、创建虚拟环境启用虚拟环境退出虚拟环境 四、添加自定义系统服务(很重要) 一、安装Python3环境 1.首先安装编译环境(后续需要从python官网获取Python3的源码自己编译python yum install zlib-devel …

案例研究丨国控星鲨利用DataEase释放数据潜能,重塑业务视野

国药控股星鲨制药(厦门)有限公司(以下简称为国控星鲨)始创于1952年,前身为厦门鱼肝油厂,距今已经有70余年历史,是国家商务部认定的“中华老字号”企业。2011年,国药控股与厦门轻工集…

C# C++ 笔记

第一阶段知识总结 lunix系统操作 1、基础命令 (1)cd cd /[目录名] 打开指定文件目录 cd .. 返回上一级目录 cd - 返回并显示上一次目录 cd ~ 切换到当前用户的家目录 (2)pwd pwd 查看当前所在目录路径 pwd -L 打印当前物理…

从“可用”到“好用”,百度智能云如何做大模型的“超级工厂”?

如果说,过去两三年大模型处于造锤子阶段,那么今年,更多的则是考验钉钉子的能力,面对各类业务场景大模型是否能够有的放矢、一击必中,为千行百业深度赋能。 当前市场上,已经有200多把这样的锤子在疯狂找钉子…

从零开始使用树莓派debian系统使用opencv4.10.0进行人脸识别(保姆级教程)

一、总体架构 本文主要是使用树莓派自带的csi摄像头,搭配上opencv4.10.0进行物体的识别。本文使用的环境是python3.7.3,环境不一样有可能安装的opencv的过程也会很不一样,但是python的环境我们可以自己自行安装。 二、树莓派系统的安装 本文…

江协科技STM32学习- P19 TIM编码器接口

🚀write in front🚀 🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝​…

亲身体验Llama 3.1:开源模型的部署与应用之旅

文章目录 1 Llama 3.1系列的诞生2 大型模型的未来发展3 使用教程4 Llama 3.1在客户服务中的运用 1 Llama 3.1系列的诞生 在人工智能的浪潮中,大型语言模型(LLM)正以其独特的魅力和潜力,成为深度学习领域的一颗耀眼明星。 这些模…

计算机毕业设计Hadoop+Spark知识图谱体育赛事推荐系统 体育赛事热度预测系统 体育赛事数据分析 体育赛事可视化 体育赛事大数据 大数据毕业设计

《HadoopSpark知识图谱体育赛事推荐系统》开题报告 一、研究背景及意义 随着互联网技术的迅猛发展和大数据时代的到来,体育赛事数据的数量呈爆炸式增长。用户面对海量的体育赛事信息,常常感到信息过载,难以快速找到感兴趣的赛事内容。如何高…

锐捷—NAT地址映射+IPsec隧道

任务目标 在出口路由器R3上将R5私网地址1对1映射的公网地址与R1建立IPsec隧道,使得R4在访问R5的映射公网地址时,可以进行IPsec隧道的转发 要求: 1、R4和R5可通过NAT转换正常访问互联网地址(R2的lo0) 2、R5的私网地…

云手机群控怎么用?有什么优势?

群控系统,顾名思义,是用于批量控制多部手机的工具,能够通过计算机或客户端同时管理多台设备。借助群控系统,用户可以在电脑上操作多部手机,模拟真实操作场景,从而大幅提升工作效率,并有效控制管…

calibre-web默认左上角字体修改

calibre-web默认左上角字体修改 如图: 有些奇异,如果想变成正常的常规字体,需要修改: cps\static\css\style.css 下的代码: 默认是GrandHotel-Regular: 换成其他字体即可。其他字体在 calibre-web\cps\s…

图像处理04

图像处理 问题:把不规则的图片按照参考图摆放 步骤: 1. 用ORB找关键点 2. 关键点匹配 3. 根据上一步匹配的关键点得出单应性矩阵 4. 根据单应性矩阵对不规则进行透视变换 import cv2 import numpy as np import matplotlib.pyplot as pltimgl cv2.imrea…

微信小程序 - 最新详细安装使用 Vant weapp UI 框架环境搭建详细教程

前言 自从 2024 年开始,小程序做了很多改变和升级, 导致网上很多搭建教程文章的教程失效了,本文来做最新的教程。 第一步 为了更贴合新手,我这里创建了一个纯净无任何业务代码的小程序项目。

【AI基础】pytorch lightning 基础学习

传统pytorch工作流是首先定义模型框架,然后写训练和验证,测试循环代码。训练,验证,测试代码写起来比较繁琐。这里介绍使用pytorch lightning 部署模型,加速模型训练和验证,记录。 准备工作 1 安装pytorch…

铨顺宏科技携RTLS+RFID技术亮相工博会!

中国国际工业博览会盛大开幕! 铨顺宏科技展亮点速递 铨顺宏科技展位号:F117 中国国际博览会今日开幕,铨顺宏科技携创新产品亮相,吸引众多参观者。 我们珍视此次国际盛会,将全力以赴确保最佳体验。 工作人员热情解答…

实时数字人DH_live使用案例

参看: https://github.com/kleinlee/DH_live ubuntu 测试 apt install ffmpeg 下载安装: git clone https://github.com/kleinlee/DH_live.git cd DH_liveconda create -n dh_live python=3.12 conda activate dh_live pip install -r requirements.txt pip install torch -…

E. Alternating String

E. Alternating String 这道题就是前缀和的变化, 现在做起来比较简单, 打这场的时候差了点时间就做出来了 代码 #include <bits/stdc.h> #define int long long using namespace std;const int N 200010;int od[N][30], ev[N][30]; int n;void init() {for(int i 0; …

【Linux篇】常用命令及操作技巧(进阶篇 - 上)

&#x1f30f;个人博客主页&#xff1a;意疏-CSDN博客 文章目录&#xff1a; Linux常用命令以及操作技巧&#xff08;进阶&#xff09;前言一、远程管理常用命令1、关机/重启shutdown命令 二、查看或配置网卡信息2、网卡和IP地址网卡IP地址ifconfig命令ping命令 三、SSH基础1.…

Dart中FFI学习

Flutter中FFI学习 Dart FFI编程概述NativeType&#xff08;类型映射&#xff09;Window安装GCCDart调用C的函数数组字符串结构体 Dart FFI编程 概述 dart:ffi库可以使用Dart语言调用本地C语言API ,并读取、写入、分配和删除本地内存。FFI是指外部函数接口&#xff08;Foregin…

JS设计模式之组合模式:打造灵活高效的对象层次结构

引言 当我们构建复杂的应用程序时&#xff0c;经常会遇到处理对象层次结构的情况。这些层次结构通常是树形结构&#xff0c;由组合节点和叶子节点组成。在这样的情况下&#xff0c;JavaScript 设计模式之一的组合模式就能派上用场。 组合模式是一种结构型设计模式&#xff0c…