ADC(Analog to Digital Converter,模数转换器)是指将连续变化的模拟信号转换为离散的数字信号的电子器件。ADC可以将真实世界的模拟信号,例如温度、压力、声音等,转换成更容易储存、处理和发射的数字形式,因此被广泛应用在各种产品中。本期我们将通过一个读取电位器电压值的小实验来了解RV-STAR开发板上ADC的使用方法。
系统环境
Windows 10-64bit
软件平台
NucleiStudio IDE 202102版或 PlatformIO IDE
硬件需求
RV-STAR开发板
旋转电位器
GD32VF103的ADC外设
GD32VF103包含一个12位精度的ADC,它是一种采用逐次逼近方式的模拟数字转换器,它有18个多路复用通道,可以转换来自16个外部通道和2个内部通道的模拟信号。模拟看门狗允许应用程序来检测输入电压是否超出用户设定的高低阈值。各种通道的A/D转换可以配置成单次、连续、扫描或间断转换模式。ADC转换的结果可以按照左对齐或右对齐的方式存储再16位寄存器中。片上的硬件过采样机制可以通过减少来自MCU的相关计算负担来提高性能。
高性能:
- 可配置12位、10位、8位、或者6位分辨率;
- 自校准;
- 可编程采样时间;
- 数据寄存器可配置数据对齐方式;
- 支持规则数据转换的DMA请求。
模拟输入通道:
- 16个外部模拟输入通道;
- 1个内部温度传感通道(VSENSE);
- 1个内部参考电压输入通道(VREFINT)。
转换开始的发起:
转换模式:
- 转换单个通道,或者扫描一序列的通道;
- 单次模式,每次触发转换一次选择的输入通道;
- 连续模式,连续转换所选择的输入通道;
- 间断模式;
- 同步模式(适用于具有两个或多个ADC的设备)。
模拟看门狗。
中断的产生:
过采样:
- 16位的数据寄存器;
- 可调整的过采样率,从2x到256x;
- 高达8位的可编程数据移位。
ADC供电要求:2.6V到3.6V,一般电源电压为3.3V。
ADC输入范围:VREF- ≤VIN ≤VREF+。
实验部分
本次实验使用的外设部件为旋转电位器,它是一个典型的模拟器件,通过旋转旋钮可以输出0到供电电压VCC之间的模拟量。
通过查阅电路原理图得知,RV-STAR的PC0引脚对应着一个ADC复用通道,我们使用它来连接旋转电位器外设,连线参考如下表:
RV-STAR
| 旋转编码器
| PC0
| OUT
| 3V3
| VCC
| GND
| GND
|
旋转编码器的供电一定要接3V3不能接5V,否则可能因为输入电压过高而烧坏芯片。
完成电路连线之后就可以创建工程开始编写代码了,首先需要定义一系列的配置函数,用于初始化时钟、外设引脚和进行ADC的配置:
void rcu_config(void)
{
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_ADC1);
rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8);
}
void gpio_config(void)
{
gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
}
void adc_config(void)
{
/* reset ADC */
adc_deinit(ADC1);
/* ADC mode config */
adc_mode_config(ADC1, ADC_MODE_FREE);
/* ADC scan function enable */
adc_special_function_config(ADC1, ADC_SCAN_MODE, ENABLE);
/* ADC contineous function enable */
adc_special_function_config(ADC1, ADC_CONTINUOUS_MODE, ENABLE);
/* ADC data alignment config */
adc_data_alignment_config(ADC1, ADC_DATAALIGN_RIGHT);
/* ADC channel length config */
adc_channel_length_config(ADC1, ADC_REGULAR_CHANNEL, 1);
adc_external_trigger_source_config(ADC1, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_NONE);
adc_external_trigger_config(ADC1, ADC_REGULAR_CHANNEL, ENABLE);
delay_1ms( 1);
adc_enable(ADC1);
adc_calibration_enable(ADC1);
adc_software_trigger_enable(ADC1, ADC_REGULAR_CHANNEL);
adc_regular_channel_config(ADC1, 0, ADC_CHANNEL_10, ADC_SAMPLETIME_55POINT5);
}
其中,我们使用的PC0管脚对应着ADC1的通道10,编写配置函数的时候要注意,另外在本应用中,ADC被配置为独立的连续扫描模式,使用常规通道触发(即软件触发)。
在主函数中,周期性的读取ADC的值,然后打印到串口终端,对应的代码如下:
#include "nuclei_sdk_hal.h"
#include
void rcu_config(void);
void gpio_config(void);
void adc_config(void);
uint16_t adc_value;
int main(void)
{
rcu_config();
gpio_config();
adc_config();
gd_com_init(GD32_COM0);
while (1) {
delay_1ms(1000);
adc_value = adc_regular_data_read(ADC1);
printf("rn ADC1 regular channel 10 data = %d rn", adc_value);
printf("rn ***********************************rn");
}
}
以上就是完整的代码内容,完成后,将RV-STAR开发板连接到电脑,编译并上传代码,打开串口终端,旋转电位器旋钮,可以观察到打印到串口终端的读数发生了改变,说明ADC功能正常开启。
|