当前位置: 首页 > news >正文

【Zephyr】02_从零教你开发芯片级ADC驱动(HAL层篇)

文章目录

  • 前言
  • 一、参考官方驱动API
    • 1.1:基础API
    • 1.2:参数结构体
  • 二、功能函数操作逻辑梳理
    • 2.1:系统初始化逻辑:
    • 2.2:ADC配置初始化
    • 2.3:ADC通道配置
    • 2.4:原始数据获取
    • 2.5:校准函数
  • 三、HAL层函数定义
  • 四、HAL层函数验证
    • 4.1:验证方法论
    • 4.2:验证过程
      • 4.2.1:时钟使能(0x401800F0-bit0)
      • 4.2.2:通道使能(0x4018C000)
      • 4.2.2:时钟源分频(0x4018C000-bit30-28)
      • 4.2.3:功能函数验证(0x4018C044)
  • 总结


前言

本文详细记录了Zephyr下ADC驱动开发中硬件抽象层(HAL)的设计与实现过程。HAL层作为连接底层硬件与上层驱动的重要桥梁,其设计质量直接影响驱动的稳定性和可移植性。文档包含HAL层接口设计、功能函数实现、验证方法及结果分析等内容。

一、参考官方驱动API

1.1:基础API

typedef int (*adc_api_channel_setup)(const struct device *dev,const struct adc_channel_cfg *channel_cfg);typedef int (*adc_api_read)(const struct device *dev,const struct adc_sequence *sequence);

重要说明:ADC驱动API有两个功能函数,为保证与官方统一,传入的参数与我们在HAL层头文件定义的结构体相同

  • 通道初始化:adc_api_channel_setup(),需要传入的结构体adc_channel_cfg
  • 数据读取:adc_api_read(),需要传入的结构体adc_sequence

1.2:参数结构体

struct adc_channel_cfg {enum adc_gain gain;           // 增益选择enum adc_reference reference; // 参考电压选择uint16_t acquisition_time;    // 采样时间uint8_t channel_id : 5;       // 通道ID (0-31)uint8_t differential : 1;     // 差分模式标志// 可选字段(根据CONFIG_ADC_CONFIGURABLE_INPUTS)uint8_t input_positive;       // 正输入uint8_t input_negative;       // 负输入(差分模式)
};
struct adc_sequence {const struct adc_sequence_options *options; // 序列选项uint32_t channels;                          // 通道位掩码void *buffer;                               // 数据缓冲区size_t buffer_size;                         // 缓冲区大小uint8_t resolution;                         // 分辨率uint8_t oversampling;                       // 过采样bool calibrate;                             // 校准标志
};

说明:

  • adc_channel_cfg:我们在HAL层需要定义的channel_cfg结构体,仅需考虑acquisition_time和channel_id即可,但需要额外定义结构体,来获取其他参数。
  • adc_sequence:同理在HAL层需要定义的adc_sequence结构体,仅需考虑channels即可,但需要额外定义结构体,来获取其他参数。

二、功能函数操作逻辑梳理

2.1:系统初始化逻辑:

  • 门控clock使能
  • 门控clock复位
  • ADC总线时钟使能
  • Timer使能(中断,延时)

2.2:ADC配置初始化

  • 配置对应GPIO引脚为ADC功能
  • 时钟源选择
  • 时钟分频
  • 必须功能:clean,首次抓换延迟
  • 校准函数
  • 配置ACQ采样时间持续寄存器

2.3:ADC通道配置

  • 根据通道名称,配置对应GPIO引脚
  • 模式选择:暂提供nolmal,单次,连续三种
  • 若为连续模式:配置第11:8位采样时间间隔
  • 启动通道

2.4:原始数据获取

  • 根据指定通道获取数据

2.5:校准函数

  • 校准数据误差,可使用默认值

三、HAL层函数定义

根据针对性的功能函数梳理,我们可以裁剪出以下HAL层函数:

//结构体初始化,将寄存器结构体指针指向基地址
void hal_kadc_module_init(void); 
//时钟源选择与分频
void hal_kadc_clk_div_config(enum adc_ch_clk inclk,uint16_t div_clk);
//校准
void kadc_hal_calibrate(uint32_t pre,bool use_data_en,bool use_mod,bool use_en,uint32_t cal_data);
//采样维持时间
void kadc_hal_acq_time_config(uint32_t acq_time);
//模式配置
void kadc_hal_mode_config(uint16_t channel_id,enum kadc_ch_mode mode,uint16_t continue_mod_time_n);
//通道使能
void kadc_hal_enable(uint16_t channel_id,enum kadc_ch_en en);
//数据获取
uint32_t kadc_hal_get_data(uint16_t channel_id);

四、HAL层函数验证

4.1:验证方法论

在完成HAL层函数的编写,我们不急于马上进行驱动开发,为保证减少驱动层BUG的出现,应先对HAL层进行验证,确认每条函数是否正确将寄存器置位。
常用的验证方法:

  • 应用层:main.c验证函数,且打印函数调用前后的寄存器信息
  • 驱动层:编写Shell指令进行函数验证,且打印函数调用前后的寄存器信息

4.2:验证过程

4.2.1:时钟使能(0x401800F0-bit0)

  • 置位前:
    在这里插入图片描述
  • 置位后:(01)
    在这里插入图片描述
    说明:bit0为使能位,可以验证得时钟使能函数操作正确!

4.2.2:通道使能(0x4018C000)

  • 通道1置位后:(02)
    在这里插入图片描述
    说明:bit1为通道1使能位,各通道对应各bit,可以验证得通道使能函数操作正确!

4.2.2:时钟源分频(0x4018C000-bit30-28)

  • 分频系数:3(30)
    在这里插入图片描述
    说明:bit30:28为分频系数位,可以验证得分频函数操作正确!

4.2.3:功能函数验证(0x4018C044)

  • 3.3V通电状态:
    在这里插入图片描述
    说明:根据寄存器信息,当前ADC捕获值为4084,即当前电压为4084*3.3/4096=3.29V,功能正常!

  • 浮空状态
    在这里插入图片描述
    说明:根据寄存器信息,当前ADC捕获值为1412,即当前电压为1412*3.3/4096=1.13V,功能不正常!待确认。

总结

硬件抽象层(HAL)作为连接底层硬件与上层应用的桥梁,需实现标准化接口与硬件无关性设计。针对ADC模块开发时,需封装设备初始化、通道配置、采样触发、数据读取等基础功能。本文介绍了ADC驱动开发下HAL层开发的思路与验证手段,为后续驱动层开发减少了BUG的出现和调试的困难。

http://www.lryc.cn/news/613371.html

相关文章:

  • 第三章:【springboot】框架介绍MyBatis
  • 恒虚警检测(CFAR)仿真:杂波边缘与多目标场景分析
  • 在新建word中使用以前文件中的列表样式
  • java中override和overload的区别
  • Java 大视界 -- Java 大数据在智能安防门禁系统中的人员行为分析与异常事件预警(385)
  • AR技术:制造业质量控制的“智能革新”
  • Redis最新安装教程(WindowsLinux)
  • Kubernetes(k8s)之Service服务
  • SpringBoot的优缺点
  • 【更新被拒绝,因为推送的一个分支的最新提交落后于其对应的远程分支。】
  • VLMEvalKit使用记录
  • 公开致歉声明
  • P1690 贪婪的 Copy
  • idea工具maven下载报错:PKIX path building failed,配置忽略SSL检查
  • 量子计算入门 | 量子力学的发展
  • 如何将普通HTTP API接口改造为MCP服务器
  • list类
  • SQL注入攻击基础
  • Cookie和Session是什么?有什么区别?
  • 如何开发一个运行在windows系统服务器上的服务
  • 跨学科视域下的深层语义分析与人类底层逻辑一致性探索
  • 性能优化——GPU的影响
  • 基于Matlab图像处理的黄豆自动计数系统设计与实现
  • sklearn study notes[3]
  • Nuxt.js 国际化配置完整教程(含版本兼容与问题解决)
  • 驱动-设备树插件注册子系统
  • 【Bluedroid】蓝牙音频接收端活动设备切换机制深度解析(sink_set_active_device)
  • Maven私服搭建--Nexus-3.82.0 Linux环境
  • mysql基础-聚合函数
  • 二叉树算法之【中序遍历】