GD32F303固件库开发(11)----ADC在DMA模式下扫描多个通道

发布者:RainbowGarden最新更新时间:2024-11-18 来源: elecfans关键字:GD32F303  固件库开发  ADC  DMA模式 手机看文章 扫描二维码
随时随地手机看文章

概述

本章主要配置,ADC在DMA模式下扫描多个通道,通过串口进行打印。 查阅手册可以得知,PA9、PA10为串口0的输出和输入口。 需要GD样片的可以加群申请:615061293 。

在这里插入图片描述

ADC通道配置

在这里插入图片描述

硬件准备

这里准备了1块开发板进行验证,分别是GD32303C_START开发板。

在这里插入图片描述

keil配置

microlib 进行了高度优化以使代码变得很小。 它的功能比缺省 C 库少,并且根本不具备某些 ISO C 特性。 某些库函数的运行速度也比较慢,如果要使用printf(),必须开启。

在这里插入图片描述

使能串口

/* 使能GPI0A,用PA9、PA10为串口 */

    rcu_periph_clock_enable(RCU_GPIOA);


    /*使能串口0的时钟 */

    rcu_periph_clock_enable(RCU_USART0);


    /*配置USARTx_Tx(PA9)为复用推挽输出*/

    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);


    /*配置USARTx_RxPA9)为浮空输入 */

    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);


    /* USART 配置 */

    usart_deinit(USART0);//重置串口0

    usart_baudrate_set(USART0, 115200U);//设置串口0的波特率为115200

    usart_word_length_set(USART0, USART_WL_8BIT);          // 帧数据字长

        usart_stop_bit_set(USART0, USART_STB_1BIT);               // 停止位1位

    usart_parity_config(USART0, USART_PM_NONE);           // 无奇偶校验位

    usart_receive_config(USART0, USART_RECEIVE_ENABLE);//使能接收器

    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);//使能发送器

    usart_enable(USART0);//使能USART

串口重定向

复制

/* retarget the C library printf function to the USART */

int fputc(int ch, FILE *f)

{

    usart_data_transmit(USART0, (uint8_t)ch);

    while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));

    return ch;

}


串口重定向后就可以使用printf进行打印。

ADC通道设置

在这里插入图片描述

DMA设置

在这里插入图片描述


ADC0初始化

void rcu_config(void)

{

    /*使能GPIOA时钟 */

    rcu_periph_clock_enable(RCU_GPIOA);

    /* 使能ADC时钟 */

    rcu_periph_clock_enable(RCU_ADC0);

    /* 使能DMA0时钟 */

    rcu_periph_clock_enable(RCU_DMA0);

    /* 配置ADC速率 */

    rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6);

}

GPIO初始化

void gpio_config(void)

{

    /* config the GPIO as analog mode */

    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_0);

    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_1);

    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_2);

    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_10MHZ, GPIO_PIN_3);

}

ADC0配置

void adc_config(void)

{


        adc_deinit(ADC0);

    /* ADC mode config */

    adc_mode_config(ADC_MODE_FREE); 

    /* 开启连续转换 */

    adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);

    /* 开启扫描模式 */

    adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);

    /*数据右对齐 */

    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);


    /* ADC channel length config */

    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 4);


    /* ADC regular channel config */ 

    adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5);

    adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);

    adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_2, ADC_SAMPLETIME_55POINT5);

    adc_regular_channel_config(ADC0, 3, ADC_CHANNEL_3, ADC_SAMPLETIME_55POINT5);


    /* ADC 软件触发(规则组) */

    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);

    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);


    /* ADC DMA function enable */

    adc_dma_mode_enable(ADC0);

    /* enable ADC interface */

    adc_enable(ADC0);



    /* ADC校准和复位校准 */

    adc_calibration_enable(ADC0);

}

DMA0初始化

void dma_config(void)

{

    /* ADC_DMA_channel configuration */

    dma_parameter_struct dma_data_parameter;


    /*  ADC DMA0_0初始化 */

    dma_deinit(DMA0, DMA_CH0);


    /* initialize DMA single data mode */

    dma_data_parameter.periph_addr  = (uint32_t)(&ADC_RDATA(ADC0));//外设基地址

    dma_data_parameter.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;//内存地址增量模式

    dma_data_parameter.memory_addr  = (uint32_t)(&ADC0_Value);//数据存放地址

    dma_data_parameter.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;//内存地址增量模式

    dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;//dma外设宽度16位,半字

    dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;  

    dma_data_parameter.direction    = DMA_PERIPHERAL_TO_MEMORY;//传输模式,外设到存储(接收)

    dma_data_parameter.number       = 40;//长度

    dma_data_parameter.priority     = DMA_PRIORITY_HIGH;//优先级高

    dma_init(DMA0, DMA_CH0, &dma_data_parameter);


    dma_circulation_disable(DMA0, DMA_CH0);//循环模式开启dma_circulation_enable(DMA0, DMA_CH0)//dma_circulation_disable


        /* enable DMA transfer complete interrupt */

    dma_interrupt_enable(DMA0, DMA_CH0, DMA_INT_FTF);    //打开全部完成中断

    /* enable DMA channel */

    dma_channel_enable(DMA0, DMA_CH0);    /* DMA内存到内存模式不开启 */

}

DMA0_Channel0_IRQHandler()

void DMA0_Channel0_IRQHandler(void)

{

  if(dma_interrupt_flag_get(DMA0, DMA_CH0, DMA_INT_FLAG_FTF)==SET)

  {     

        dma_interrupt_flag_clear(DMA0, DMA_CH0, DMA_FLAG_FTF);//清除DMA通道传输完成标志

        dma_channel_disable(DMA0, DMA_CH0);


        ADC0_Flag=1;

  }

}

初始化定义

/* system clocks configuration */

    rcu_config();

    nvic_irq_enable(DMA0_Channel0_IRQn, 0, 0);

    /* GPIO configuration */

    gpio_config();

    /* DMA configuration */

    dma_config();

    /* ADC configuration */

    adc_config();

        /* ADC software trigger enable */

    adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);

数据采集

while (1)

        {

            if(ADC0_Flag==1)

            {

                ADC0_0=0;

                ADC0_1=0;

                ADC0_2=0;

                ADC0_3=0;

                for(i=0;i<40;)

                {

                    ADC0_0+=ADC0_Value[i++];

                    ADC0_1+=ADC0_Value[i++];

                    ADC0_2+=ADC0_Value[i++];

                    ADC0_3+=ADC0_Value[i++];

                }        

          printf('\n');

          printf('adc1_IN0(PA0)=%4.0d,ADC_IN0=%1.4f\r\n',ADC0_0/10,ADC0_0/10*3.3f/4096);

          printf('adc1_IN1(PA1)=%4.0d,ADC_IN1=%1.4f\r\n',ADC0_1/10,ADC0_1/10*3.3f/4096);

          printf('adc1_IN2(PA2)=%4.0d,ADC_IN2=%1.4f\r\n',ADC0_2/10,ADC0_2/10*3.3f/4096);

          printf('adc1_IN3(PA3)=%4.0d,ADC_IN3=%1.4f\r\n',ADC0_3/10,ADC0_3/10*3.3f/4096);

            ADC0_Flag=0;

        adc_config();    

        dma_memory_address_config(DMA0, DMA_CH0, (uint32_t)(&ADC0_Value));

        dma_transfer_number_config(DMA0, DMA_CH0, 40);        

        dma_channel_enable(DMA0, DMA_CH0);

        adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);            


            }

      delay_1ms(1000);

    }


测试结果

输入固定电压进行测试。

在这里插入图片描述

测试结果如下。

在这里插入图片描述


关键字:GD32F303  固件库开发  ADC  DMA模式 引用地址:GD32F303固件库开发(11)----ADC在DMA模式下扫描多个通道

上一篇:基于GD32L233的物联网水表解决方案
下一篇:最后一页

推荐阅读最新更新时间:2024-11-18 10:43

STM32-电源【ADC供电、VDDA、VSSA、VREF、VBAT等】
STM32供电方案一览 STM32的电源框图如下所示,电源供电共分为4个区域: VDD、VSS供电区域; VDDA、VSSA供电区域; 1.8V供电区域; 后备电源(VBAT)供电区域; STM32F103ZET6(其他的STM32也基本无差)的Datasheet关于供电方案的说明如下: Power supply schemes • VDD = 2.0 to 3.6 V: external power supply for I/Os and the internal regulator(内部调节器或稳压器). Provided externally through VDD pins. • VSSA, VDDA = 2
[单片机]
STM32-电源【<font color='red'>ADC</font>供电、VDDA、VSSA、VREF、VBAT等】
ADC的架构与触发源原理
1.引言 在 STM32 MCU 中,ADC 有多种启动触发方式,本文对各种触发源的原理进行介绍,方便大家以后如何选择合适的触发源。 2. ADC 的架构与触发源 以 STM32G474 为例,ADC 模块的架构框图如下,基于逐次逼近原理(SAR)完成模拟量到数字量的转换。前端通过多通道选择开关(input selection)来对转换通道进行切换,从而实现对多个输入通道的信号进行采样。 ADC 模块的信道可以工作在规则模式或是注入模式下,对应的触发源分别为规则触发源与注入触发源。所有规则通道共享一个 ADC 结果寄存器,一个通道转换完成后需要及时读取转换结果,否则转换结果可能会被覆盖,具体取决于 overrun 的相关设置。
[单片机]
<font color='red'>ADC</font>的架构与触发源原理
由开关电源驱动的高速ADC设计
  系统设计人员正面临越来越多的挑战,他们必须在不降低系统元件(如高速资料转换器)性能的情况下让设计最大程度地实现节能。设计人员们可能转而採用许多以电池供电的应用(如某种手持终端、软体无线设备或可携式超音波扫描器),也可能缩小产品的外形尺寸,因而必须寻求减少发热的诸多方法。   极大降低系统功耗的一种方法是对高速资料转换器的电源进行最佳化。资料转换器设计和製程技术的一些最新进展,让许多新型ADC可直接由开关电源来驱动,因而达到最大化功效的目的。   系统设计人员们习惯在交换式稳压器和ADC之间使用一些低杂讯、低压降稳压器(LDO),以清除输出杂讯和开关频率突波(请参见图1)。但是,这种乾净的电源设计代价是高功耗,因为LDO要求压降
[电源管理]
由开关电源驱动的高速<font color='red'>ADC</font>设计
ADC设计挑战:从高性能转向低功耗
新的应用需求不断推动模拟技术的发展:性能越来越高,集成度不断提高。ADC产品作为模拟IC的重要成员,在符合上述发展的趋势下,还存在自身的特点。 当使用“巧克力”手机时,不用按键只用轻触那泛着深红色光的区域,你是否知道电容感应技术改变了你的体验;当看到那小小的骑车机器人“村田顽童”可以前进、倒退、爬坡并且停而不倒时,你是否知道其中使用了多种传感器以检测各个方向的倾斜角度和探测道路状况;当你惊叹残疾人可以自如地控制假肢完成复杂动作时,你是否知道与假肢相连的探测器可以检测人体肌肉的最细微运动从而实现对假肢的控制;也许你并没有留意到用手机通话时显示屏会自动关闭以便降低功耗,这是手机检测到显示屏被物体(例如耳朵)遮住时的操作……所有这些都表
[模拟电子]
<font color='red'>ADC</font>设计挑战:从高性能转向低功耗
用带ADC的avr单片机做的一款电压检测表
电压表效果 电路原理图如下: 单片机源码: #include iom16v.h #include macros.h #define uchar unsigned char #define uint unsigned int void delayms(uint mS) //微秒 { uint i,j; for( i=0;i mS;i++) for(j=0;j 200;j++); } unsigned char disp = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90,
[单片机]
用带<font color='red'>ADC</font>的avr单片机做的一款电压检测表
Delta-Sigma模数转换器的优点
National Instruments设计了24位delta-sigma模数转换器(ADC)用于许多高性能的数据采集(DAQ)设备,其中就包括NI SC Express 系列产品,它集成了信号调理功能可以直接测量传感器。同时,基于Delta-sigma ADC采用的噪声整形和滤波技术,可以为高分辨率测量提供最高的测试精度。本文将介绍delta-sigma ADC的体系结构和SC Express用软件对滤波延迟进行自动补偿的方法。 Delta-Sigma ADC体系结构 放大图片 图1: delta-sigma (Δ -∑ ) ADC由积分器、比较器和1位DAC组成。 Delta-sigma ADC(也称为
[模拟电子]
stm32 嵌入式开发 用标准进行 ADC 实验总结
硬件原理图 ,滑动电位器与芯片PC3引脚连接 根据开发板可知:STM32F429IGT6 有 3 个 ADC,每个 ADC 有 12 位、 10 位、 8 位和 6 位可选,每个ADC 有 16 个外部通道。         每个ADC 同时还有3个内部通道:通道16/17/18         工作模式有3种:独立模式、双重模式和三重模式 。 转换顺序可分为:规则序列,注入序列。如下图所示: 规则序列寄存器设置根据表由上到下选择通道进行配置 注入序列寄存器JSQR转换顺序为JSQR ,                   X=4-JL,JL为需要转换的通道 触发源可选择:ADC2_CR2-
[单片机]
stm32 嵌入式<font color='red'>开发</font> 用标准<font color='red'>库</font>进行 <font color='red'>ADC</font> 实验总结
stm32专题二十四:ADC简介
ADC简介: ADC :Analog to Digital,模拟数字转换器 三个独立的ADC 1 / 2 / 3; 分辨率为12位; 每个ADC具有18个通道,其中外部通道16个; ADC结构框图,主要分成7个部分: 电压输入范围、输入通道、转换顺序、触发源、转换时间、数据寄存器、中断。 (1)输入电压范围: ADC 输入范围为:VREF- ≤ VIN ≤ VREF+。由VREF-、VREF+ 、VDDA 、VSSA、这四个外部引脚决定。 在设计原理图的时候一般把VSSA 和VREF-接地,把VREF+和VDDA 接3V3,得到ADC 的输入电压范围为:0~3.3V。 如输入电压超过3.3v,如希望测量
[单片机]
stm32专题二十四:<font color='red'>ADC</font>简介
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved