GD32F4xx 的12位ADC是一种采用逐次逼近方式的模拟数字转换器。
引脚名称 | 信号类型 | 说明 |
---|---|---|
VDDA | 输入,模拟供电电源 | 2.6v ≤ VDDA ≤ 3.6v |
VSSA | 输入,模拟电源地 | 等于Vss |
VREFP | 输入,模拟参考电压正 | ADC 正参考电压 2.6v ≤ VREFP ≤ VDDA |
VREFN | 输入,模拟参考电压负 | ADC 负参考电压 VREFN = VSSA |
ADCx_IN[15:0] | 输入,模拟信号 | 16路外部通道 |
VBAT | 输入,模拟信号 | 外部电池电压 |
PS: VDDA 和 VSSA 必须分别接到VDD 和 Vss
ADC带有一个前置校准功能。在校准期间,ADC计算一个校准系数,这个系数直到ADC下次掉电才无效。在校准期间,不能使用ADC必须等到校准完成。在AD转换之前应执行校准操作,一般放在初始化里执行。通过软件设置 ADC_CTL1寄存器的RSTCLB位为1来对校准进行初始化,在校准期间RSTCLB位会一直保持1,直到校准完成,该位由硬件清0。
PS: 当ADC运行条件改变(如,VDDA、VREFP、温度等条件变化,建议重新执行一次校准操作。)
ADC CLK 与 CK_AHB、PLCK2 时钟保持同步。ADC最大时钟频率为40MHz。
ADC转换可以组织成2组: 一个规则组通道和一个注入组通道。
1)规则组最多16个转换组成。而注入组最多4个转换组成。
2)注入组通道可以打断规则组通道
注入通道有2中模式:
① 触发注入模式: 在规则组通道转换期间如果软件触发或外部触发发生,ADC取消当前转换,启动触发注入转换,注入通道序列被以单次扫描方式进行转换。注入通道转换结束后,规则组转换从上次被取消的转换处重新开始。
② 自动注入模式:在规则通道之后,注入通道被自动转换。
举例说明: 规则组通道序列为 CH_0、CH_1、CH_2。
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 …