#创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现 原创 精华
FFH杞人
 发布于 2023-3-21 09:27
 浏览
 6收藏
【本文正在参加2023年第一期优质创作者激励计划】
标准系统HDF平台驱动(三)——ADC应用实现
个人简介:
深圳技术大学FSR实验室大三学生,正于九联科技实习,共同学习研究鸿蒙南向开发知识。
博客主页:https://ost.51cto.com/person/posts/15624680
@[toc]
前言
前面两篇文章已经实现了ADC的HDF框架接入,现在已经可以正常调用HDF提供的ADC统一驱动接口进行应用开发。结合之前学的一些知识,设计一个基于NAPI框架和HDF框架读取温度传感器数据的程序应用。
![#创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区 #创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区](https://dl-harmonyos.51cto.com/images/202303/32c624a30c1c0069dd3257acc58c6957abb4ed.png?x-oss-process=image/resize,w_820,h_1280)
参考
平台驱动使用
标准系统HDF平台驱动(一)——ADC驱动适配
标准系统HDF平台驱动(二)——ADC平台驱动使用
环境
- OpenHarmony-3.2-Beta5
 - 九联UnionPi-Tiger开发板
 - Visual Studio Code(版本需1.62.0及以上)
 - USB_Burning_Tool烧录工具
 - napi_generator工具可执行文件或vs code插件
 - Deveco Studio(API 9 )
 - LM35线性模拟温度传感器
 
概述
开发步骤
一. 编译构建实现
- 添加子系统
 
  "napisubsys":{
    "path":"vendor/unionman/unionpi_tiger/sample/napi/napisubsys",
    "name":"napisubsys"
  }
- 添加组件
打开unionpi_tiger/sample/napi/napisubsys/ohos.build文件,在"parts":中添加下列语句 
        "adc_hdf": {
            "variants": [
                "phone"
            ],
            "module_list": [
                "//vendor/unionman/unionpi_tiger/sample/napi/napisubsys/adc_hdf:adc_hdf"
            ]
        }
- 添加产品定义
打开vendor/unionman/unionpi_tiger/config.json文件,在"subsystems":中添加下列语句 
    {
      "subsystem": "napisubsys",
      "components": [
        {
          "component": "adc_hdf",
          "features": []
        }
      ]
    },
二. NAPI接口设计及NAPI框架生成
- 编写ts文件
新建文件@ohos.adc_hdf.d.ts于vendor/unionman/unionpi_tiger/sample/napi/napisubsys/adc_hdf目录下,声明应用接口函数get_adc_value,传入参数为通道号,返回值为ADC采样值,北向应用通过调用该接口获取的ADC采样值计算温度。 
declare namespace adc_hdf {
    function get_adc_value(channel: number): number;
}
export default adc_hdf;
- 生成NAPI框架
使用napi_generator可执行程序或者vscode插件生成NAPI框架。
![#创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区 #创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区](https://dl-harmonyos.51cto.com/images/202303/c3a3728060a745e8f9c6112bce4ec3f38532eb.png?x-oss-process=image/resize,w_379,h_485)
生成框架路径也选择当前路径,number类型选择uint32_t。
![#创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区 #创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区](https://dl-harmonyos.51cto.com/images/202303/c9ba6f0033488ad0771133761a48c54145580d.png?x-oss-process=image/resize,w_596,h_476)
 
三. NAPI接口实现
- 实现adc_hdf.cpp接口
文件生成结束后,我们定义的北向应用接口需要在adc_hdf.cpp中实现,具体代码如下: 
#include "adc_hdf.h"
#include "adc_if.h"
#include "hdf_log.h"
#include <cstdio>
namespace adc_hdf {
bool get_adc_value(NUMBER_TYPE_1& channel, NUMBER_TYPE_2& out)
{
    int32_t ret;
    DevHandle adcHandle = NULL;
    uint32_t read_val = 0;
    /* 打开ADC设备 */ 
    adcHandle = AdcOpen(ADC_DEVICE_NUM);
    if (adcHandle == NULL) {
        printf("%s: Open ADC%u fail!", __func__, ADC_DEVICE_NUM);
        return false;
    }
    /* 读取ADC采样值 */ 
    ret = AdcRead(adcHandle, (uint32_t)channel, &read_val);
    if (ret != HDF_SUCCESS) {
        printf("%s: ADC read fail!:%d", __func__, ret);
        AdcClose(adcHandle);
        return false;
    }
    /* 结果返回值 */ 
    out = (NUMBER_TYPE_2)read_val;
    printf("ADC read:%d\r\n",read_val);
    /* 访问完毕关闭ADC设备 */ 
    AdcClose(adcHandle);
    return true;
}
}
- 修改BUILD.gn文件
主要添加了ADC平台驱动所需依赖及头文件路径,并且修改目标子系统及所属部件,编译后会生成相应的.so共享库文件,存放在/system/lib/module目录下。 
import("//build/ohos.gni")
ohos_shared_library("adc_hdf")
{
    sources = [
        "adc_hdf_middle.cpp",
        "adc_hdf.cpp",
        "tool_utility.cpp",
    ]
    include_dirs = [
        ".",
        "//third_party/node/src",
        "//drivers/hdf_core/framework/include/platform"
    ]
    deps=[
        "//foundation/arkui/napi:ace_napi",
        "//drivers/hdf_core/adapter/uhdf2/platform:libhdf_platform"
    ]
    external_deps = [
    "hdf_core:libhdf_utils",
    "hiviewdfx_hilog_native:libhilog",
    ]
    remove_configs = [ "//build/config/compiler:no_rtti" ]
    cflags=[
    ]
    cflags_cc=[
        "-frtti",
    ]
    ldflags = [
    ]
    
    relative_install_dir = "module"
    part_name = "adc_hdf"
    subsystem_name = "napisubsys"
}
四. 编译打包烧录
- 进入源码根目录,执行如下命令进行编译:
 
./build.sh --product-name unionpi_tiger
- 编译完成后需要打包成可以给开发板烧录的镜像,执行一下命令:
 
./device/board/unionman/unionpi_tiger/common/tools/packer-unionpi.sh
- 固件打包完成,生成路径为编译根目录下的
out/unionpi_tiger/packages/phone/images/OpenHarmony.img,下载或映射到Windows上进行烧录。 - 打开烧录工具,连接PC与开发板OTG口并接通电源,导入烧录包进行烧录。
 
![#创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区 #创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区](https://dl-harmonyos.51cto.com/images/202303/09d7f9943e6181db6534684c440ec79027677f.png?x-oss-process=image/resize,w_820,h_683)
或者使用hdc_std工具:
hdc_std shell mount -o remount,rw /
hdc_std file send libadc_hdf.z.so /system/lib/module/
五. NAPI应用实现
- 
新建OpenHarmony工程(stage+ArkTs)
![#创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区 #创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区](https://dl-harmonyos.51cto.com/images/202303/290d34085171fa55e094856c69d0cabba34137.png?x-oss-process=image/resize,w_820,h_658)
 - 
导入外部接口
adc_hdf为上述定义NAPI接口生成的动态库文件名字一致,直接导入会报找不到包,忽略即可,prompt为弹窗组件接口。 
// @ts-ignore
import adc_hdf from '@ohos.adc_hdf';
import prompt from '@system.prompt'
- ADC通道选择组件(使用Swiper滑块视图容器实现)
新建滑块视图数据类 
class MyDataSource implements IDataSource {
  private list: string[] = []
  private listener: DataChangeListener
  constructor(list: string[]) {
    this.list = list
  }
  totalCount(): number {
    return this.list.length
  }
  getData(index: number): any {
    return this.list[index]
  }
  registerDataChangeListener(listener: DataChangeListener): void {
    this.listener = listener
  }
  unregisterDataChangeListener() {
  }
}
Swiper滑块视图容器组件,滑动或点击可以切换ADC通道,点击select进行数据采集。
//通道选择组件实现
@Component
struct channel_chose {
  private swiperController: SwiperController = new SwiperController()
  private data: MyDataSource = new MyDataSource([])
  private channelNum: number = 2
  private tmp: number = 1
  @Link channel: number
//导入轮播内容
  aboutToAppear(): void {
    let list = []
    for (var i = 1; i <= this.channelNum; i++) {
      list.push('ADC_' + i.toString());
    }
    this.data = new MyDataSource(list)
  }
  build() {
    Column({ space: 5 }) {
      Swiper(this.swiperController) {
        LazyForEach(this.data, (item: string) => {
          Text(item)
            .borderRadius(10)
            .width('80%')
            .height(70)
            .fontColor('#ff1a5ea4')
            .fontWeight(FontWeight.Bolder)
            .textAlign(TextAlign.Center)
            .fontSize(30)
        }, item => item)
      }
      .cachedCount(2)
      .interval(4000)
      .indicator(false)
      .duration(1000)
      .itemSpace(10)
      .vertical(true)
      .curve(Curve.Linear)
      .onChange((index: number) => {
        this.tmp = index + 1
      })
      Row({ space: 12 }) {
        Button('Change').backgroundColor('#ff366fb1').fontSize(20).height(50).width(120)
          .onClick(() => {
            this.swiperController.showNext()
          })
        Button('Select').backgroundColor('#ff366fb1').fontSize(20).height(50).width(120)
          .onClick(() => {
            this.channel = this.tmp;
            prompt.showToast({ message: 'Select data From ADC_'+this.channel.toString() })
            console.info('Select data From Channel_'+this.channel.toString())
          })
      }.margin(20)
    }.width('50%')
  }
}
- 文本组件显示温度值
 
@Component
struct show_temperature{
  @Link temperature: Number
  build(){
    Text(this.temperature.toFixed(1)+'°C')
      .width('50%')
      .fontSize(60)
      .fontColor(Color.White)
      .fontStyle(FontStyle.Italic)
      .textAlign(TextAlign.Center)
      .fontWeight(FontWeight.Bold)
  }
}
- 温度计算及首页内容组件,程序启动时开启定时器,每隔1s获取一次ADC温度值。
 
@Entry
@Component
struct Index {
  @State channel: number = 1
  @State adc_val: number = 0
  @State temperature: number = 0
  private  timerId: number = -1
  //获取温度传感器ADC采样值并计算温度
  private get_adc_value() {
    let get_value = adc_hdf.get_adc_value(this.channel-1);
    if (get_value <= 1500) {
      this.adc_val = get_value;
      this.temperature = (this.adc_val / 4096) * 1.8 * 100;
    }
    else {
      this.temperature = 0
      prompt.showToast({
        message: "获取失败,请检查连线", // 显示文本
        duration: 1000, // 显示时长
      })
    }
  }
  //程序运行时开启定时器Interval,每隔一秒调用get_adc_value更新温度值
  aboutToAppear(): void {
    this.timerId = setInterval(() => {
      this.get_adc_value()
    }, 1000)
  }
  //销毁定时器
  aboutToDisappear() {
    if (this.timerId > 0) {
      clearTimeout(this.timerId)
      this.timerId = -1
    }
  }
  build() {
    Row() {
      show_temperature({temperature: $temperature})
      Column({space:0}){
        channel_chose({channel:$channel})
      }.height('80%')
    }.height('100%')
    .backgroundImage($r('app.media.bg')).backgroundImageSize(ImageSize.Cover)
  }
}
- 应用签名
![#创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区 #创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区](https://dl-harmonyos.51cto.com/images/202303/880b436576be6c0b814179fdf9f0f3b5d2a5e4.png?x-oss-process=image/resize,w_820,h_681)
![#创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区 #创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区](https://dl-harmonyos.51cto.com/images/202303/c8f3878750427285cad4623230f5d080aa223a.png?x-oss-process=image/resize,w_820,h_642)
 - 安装应用到开发板
![#创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区 #创作者激励# [FFH]标准系统HDF平台驱动(三)——ADC应用实现-鸿蒙开发者社区](https://dl-harmonyos.51cto.com/images/202303/37504df55387a13348d810ef55377a740acc4f.png?x-oss-process=image/resize,w_673,h_161)
 
结果演示
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
   adc_temperature.zip 88.47K 20次下载  
已于2023-3-21 10:53:21修改
 
        赞
        10
 
        收藏 6
      
 回复
  相关推荐
 




















完整的一次打通南北过程
有了插件果然方便不少
点灯和测温总是拿到开发板最先完成的工作
学习了。
流程分享的很完整