GD32F4xx MCU ADC+DMA 多通道采样

您所在的位置:网站首页 返校剧情介绍 GD32F4xx MCU ADC+DMA 多通道采样

GD32F4xx MCU ADC+DMA 多通道采样

#GD32F4xx MCU ADC+DMA 多通道采样| 来源: 网络整理| 查看: 265

1、GD32F4xx ADC

GD32F4xx 的12位ADC是一种采用逐次逼近方式的模拟数字转换器。

1.1 主要特征 可配置12位、10位、8位、6位分辨率;ADC采样率:12位分辨率为2.6MSPs,10位分辨率为3.0 MSPs。分辨率越低,转换越快; PS: MSPs (模拟混合信号转换速率),是指完成1次从模拟转换到数字的AD转换所需的时间的倒数。常用单位是ksps和Msps,表示每秒采样(千)/(百万)次(kilo / Million Samples per Second)。 1msps=1000 ksps自校准时间:131个ADC时钟周期;(如25MHz时钟,校准时间约5.24us)可编程采样时间、可配置数据对齐方式;支持规则通道数据转换的DMA请求;模拟输入通道: 1) 16个外部输入通道; 2) 1个内部温度传感器通道; 3) 1个内部参考电压输入通道; 4) 1个外部监测电池Vbat供电引脚输入通道;转换触发: 软件触发 和 硬件触发(硬件中断等) 1.2 引脚定义 引脚名称信号类型说明VDDA输入,模拟供电电源2.6v ≤ VDDA ≤ 3.6vVSSA输入,模拟电源地等于VssVREFP输入,模拟参考电压正ADC 正参考电压 2.6v ≤ VREFP ≤ VDDAVREFN输入,模拟参考电压负ADC 负参考电压 VREFN = VSSAADCx_IN[15:0]输入,模拟信号16路外部通道VBAT输入,模拟信号外部电池电压

PS: VDDA 和 VSSA 必须分别接到VDD 和 Vss

1.3 ADC校准

ADC带有一个前置校准功能。在校准期间,ADC计算一个校准系数,这个系数直到ADC下次掉电才无效。在校准期间,不能使用ADC必须等到校准完成。在AD转换之前应执行校准操作,一般放在初始化里执行。通过软件设置 ADC_CTL1寄存器的RSTCLB位为1来对校准进行初始化,在校准期间RSTCLB位会一直保持1,直到校准完成,该位由硬件清0。

PS: 当ADC运行条件改变(如,VDDA、VREFP、温度等条件变化,建议重新执行一次校准操作。)

1.4 ADC时钟

ADC CLK 与 CK_AHB、PLCK2 时钟保持同步。ADC最大时钟频率为40MHz。 在这里插入图片描述

1.5 规则组和注入组

ADC转换可以组织成2组: 一个规则组通道和一个注入组通道。 1)规则组最多16个转换组成。而注入组最多4个转换组成。 2)注入组通道可以打断规则组通道 注入通道有2中模式: ① 触发注入模式: 在规则组通道转换期间如果软件触发或外部触发发生,ADC取消当前转换,启动触发注入转换,注入通道序列被以单次扫描方式进行转换。注入通道转换结束后,规则组转换从上次被取消的转换处重新开始。 ② 自动注入模式:在规则通道之后,注入通道被自动转换。

1.6 转换模式

举例说明: 规则组通道序列为 CH_0、CH_1、CH_2。 在这里插入图片描述

1.7 其他 模拟看门狗,可以设置ADC转换电压的低阈值和高阈值,当转换电压 < 低阈值或 >高阈值时,看门狗可以置位标志位或产生中断。可以通过配置看门狗监控单一通道或多通道。可编程的采样时间:ADC使用若干个ADCCLK周期对输入电压进行采样。每个通道可以用不同的时间采样。 12位分辨率的情况下:总转换时间 = 采样时间 + 12个ADCCLKDMA:ADC在规则组一个通道转换结束后产生一个DMA请求,DMA接收到请求后可以将转换的数据从ADC_RDATA寄存器传输到用户指定的目的地址。ADC同步模式:待研究… 2、ADC + DMA 测试代码

ADC_DMA_Init

// ADC Init void ADC_DMA_Init(void) { /* enable GPIOC clock */ rcu_periph_clock_enable(RCU_GPIOC); // enable GPIOC clk /* enable ADC clock */ rcu_periph_clock_enable(RCU_ADC0); // enable ADC clk /* config ADC clock */ adc_clock_config(ADC_ADCCK_PCLK2_DIV4); // config ADC clk: PCLK2/4 = 25MHz (PCLK2=100MHz) rcu_periph_clock_enable(RCU_DMA1); // enable DMA1 clk /* config the GPIO as analog mode */ gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_0); // PC0 : ADC012_IN10 gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1); // PC1 : ADC012_IN11 ADC_Config(); // ADC init DMA_config(); // DMA init Log_printf("ADC_DMA_Init\r\n"); }

ADC_Config

void ADC_Config(void) { // ADC 独立模式 adc_sync_mode_config(ADC_SYNC_MODE_INDEPENDENT); // 连续转换模式使能 adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE); // Scan mode enable adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE); // ADC data右对齐 adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT); // 规则通道数量 adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 2); // ADC规则通道配置:Rank优先级排序(0~15),采样时间:15个周期 adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_10, ADC_SAMPLETIME_15); adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_11, ADC_SAMPLETIME_15); adc_resolution_config(ADC0, ADC_RESOLUTION_12B); // 12位分辨率 // ADC外部触发禁用, 即只能使用软件触发 adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, EXTERNAL_TRIGGER_DISABLE); // ADC DMA function enable adc_dma_request_after_last_enable(ADC0); // 每个规则组通道转换完成后发送一个DMA请求 adc_dma_mode_enable(ADC0); adc_enable(ADC0); // wait for ADC stability osDelay(1); // ADC自校准 adc_calibration_enable(ADC0); }

DMA_config

#define ADC_CH_CNT 2 //ADC通道数 #define ADC_VALUE_CNT 30 //每通道保存值个数 #define ADC_BUF_LEN (ADC_CH_CNT * ADC_VALUE_CNT) //DMA缓冲区数据长度 uint16_t gt_adc_val[ADC_BUF_LEN]; //DMA缓冲区 void DMA_config(void) { // ADC0 DMA dma_single_data_parameter_struct dma_single_data_parameter; // ADC DMA_channel configuration dma_deinit(DMA1, DMA_CH0); // initialize DMA single data mode dma_single_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC0)); // peripheral address dma_single_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE; dma_single_data_parameter.memory0_addr = (uint32_t)(gt_adc_val); // memory address dma_single_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE; dma_single_data_parameter.periph_memory_width = DMA_PERIPH_WIDTH_16BIT; dma_single_data_parameter.direction = DMA_PERIPH_TO_MEMORY; // transfer direction dma_single_data_parameter.number = ADC_BUF_LEN; // transfer length dma_single_data_parameter.priority = DMA_PRIORITY_HIGH; dma_single_data_mode_init(DMA1, DMA_CH0, dma_single_data_parameter); dma_channel_subperipheral_select(DMA1, DMA_CH0, DMA_SUBPERI0); // 使能循环模式 dma_circulation_enable(DMA1, DMA_CH0); }

ADC_Conv_Start

// 启动ADC转换 void ADC_Conv_Start(void) { dma_channel_enable(DMA1, DMA_CH0); // 启动DMA adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL); // 开启软件触发ADC转换 }

PS: 1.开启转换后,ADC采样值通过DMA直接传送到了gt_adc_val[ADC_BUF_LEN] 中。由于规则通道组是2个通道(ADC_CHANNEL_10,ADC_CHANNEL_11)。gt_adc_val[ADC_BUF_LEN] 中的存储形式如下: gt_adc_val[0] = ADC_CHANNEL_10的值; gt_adc_val[1] = ADC_CHANNEL_11的值; gt_adc_val[2] = ADC_CHANNEL_10的值; gt_adc_val[3] = ADC_CHANNEL_11的值; … 2.采样值转换12位分辨率: Value = Vadc * VREFP / 4096

以上是近期使用的一些总结,后续如有需要会继续补充!

To Be Continue …



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3