【GD32】02-ADC模拟数字转换器

ADC

在电子和通信技术中,ADC(模拟数字转换器)是一种将模拟信号转换为数字信号的电子设备。这种转换是电子系统中非常关键的一个环节,因为数字信号更易于处理、存储和传输。ADC的工作原理通常包括采样、保持、量化和编码等步骤。采样是从模拟信号中提取离散的值,保持是确保在采样期间信号值不变,量化是将采样值转换为最接近的数字值,而编码则是将这些数字值表示为二进制代码。ADC的性能指标包括分辨率、转换速率和精度等。

ADC在多个领域都有广泛的应用。在通信领域,ADC用于将模拟信号(如语音信号)转换为数字信号,以便在无线通信、有线通信和光纤通信系统中进行传输。在医疗领域,ADC用于将生物信号(如心电图和脑电图)转换为数字信号,以便于进行医学分析和诊断。此外,在汽车领域,ADC用于检测传感器信号,如发动机转速、车速和油位等,以实现对汽车系统的精确控制。

 以上介绍来自文心一言。

GD32E230C8T6中的ADC

GD32E230C8T6只有一个ADC,但是可以用的外部通道有10个,还是够用的。

那么我们需要看看ADC的不同通道对应着哪些GPIO。

可用的GPIO是GPIOA的0号引脚到7号引脚,以及GPIOB的0和1号引脚。

接下来我们来看看怎么使用ADC。

固件库函数

在介绍ADC相关固件库之前我们需要先打开外设时钟。 

    rcu_periph_clock_enable(RCU_ADC);

还需要指定一下ADC的时钟。

rcu_adc_clock_config

可以选择的选项在上面表格中。关于如何选择,我们还需要看看GD32E230的时钟树。

由于ADC最大只能28MHz,因此配置的时钟频率不能大于28MHz。

ADC相关的固件库函数很多,我这边就挑着讲。

adc_enable

无需参数,调用即可使能ADC外设。

当然了,这个函数我们需要等ADC配置完再调用,可以参考STM32的ADC。这边先讲是因为我按照固件库使用指南的顺序说的,函数具体调用的时机可以参考我最后的示例代码。

adc_disable

有使能就有失能。调用之后就相当于关闭了ADC外设。

adc_calibration_enable

开启ADC校准复位。也就是让ADC开始校准,在STM32中也有类似的做法,不过在GD32的固件库中我们只需要调用这个函数即可。

adc_channel_length_config

配置通道组的长度,一般来说都是用的规则组(ADC_REGULAR_CHANNEL),我们一共用到几个ADC通道,我们第二个参数就填几。

adc_regular_channel_config

设置规则组,设置rank也就是通道序列,还有ADC的通道,一般来说通道几我们的rank也就是几。还有就是采样时间,可供选择的参数可以参考上表,采样周期越长,采样结果越精确,按照实际需求配置就行。

adc_external_trigger_config

配置ADC外部触发。我们选择规则组和使能。

这个函数描述会有点歧义,我们ADC一般是由软件触发的,实际上软件触发也属于外部触发的一种,这边外部触发的外部和外部中断的外部不太一样。

adc_external_trigger_source_config

选择外部触发源,我们选择软件触发。 

adc_software_trigger_enable

开启软件转换。

adc_regular_data_read

读取规则组的ADC的转换值,但是我们需要在ADC转换之后再读取。

adc_flag_get

获取ADC的标志位,我们在读取数据之前需要等待ADC转换结束,用的就是这个函数。

adc_resolution_config

配置ADC分辨率,可以选6,8,10,12位,一般来说我们就多多益善,选择12位的分辨率。

adc_special_function_config

开启ADC特殊功能,我们这边打开扫描模式。如果有用到DMA的话可以选择连续模式。

adc_data_alignment_config

选择数据对齐方式,因为存放ADC转换结果的寄存器是16位,而我们的分辨率是小于16位的,因此我们需要选择把这12位的数据靠左放还是靠右放,一般就是右对齐。

示例代码

我们再梳理一下,首先先调用配置函数,配置函数的顺序无所谓,都可以。

然后是使能ADC,接着是校准。

最后是读取数据,开启软件触发之后我们就等待转换完毕,转换结束之后调用函数读取即可。

#include "gd32e23x.h"
#include "systick.h"
#include <stdio.h>
#include "OLED.h"


uint16_t getValue(uint8_t  ADC_CHANNEL_x){
    adc_regular_channel_config(0, ADC_CHANNEL_x, ADC_SAMPLETIME_239POINT5); //设置采集通道
    adc_software_trigger_enable(ADC_REGULAR_CHANNEL);                       //开始软件转换
    while ( adc_flag_get(ADC_FLAG_EOC) == RESET ) ;                         //等待 ADC 采样完成 
    uint16_t res = adc_regular_data_read();                                 //读取采样值
    return res;
}

int main(void){
    systick_config();       //延时函数初始化
    OLED_Init();            //OLED初始化
    
    rcu_periph_clock_enable(RCU_GPIOA);   //开启GPIOA的外设时钟
    rcu_periph_clock_enable(RCU_ADC);     //开启ADC的外设时钟
    rcu_adc_clock_config(RCU_ADCCK_APB2_DIV4);  //指定ADC的时钟为5分频的APB2(72MHz/4)

    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_0);     //将ADC的对应通道的对应引脚设为模拟输入
    adc_special_function_config(ADC_SCAN_MODE, ENABLE);                     //开启扫描模式
    adc_external_trigger_config(ADC_REGULAR_CHANNEL,ENABLE);                //开启规则组外部触发
    adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);  //配置规则组为软件触发
    adc_regular_channel_config(0, ADC_CHANNEL_0, ADC_SAMPLETIME_239POINT5); //设置规则组通道
    adc_data_alignment_config(ADC_DATAALIGN_RIGHT);                         //数据右对齐
    adc_resolution_config(ADC_RESOLUTION_12B);                              //配置分辨率为12位
    adc_channel_length_config(ADC_REGULAR_CHANNEL, 1);                      //配置规则组长度为1
    
    adc_enable();                       //使能ADC    
    adc_calibration_enable();           //开启校准
    
    uint16_t val;
    OLED_ShowString(1,1,"Hello World");
    while(1){
        val=getValue(ADC_CHANNEL_0);
        OLED_ShowNum(2,1,val,6);
        delay_ms(1000);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值