【Ai-WB2中级篇】ADC模数转换

[复制链接]
查看1098 | 回复4 | 2024-8-28 14:15:50 | 显示全部楼层 |阅读模式
模数转换器(analog-to-diaital converter,通常称为ADC)是一种模拟与数字转换器,支持12路外部模拟输入和若干内部模拟信号选择。
Ai-WB2的ADC支持以下四种模式:单次单诵道转换、连续单诵道转换、单次多通道转换和连续多通道转换模式。转换结果为1214116bits左对齐模式。ADC拥有深度为32的FIFO,支持多种中断和DMA操作。 ADC除了用于普通模拟信号测量外,还可以用于测量供电电压,比外ADC还可以通过测量内/外部二极管电压用于温度检测。

本文将详细介绍如何通过Ai-WB2的ADC模块对电位计进行电压采样。

一:ADC介绍
BL602芯片内置一个12bits 的逐次逼近式模拟数字转换器(ADC),支持12 路外部模拟输入和若干内部模拟信号选择。ADC可以工作在单次转换和多通道扫描两种模式下,转换结果为12/14/16bits左对齐模式。ADC 拥有深度为32的FIFO,支持多种中断,支持DMA 操作。ADC 除了用于普通模拟信号测量外,还可以用于测量供电电压,此外ADC 还可以通过测量内/外部二极管电压用于温度检测。
Ai-WB2的ADC具有如下特性:
高性能
      · 可以选择12-bit,14-bit,16-bit 转换结果输出
      · ADC 转换时间最快0.5us(12-bit 转换结果)
      · 支持1.8V3.3V 可选参考电压
      · 支持DMA 将转换结果搬运到内存
      · 支持单通道转换和多通道扫描两种模式
      · 支持单端与差分两种输入模式
      · 支持抖动补偿
      · 支持用户自行设定转换结果偏移值
      ·
扫描模式时钟最大支持1M,非扫描模式支持2M
模拟通道数
      · 12 路外部模拟通道
      · 2 路DAC 内部通道

      · 1路VBAT/2 通道
      ·
1路TSEN 通道
ADC的功能框图如下:

1.png

ADC 模块包含五大部分,分别为前端输入通道选择器,程控放大器,ADC 采样模块,数据处理模块以及FIFO。输入通道选择器用于选择需要采样的通道,既包含外部模拟信号,也包含内部模拟信号,程控放大器用于对输入信号做进一步处理,可以根据输入信号的特点,比如直流,交流,进行设定,以便得到更准确的转换值。ADC 采样模块是最主要的功能模块,实现通过逐次比较的方式,得到模拟信号到数字信号的转换。转换的结果为12bit,数据处理模块负责将转换的结果进一步处理,包括添加通道信息等。最后得到的数据会推送到最后端的FIFO 中。

BL602中,ADC通道与GPIO的对应关系如下:
2.png

二:ADC驱动API
在bl_iot_sK中,ADC的HOSAL层高级APl在 components/platform/hosal/include/hosal_adc.h中定义。常用的驱动API函数如下:
· int hosal_adc_init(hosal_adc_dev_t *adc):初始化ADC。参数说明如下:
      · adc:ADC设备。其定义如下:

  1.   /**
  2.    * @brief Define ADC dev hosal handle
  3.    */
  4.   typedef struct {
  5.       uint8_t port;                    /**< @brief adc 端口 */
  6.       hosal_adc_config_t config;        /**< @brief adc 配置 */
  7.       hosal_dma_chan_t dma_chan;        /**< @brief adc dma 通道 */
  8.       hosal_adc_irq_t cb;               /**< @brief adc 回调函数 */
  9.       void *p_arg;                      /**< @brief p_arg 回调函数参数 */
  10.       void *priv;                       /**< @brief priv 用户自定义数据 */
  11.   } hosal_adc_dev_t;
复制代码
其中,hosal_adc_config_t为ADC配置,其定义如下:
  1. /**
  2. * @brief Define ADC config args
  3. */
  4. typedef struct {
  5.     uint32_t sampling_freq;             /**< @brief 采样频率(以Hz为单位) */
  6.     uint32_t pin;                        /**< @brief adc 引脚 */
  7.     hosal_adc_sample_mode_t mode;       /**< @brief adc 采样模式 */
  8.     uint8_t sample_resolution;          /**< @brief adc 采样精度 */
  9. } hosal_adc_config_t;
复制代码
其中hosal_adc_sample_mode_t的定义如下:
  1.   /**
  2.    * @brief ADC MODE type
  3.    */
  4.   typedef enum {
  5.       HOSAL_ADC_ONE_SHOT,       /**< @brief 单次采样 */
  6.       HOSAL_ADC_CONTINUE        /**< @brief 持续采样 */
  7.   } hosal_adc_sample_mode_t;
复制代码
      · 返回值:成功时返回0,否则返回EIO或其他值
· int hosal_adc_add_channel(hosal_adc_dev_t *adc,uint32_t channel):添加向ADC设备添加ADC通道。参数说明如下:
      · adc:ADC端口设备
      · ochannel:需要添加的ADC通道
      · 返回值:成功时返回0,否则返回EIO或其他值

· int hosal_adc_remove_channel(hosal_adc_dev_t *adc, uint32_t channel):移除ADC诵道。参数说明如下:
      · adc:ADC端囗设备
      · ochannel:需要移除的ADC通道
      · 返回值:成功时返回0,否则返回EIO或其他值

· int hosal_adc_value_get(hosal_adc_dev_t *adc, uint32_t channel,uint32_t timeout):读取单个ADC采样结果。参数说明如下:
      · adc:ADC端口设备
      · channel:ADC通道
      · otimeout:超时时长

      · 返回值:如果读取失败,则返回-1:否则返回ADC值

· int hosal_adc_tsen_value_get(hosal_adc_dev_t*adc):获取ADC端囗的TSEN值。参数说明如下:
      · adc:ADC端口设备
      · 返回值:如果读取失败,则返回-1:否则返回ADC值

· int hosal_adc_sample_cb_reg(hosal_adc_dev_t *adc,hosal_adc_cb_t cb):注册ADC回调函数(该函数未具体实现)
      · adc:ADC端口设备
      · cb:回调函数,当cb不为NULL时,表示注册;当cb为NULL时,表示注销。其定义如下:

  1.   typedef void (*hosal_adc_irq_t)(void *parg);
复制代码
       请注意:指针cb 中的 adc 必须与传递给 hosal_adc_sample_cb_reg 的 adc 指针相同,驱动程序必须通过调用 cb 通知上层 ADC 数据是否已在硬件或内存(DMA)中准备好。
      · 返回值:成功时返回0,否则返回EIO或其他值
· int hosal_adc_start(hosal_adc_dev_t *adc,void *data,uint32_t size):启动ADC采样(该函数未具体实现)。参数说明如下:
      · adc:ADC端口设备
      · data:用于储存采样结果
      · size:储存ADC采样结果长度
      · 返回值:成功时返回0,否则返回EIO或其他值

· int hosal adc_stop(hosal_adc_dev_t *adc):ADC停止采样(该函数未具体实现)。参数说明如下:
      · adc:ADC端口设备
      · 返回值:成功时返回0,否则返回EIO或其他值

· hosal_adc_finalize(hosal_adc_dev_t *adc):释放ADC。参数说明如下:
      · adc:ADC端囗设备
      · 返回值:成功时返回0,否则返回EIO或其他值

三:ADC使用示例
下面将演示通过ADC的通道4(GPIO5)来对电位计的电压进行采样。示例代码如下:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <FreeRTOS.h>
  4. #include <task.h>
  5. #include <stdio.h>
  6. #include <stdbool.h>
  7. #include <hosal_dma.h>
  8. #include <hosal_adc.h>
  9. #include <blog.h>

  10. #define TAG "adc_demo"

  11. /**********   BL602  ************
  12. *    channel0   ----->     gpio12
  13. *    channel1   ----->     gpio4
  14. *    channel2   ----->     gpio14
  15. *    channel3   ----->     gpio13
  16. *    channel4   ----->     gpio5
  17. *    channel5   ----->     gpio6
  18. *    channel7   ----->     gpio9
  19. *    channel9   ----->     gpio10
  20. *    channel10  ----->     gpio11
  21. *    channel11  ----->     gpio15
  22. */

  23. static hosal_adc_dev_t adc0;

  24. static void adc_init(void){
  25.     adc0.port = 0;
  26.     adc0.config.sampling_freq = 340;
  27.     adc0.config.pin = 5;
  28.     adc0.config.mode = HOSAL_ADC_ONE_SHOT; // 配置为单次采样
  29.     int ret = hosal_adc_init(&adc0);
  30.     if (ret != 0) {
  31.         blog_error("init adc failed. \r\n");
  32.         return;
  33.     }
  34.     hosal_adc_add_channel(&adc0, 4);
  35.     printf("adc init done\r\n");
  36. }

  37. void adc_task(void* params){
  38.     adc_init();
  39.     printf("adc task start...\r\n");
  40.     vTaskDelay(500);
  41.     while(true){
  42.         //hosal_adc_start(&adc0);
  43.       
  44.         int ret = hosal_adc_value_get(&adc0, 4, 20);
  45.         if(ret < 0){
  46.             printf("adc sample failed:%d\r\n",ret);
  47.             continue;
  48.         }
  49.         printf("adc value = %d\r\n",ret);
  50.          vTaskDelay(10);
  51.         
  52.     }

  53.     hosal_adc_finalize(&adc0);
  54. }

  55. void main(void) {
  56.     hosal_dma_init();
  57.     printf("adc demo inited\r\n");
  58.     xTaskCreate(adc_task, "adc_task", 1024, NULL, 15, NULL);
  59. }
复制代码
      注意:HOSAL层使用了DMA方式采样,因此需要调用 hosal_dma_init 函数来初始化DMA模块。
用心做好保姆工作
回复

使用道具 举报

WildboarG | 2024-8-28 14:39:27 | 显示全部楼层
技术这么拼
回复 支持 反对

使用道具 举报

爱笑 | 2024-8-28 14:50:25 | 显示全部楼层

园长也要累的半死
用心做好保姆工作
回复 支持 反对

使用道具 举报

bzhou830 | 2024-8-28 15:07:49 | 显示全部楼层
太高产了吧
选择去发光,而不是被照亮
回复 支持 反对

使用道具 举报

djy876 | 2024-9-6 11:38:40 | 显示全部楼层
学习打卡
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则