应用实战精解系列(六):RVB2601的ADC轮询单通道与DMA多通道采集

简介: 应用实战精解系列(六):RVB2601的ADC轮询单通道与DMA多通道采集

编辑语:

芯片开放社区(OCC)面向广大开发者推出应用实战系列内容,通过分享开发者实战开发案例,总结应用开发经验,梳理开发中的常见问题及解决方案,为后续参与的开发者提供更多参考与借鉴。

在上期内容中,我们为大家介绍了RVB2601开发板DAC的基础功能和特点,并基于此开发了一个web播放器,使大家更直观地了解DAC芯片的控制方式。本期我们将继续讲解基础开发内容,带大家了解RVB2601如何进行ADC的DMA采样。

# 前言

由于ADC没有文档介绍也没有例程,所以就只能靠着他所给的API来用,对照着PWM一步一步的来,最后还是调通了,也总结了不少技巧。

比如他所提供的API前面有static的就是他文件内部是函数,给自己调用的,到最后就剩下了几个。比如初始化的,adc通道配置的,adc开始停止的,adc模式的函数,还有给DMA用的缓冲区还有他相应的配置函数等等。

1.内部盗用的API,可以不用管他,刚开始还研究了好久。

 static void wj_adc_channel_conv_end_irq(csi_adc_t *adc)
 static void wj_adc_irqhandler(void *args)
 static csi_error_t wj_adc_start_intr(csi_adc_t *adc)
 static csi_error_t wj_adc_start_dma(csi_adc_t *adc)
 static csi_error_t wj_adc_stop_intr(csi_adc_t *adc)
 static csi_error_t wj_adc_stop_dma(csi_adc_t *adc)
 static int adc_channel_delete(uint8_t *channels, uint8_t nums, uint8_t channel)

2.ADC初始化,开始停止,通道配置,采样频率、时间,回调函数,ADC读取值等等

 csi_error_t csi_adc_init(csi_adc_t *adc, uint32_t idx)
 void csi_adc_uninit(csi_adc_t *adc)
 csi_error_t csi_adc_start(csi_adc_t *adc)
 csi_error_t csi_adc_stop(csi_adc_t *adc)
 csi_error_t csi_adc_channel_enable(csi_adc_t *adc, uint8_t ch_id, bool is_enable)
 csi_error_t csi_adc_channel_sampling_time(csi_adc_t *adc, uint8_t ch_id, uint16_t clock_num)
 csi_error_t csi_adc_sampling_time(csi_adc_t *adc, uint16_t clock_num)
 uint32_t csi_adc_freq_div(csi_adc_t *adc, uint32_t div)
 int32_t csi_adc_read(csi_adc_t *adc)
 csi_error_t csi_adc_get_state(csi_adc_t *adc, csi_state_t *state)
 uint32_t csi_adc_get_freq(csi_adc_t *adc)
 csi_error_t csi_adc_attach_callback(csi_adc_t *adc, void *callback, void *arg)
 void csi_adc_detach_callback(csi_adc_t *adc)
 csi_error_t csi_adc_start_async(csi_adc_t *adc)
 csi_error_t csi_adc_stop_async(csi_adc_t *adc)
 csi_error_t csi_adc_continue_mode(csi_adc_t *adc, bool is_enable)

3.ADC DMA相关配置函数:

 void wj_adc_dma_event_cb(csi_dma_ch_t *dma, csi_dma_event_t event, void *arg)
 csi_error_t csi_adc_set_buffer(csi_adc_t *adc, uint32_t *data, uint32_t num)
 csi_error_t csi_adc_link_dma(csi_adc_t *adc, csi_dma_ch_t *dma)

01 对adc单通道采样

创建一个ADC任务

 static void adc_task(void *arg)
 {
      csi_pin_set_mux(EXAMPLE_ADC_CH0, PA3_ADC_A1);
     csi_adc_init(&adc1, 0);
     uint32_t freq_value = csi_adc_freq_div(&adc1, 128);
     printf("get freq_value: %d\n", freq_value);
     csi_adc_sampling_time(&adc1, 2);
     csi_adc_continue_mode(&adc1, 1);//这句是连续采样,不使能只能采样一次
    csi_adc_channel_enable(&adc1, 0, true);
     while(1)
     {
         lv_task_handler();
         aos_msleep(400);
         lv_tick_inc(1);
        i = csi_adc_read(&adc1);
         printf("adc1:%d   ", i);
     }
 }

image.png

02 对adc多通道采样

那怎么用查询的方法对多通道采样呢?这个问题开始也是想了很久,因为读取adc函数就只有一个adc的句柄,这个句柄是初始化函数过来得到的,没有包含通道的相关操作。

这我就联想到了atm32sac的几种模式,就是扫描模式,多通道读取完一个自动对下一个进行读取,然后我就按照这个

image.png

    csi_adc_channel_enable(&adc1, 0, true);
    csi_adc_channel_enable(&adc1, 1, true);
    csi_adc_channel_enable(&adc1, 2, true);

注册了几个端口,连续读取三次果然是三个端口的值:

       i = csi_adc_read(&adc1);
       printf("adc1:%d  ", i);
       i = csi_adc_read(&adc1);
       printf("adc1:%d  ", i);
       i = csi_adc_read(&adc1);
       printf("adc1:%d  ", i);


结果就是依次读取那个PA3-5的adc值。

image.png

03 DMA对多通道采样

实际上我们比较多用DMA采样多通道的adc值,这样可以释放cpu也可以很好的随时读取:

我们加上DMA的配置代码

 csi_adc_set_buffer(&adc1,  buff0,  3);
 csi_adc_link_dma( &adc1, &dma1);  
 csi_adc_channel_enable(&adc1, 0, true);
 csi_adc_channel_enable(&adc1, 1, true);
 csi_adc_channel_enable(&adc1, 2, true);
 csi_adc_start_async(&adc1);
 while(1)
     {
         lv_task_handler();
         aos_msleep(400);
         lv_tick_inc(1);
            i=buff0[0];
         printf("adc1:%d   ", i);
         printf("adc1:%d mv\r\n", i * 3300 / 4095);    
        i=buff0[1];
         printf("adc1:%d   ", i);
         printf("adc1:%d mv\r\n", i * 3300 / 4095);    
 i=buff0[2];
         printf("adc1:%d   ", i);
         printf("adc1:%d mv\r\n", i * 3300 / 4095);  

image.png


相关文章
|
4月前
|
传感器 编解码 数据处理
毕业设计|基于STM32单片机的水位浑浊度检测设计
毕业设计|基于STM32单片机的水位浑浊度检测设计
717 0
|
数据采集 C语言
单片机开发之ADC0808/9信号采集
本文主要介绍了单片机开发之ADC0808/9信号采集
577 0
单片机开发之ADC0808/9信号采集
|
2月前
|
传感器 编解码 API
【STM32开发入门】温湿度监测系统实战:SPI LCD显示、HAL库应用、GPIO配置、UART中断接收、ADC采集与串口通信全解析
SPI(Serial Peripheral Interface)是一种同步串行通信接口,常用于微控制器与外围设备间的数据传输。SPI LCD是指使用SPI接口与微控制器通信的液晶显示屏。这类LCD通常具有较少的引脚(通常4个:MISO、MOSI、SCK和SS),因此在引脚资源有限的系统中非常有用。通过SPI协议,微控制器可以向LCD发送命令和数据,控制显示内容和模式。
|
4月前
【STM32】使用单片机DAC产生噪声群
【STM32】使用单片机DAC产生噪声群
|
4月前
|
芯片
动画图解常见串行通讯协议:SPI、I²C、UART、红外分析
动画图解常见串行通讯协议:SPI、I²C、UART、红外分析
117 0
|
物联网 芯片 计算机视觉
树莓派开发笔记(十):Qt读取ADC模拟量电压(ADS1115读取电压模拟量)
树莓派开发笔记(十):Qt读取ADC模拟量电压(ADS1115读取电压模拟量)
树莓派开发笔记(十):Qt读取ADC模拟量电压(ADS1115读取电压模拟量)
|
数据采集 索引
NI采集卡USB-6361多通道模拟输入采集报错解决方案
折腾一块 USB-6361 采集卡很久了,之前都是单通道采集模拟信号,突然接到要使用双通道采集模拟信号,本想着就新增加一路 Analog Input task 即可,但事情总没有想象的那么简单,因此记录一下解决的方法。
270 0
|
传感器 监控
LabVIEW控制Arduino采集DHT11温湿度数值(进阶篇—4)
在多数情况下,测量温度的同时需要测量湿度,本篇博文将介绍使用DHT11温湿度传感器、Arduino Uno和LabVIEW组成温湿度测量系统,可用于粮仓等场合的温湿度监控。
|
数据采集 传感器 编解码
LabVIEW控制Arduino采集多路模拟量、数字量(进阶篇—1)
数据采集,是指从传感器和其他待测设备的模拟和数字被测单元中自动采集信息的过程。能够实现数据采集功能的系统叫作数据采集系统。
|
算法 程序员 调度
S32K3XX单片机DMA原理深度解析(下)
S32K3XX单片机DMA原理深度解析(下)