外观
十、ADC检测实验
ADC基础知识
什么是ADC
ADC是一种用于将模拟信号转换为数字信号的模拟数字转换器。我们知道,模拟信号是连续的,其取值可以在一定范围内任意变化。而数字信号则是离散的,仅能取有限的值。ADC的工作原理是将模拟信号通过采样转换为离散的数字信号,然后再通过量化、编码等处理,最终得到对应的数字表示。ADC采样的频率越高,得到的数字信号就越接近原来的模拟信号,也就是保真度越高,但是需要更多的资源和计算功耗。
GD32的ADC介绍
GD32E230片上集成了12位逐次逼近式ADC,可以采样来自于10个外部通道、2个内部通道的模拟信号,最快采样速率2MSPS。
ADC转换使用说明
假设此时ADC分辨率设置为12位,采集一个0~5V的电压信号,这意味着我们的输入电压0~5V将被分成4096个离散模拟值,4096是12位ADC的分辨率(2^12=4096)。
这样,如果实际输入电压为0V,则单片机的ADC会读取到的值为0,如果是5V,单片机将读取4096,如果是2.5V,则MCU将读取2048。
另外一个知识点是ADC的参考电压,在ADC转换过程中,通过与参考电压进行比较,来获取未知电压,GD32E230ADC参考电压与供电电压保持一致,一般情况下为(3.3V)。
可以使用以下公式根据ADC的分辨率和ADC获取的值来转换为实际的电压值。
(ADC分辨率)/(参考电压)=(ADC获取的值)/(实际电压值)
ADC引脚原理图
这里我们仅需知道ADC引脚是PA3即可,相关电路分析可前往电路原理分析
串口输出电压值
项目分析
本次项目是将获取到的ADC值转换为电压值通过串口发送到串口调试助手上进行显示。
配置流程
一般使用ADC功能,都需要以下几个步骤:
- 配置时钟
- 配置引脚
- 配置ADC模式
- 配置数据对齐方式
- 配置分辨率
- 配置采集通道与通道长度
- 配置触发方式
- 使能ADC
- 开启校准
配置时钟
使用ADC功能,需要开启ADC的时钟,同时ADC引脚也是GPIO,我们同样需要使能GPIO时钟。
ADC的时钟来源有AHB(72MHz-MAX)、APB2(72MHz-MAX)和IRC28M(28MHz)总线,我们需要选择一个时钟源,并将其分频到28MHz以下。
本次实验选择AHB总线,使用3分频,这样输入时钟是72/3=24Mhz,接近最大速度了。
C
//使能引脚时钟
rcu_periph_clock_enable(RCU_GPIOA);
//使能ADC时钟
rcu_periph_clock_enable(RCU_ADC);
//配置ADC时钟,3分频
rcu_adc_clock_config(RCU_ADCCK_AHB_DIV3);
1
2
3
4
5
6
2
3
4
5
6
配置引脚
从前面的引脚原理图可知,ADC引脚是PA3;在配置引脚模式时需要注意,引脚必须设置为模拟浮空输入模式,若设置为上拉或下拉模式,则采集的电压是不准确的。
C
//配置引脚为模拟浮空输入模式
gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_3);
1
2
2
配置ADC模式
在代码中能够配置的ADC模式有以下三种情况:
- ADC_SCAN_MODE:扫描模式
- ADC_INSERTED_CHANNEL_AUTO:注入组自动转换模式
- ADC_CONTINUOUS_MODE:连续模式
这里的注入组自动转换模式仅在使用注入组的情况下使用,这里不做说明,可自行参考《GD32E230用户手册》。
在连续模式下,一旦ADC被启动,它会不断对选定的通道进行采样和转换,直到函数命令其停止,连续模式下转换无需重新启动。
在扫描模式下,ADC按照预设的顺序自动扫描多个通道,并对每一个通道进行一次采样和转换,扫描模式下需要开启DMA;
注意这里的模式并不是多选一的结构,而是多选多,自由搭配,(例:连续扫描模式,可连续不间断扫描),当我们将连续模式与扫描模式都关闭,应该就是打开单次转换模式。
模式设置完成后,就是设置对应触发源与采样时长;
触发源可选择规则组通道与注入组通道(注入组类似于中断,当规则组正常运行时,若有例外情况参数,则可通过注入组打断规则组,进行采样);
触发条件可选定时器、外部中断、软件触发三种;
C
//关闭扫描模式
adc_special_function_config(ADC_SCAN_MODE, DISABLE);
//关闭连续模式
adc_special_function_config(ADC_CONTINUOUS_MODE, DISABLE);
//设置为ADC规则组,软件触发模式。
adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
1
2
3
4
5
6
2
3
4
5
6
通过查找数据手册可知,PA3引脚对应ADC通道3,采样周期是单次ADC转换时间,时间越短转换越快,但误差较大。
该函数第一个参数为规则通道顺序表,在扫描模式下,是按照此顺序从小到大依次扫描转换的。
相关函数说明可参考《GD32固件库使用指南》
C
//常规通道配置。通道1 采样周期为55.5
adc_regular_channel_config(0U, ADC_CHANNEL_3, ADC_SAMPLETIME_55POINT5);
1
2
2
配置数据对齐方式
GD32E230C8T6微控制器的ADC支持各种数据对齐方式以适应不同的应用场景。常见的数据对齐方式包括左对齐和右对齐。在右对齐模式下,ADC的数据在转换结束后被右对齐到最低位,不足的位数在高位填充0。右对齐模式允许实现在没有精度的损失下更好的动态范围。
在左对齐模式下,ADC的数据被左对齐到最高位,不足的位数在低位填充0。左对齐模式可以提高分辨率,但会导致动态范围降低。 这里选择右对齐方式,可以直接将转换完成的数据进行计算。C
//数据右对齐
adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
1
2
2
配置分辨率
GD32E230C8T6的分辨率可以配置为6、8、10、12 位。我们可以通过降低 ADC 的分辨率,获得较快的转换时间(tADC)。对于那些不需要高精度数据的应用,可以使用较低的分辨率来实现更快速地转换。
这里配置为12位分辨率 ::: code-groupC
//ADC设置为12位分辨率
adc_resolution_config(ADC_RESOLUTION_12B);
1
2
2
:::
配置采集通道与通道长度
此处配置的是规则组通道,且仅使用了通道3。若后续使用了多个规则组通道,需修改规则组通道的长度,以便扫描模式下循环遍历。
C
//ADC设置为规则组 一共使用 1 个通道
adc_channel_length_config(ADC_REGULAR_CHANNEL, 1);
1
2
2
配置触发方式
触发方式有三种,定时器事件触发、外部中断触发、软件触发;
其中外部触发输入的上升沿、下降沿可以触发规则组或注入组的转换。具体见GD32E23用户手册的第150页。需要注意的是可以实时修改外部触发选择,在修改期间不会出现触发事件。
软件触发方式是由软件触发启动,通常用在单次采样转换中。在软件触发模式下,ADC转换工作被触发后,由软件控制以固定的时间间隔进行转换,因此通常用于采集时间不太关键,但要求精度较高的应用。
这里选择的是软件触发方式,软件触发方式的配置如下:
C
//ADC外部触发配置使能
adc_external_trigger_config(ADC_REGULAR_CHANNEL,ENABLE);
//使能软件触发
adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
1
2
3
4
2
3
4
使能ADC
ADC配置好之后并不能开始工作,还需要去使能,就是相当于有一个开关可以打开关闭。需要注意的是要先使能了ADC之后,才能开始进行自校准。
使能ADC后做一个简短的延迟,等待ADC使能完毕。
C
//ADC使能
adc_enable();
delay_1ms(1U);
1
2
3
2
3
开启校准
ADC 带有一个前置校准功能。在校准期间,ADC 会计算一个出厂校准系数,这个系数是应用于 ADC 内部的,它直到 ADC 下次掉电才无效。在 A/D 转换前应执行校准操作。在校准期间,应用不能使用 ADC,它必须等到校准完成。通过软件设置 CLB=1 来对校准进行初始化,在校准期间CLB 位会一直保持 1,直到校准完成,该位由硬件清 0。可以直接使用库函数调用校准,完成操作。
开启校准的配置如下:
C
//开启ADC自校准
adc_calibration_enable();
1
2
2
采集转换
我们之前使用的是单次转换模式并使用的是软件触发方式,因此当我们要采集信号时,需要配置好采集通道并开启软件转换。开启转换后,等待EOC标志位置1。其中EOC为转换完成标志位,我们可以通过判断其是否置1,确定是否转换完成。转换完成后将数据从16位寄存器中取出。
C
/**********************************************************
* 函 数 名 称:Get_ADC_Value
* 函 数 功 能:读取ADC值
* 传 入 参 数:ADC_CHANNEL_x=要采集的通道
* 函 数 返 回:测量到的值
* 作 者:LC
* 备 注:默认采样周期为55.5个ADC采样时间
**********************************************************/
uint16_t Get_ADC_Value(uint8_t ADC_CHANNEL_x)
{
uint16_t adc_value = 0;
//设置采集通道
adc_regular_channel_config(0, ADC_CHANNEL_x, ADC_SAMPLETIME_55POINT5);
//开始软件转换
adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
//等待 ADC 采样完成
while ( adc_flag_get(ADC_FLAG_EOC) == RESET )
{
}
//读取采样值
adc_value = adc_regular_data_read();
//返回采样值
return adc_value;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
实验现象
烧录代码后,在串口助手中会发现ADC值与电压值输出。
资料下载
工程代码可前往gitee下载资料包,简易数字示波器资料包
注意事项
无法打开串口
串口连接是在GD32E230小板上的TYPEC接口处,底板TYPE-C接口仅支持供电。想要使用串口功能,需将TYPE-C线连接到核心板的接口上。
每个人连接到电脑上的COM端口都不会完成一致,不需要完全按照图片的COM端口来。