首页 > 其他分享 >GD32F303RCT6(5)-ADC采样内部温度和参考电压

GD32F303RCT6(5)-ADC采样内部温度和参考电压

时间:2024-07-26 11:25:40浏览次数:14  
标签:采样 GD32F303RCT6 转换 ADC ADC0 通道 config adc

        ADC(模数转换器)是用于将模拟电压信号转换成数字量的电路单元,是模拟信号数字化的必要器件。独立的ADC芯片和MCU连接构成信号数字化电路

1、主要特性

        (1)高性能:可配置为12位、10位、8位或6位分辨率;具前置校准功能;可编程采样时间;数据存储模式分最高有效位对齐和最低有效位对齐;可处理DMA请求

        (2)模拟输入通道:16个外部模拟输入通道,还有一个内部温度传感通道(VSENSE)和一个内部参考电压通道(VREFINT)

        (3)运行模式分为软件触发和硬件触发

        (4)转换模式:转换单次通道(扫描一序列的通道);单次运行模式(每次触发转换一次选择的输入通道);连续运行模式(连续转换所选择的输入通道);间断运行模式;同步模式(适用于两个或多个ADC的设备)

2、工作原理

ADC模块框图如图所示

2.1 模拟部分供电

        模拟部分的供电有四个引脚

        (1)VDDA是模拟部分工作电源,可以选择使用独立的模拟电源输入,来保证ADC的精度。VAAD最高不能超过3.6V,最低不低于2.6V,可以选择将VDDA与数字电源VDD连接。

        (2)VSSA是模拟电源地,与数字电源共地。

        (3)VREF+是ADC转换的正参考电压,最高不能超过VDDA,最低不能低于2.6V,一般选择将VREF+与VDDA连接。

        (4)VREF-是ADC转换的负参考电压,必须与VSSA连接。

2.2 输入通道

        每个ADC单元都有16个外部输入通道,对应16个ADC输入复用引脚,即结构框图中的ADC_IN0至ADC_IN15。除此之外还额外包括两个内部输入使用通道,温度传感器通道(ADC0_CH16)和VREFINT通道(ADC0_CH17)

        使用温度传感器:

                1. 配置温度传感器通道(ADC_IN16)的转换序列和采样时间为 ts_temp µs

                2. 置位 ADC_CTL1 寄存器中的 TSVREN 位,使能温度传感器

                3. 置位 ADC_CTL1 寄存器的ADCON 位,或者由外部触发启动ADC 转换

                4. 读取内部温度传感器输出电压 Vtemperature,

                并由此公式计算出实际温度:温度 (°C) = {(V_{25}   – V temperature ) / Avg_Slope} + 25

        其中V_{25}是内部温度传感器在25℃下的电压,为1.405V;Avg_Slope是温度与内部温度传感器输出电压曲线的均值斜率,为4.5mV/℃;ts_temp µs是读取温度时的ADC采样时间,为17.1us。

2.3 规则通道和注入通道

        选择的多个模拟输入通道可以分为两组:规则通道组和注入通道组,每个组的通道构成一个转换序列。

        规则转换序列最多可以设置16个通道,一个规则转换序列规定了多路复用转换时的顺序。例如,选择了IN0、IN1、IN2共3个通道作为规则通道,定义的规则转换序列可以是IN0、IN1、IN2,也可以是IN0、IN2、IN1,也可以是IN1、IN2、IN0。

        注入通道就是可以在规则通道转换过程中插入进行转换的通道,类似于中断的现象。注入转换序列最多可以设置4个注入通道,也可以像规则转换序列那样设置转换序列。

        每个注入通道还可以设置一个数据偏移量,每次转换结果自动减去这个偏移量,所以转换结果可以是负数。例如,设置偏移量为信号的直流分量,每次转换自动减去直流分量。

2.4 启动或触发转换

        规则通道和注入通道有单独的触发源,有3类启动或触发转换的方式:

        (1)软件启动:直接将控制寄存器ADC_CR2的ADON的位置1启动ADC转换,写入0时停止ADC转换,这种方式常用于轮询方式的ADC转换。

        (2)内部定时器触发:可以选择某个定时器的触发输出信号(TRGO)或输入捕获信号作为触发源。例如,选择TIM2_TRGO信号作为启动触发信号,而TIM2的TRGO设置为UEV事件信号,这样定时器TIM2每次定时溢出时就启动一次转换。这种方式可用于周期性ADC转换。

        (3)外部IO触发:可以选择外部中断线EXTI_11和EXTI_15作为规则组或注入组的外部中断触发源。

2.5 ADC时钟与转换时间

        ADC转换需要时钟信号ADCCLK驱动,ADCCLK有PCLK2经过分频产生,最少2分频,最多8分频。PCLK2的最高频率为84MHz,所以ADCCLK的最高频率为42MHz。

        我们可以设置在N个ADCCLK周期内对信号进行采样,N取值最小为3,最大为480。在ADC上电后,在开始精确转换之前,需要一段稳定时间t_{STAB},对于之后接下来的转换就不需要稳定延迟,而且ADON位只需要被置位一次。一次ADC转换需要14个时钟周期,在转换完成后EOC标志被置位,同时转换结果保存在10位ADC数据寄存器里面,ADC转换完成需要N+12个时钟周期。

        例如,PCLK2的频率位84MHz,ADC使用2分频,则ADCCLK的频率位42MHz,若将采样设置为15次,则一次转换的时间为:

                                                        t_{c}=\frac{15+12}{42×10^{6}}=0.64us

        可以设置在转换完一个通道后就产生EOC信号,也可以设置在转换完一个序列后产生EOC信号。

2.6 转换结果数据寄存器

        ADC完成转换后将结果数据存入数据寄存器,规则通道和注入通道有不同的数据寄存器。

        规则通道只有一个数据寄存器ADC_DR,只有低16位有效。在多通道转换时,如果前一通道转换结束后,ADC_DR的数据未被及时读出,下一个通道的转换结果就会覆盖上一次结果的数据。所以,在多通道转换时,一般在EOC中断里及时读取或者通过DMA将数据传输到内存里。

        注入通道有4个数据寄存器,分别对应四个注入通道的转换结果。

        规则数据寄存器和注入数据寄存器都是低16位有效,因为转换结果数据最多12有效,可以设置数据左对齐或右对齐,一般使用右对齐。

2.7 模拟看门狗

        可以使用模拟看门狗对某一个通道的模拟电压进行监测,设置一个阈值上限和下限(12位数表示的数值,0-4095),当监测的模拟电压ADC结果超出范围时,就产生模拟看门狗中断。

2.8 转换结果电压计算

        ADC的转换结果是一个数字量,与实际的模拟电压之间的计算关系由VREF+和转换精度位数确定。

2.9 多重ADC模式

        GD32F30x系列有3个ADC,这3个ADC可以独立工作,也可以组成双重或三重工作模式。

        多重模式就是使用主器件ADC0的触发信号去交替触发或同步触发其他ADC启动转换。例如,对于三分量模输出的振动传感器,需要对X、Y、Z这三个方向的振动信号同步采集,以合成一个三维空间中的振动矢量,这是就需要使用3个ADC对3路信号同步采集,而不能使用一个ADC对3路信号通过多路复用进行采集。

        多重ADC对多种工作模式,可以交替出发,也可以同步触发。设置ADC0和ADC1双重同步工作模式时,为ADC0设置的触发源同时也ADC1,以实现两个ADC同步转换。在多重模式下,有一个专门的32位数据寄存器ADC_CDR,用于存储多重模式下的转换结果数据。在双重模式下,ADC_CDR的高16位存储ADC1的规则转换结果数据,ADC_CDR的低16位存储ADC0的规则转换结果数据。

        在多重模式下,使用DMA进行数据传输有3种模式,其中DMA模式2适用于双重ADC的数据传输。双重ADC时,DMA模式2的工作特点是:每发送一个DMA请求,就以字的形式传输表示ADC1和ADC0转换结果的32位数据,其中高16位是ADC1的转换结果;低16位是ADC0的转换结果,相当于将ADC_CDR的数据在一个DMA请求时传输出去。

        在双重ADC同步模式下,两个ADC不能转换同一个通道。两个ADC的规则转换序列的通道个数应该相同,每个通道的采样点数也应该相同,以使得两个ADC能保持同步。

3、ADC采样代码示例

3.1 软件触发采样内部温度和参考电压

 adc.c

void rcu_config(void)
{
    rcu_periph_clock_enable(RCU_ADC0);  //使能ADC时钟

		rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6);		//配置ADC预分频因子,预分频器选择CK_APB2/6
}

void adc_config(void)
{
        adc_mode_config(ADC_MODE_FREE);  //ADC模式配置,选择所有ADC独立工作

		adc_data_alignment_config(ADC0,ADC_DATAALIGN_RIGHT);  //ADC数据右对齐

		adc_special_function_config(ADC0,ADC_SCAN_MODE,ENABLE);  //使能ADC_SCAN功能

        adc_channel_length_config(ADC0,ADC_INSERTED_CHANNEL,2);//配置常规通道组长度为 2

		adc_inserted_channel_config(ADC0, 0, ADC_CHANNEL_16, ADC_SAMPLETIME_239POINT5);  	//温度传感器通道配置,采样值配置为239.5cycles,序列号为0

		adc_inserted_channel_config(ADC0, 1, ADC_CHANNEL_17, ADC_SAMPLETIME_239POINT5);		//内部参考电压通道配置,采样值配置为239.5cycles,序列号为1

        adc_external_trigger_config(ADC0,ADC_INSERTED_CHANNEL,ENABLE);		//启动外部触发

		adc_external_trigger_source_config(ADC0, ADC_INSERTED_CHANNEL, ADC0_1_2_EXTTRIG_INSERTED_NONE);		//配置ADC外部触发源,选择为软件触发

        adc_tempsensor_vrefint_enable();  //使能温度触发器和Vrefint通道
    
        adc_enable(ADC0);		//ADC0接口使能
        delay_1ms(1);    

		adc_calibration_enable(ADC0);		//启用ADC0的校准,并重置校准
}

 main.c


int main(void)
{
    rcu_config();  

	systick_config();  
    /* ADC configuration */
    adc_config();
	uart0_init(115200);
    while(1)
    {
        adc_software_trigger_enable(ADC0, ADC_INSERTED_CHANNEL);		//使能软件触发
		delay_1ms(2000);
        /* value convert  */
        temperature = (1.43 - ADC_IDATA0(ADC0)*3.3/4096) * 1000 / 4.3 + 25;//计算方法useer_menu中有
        vref_value = (ADC_IDATA1(ADC0) * 3.3 / 4096);
      
        /* value print */
        u1_printf(" the temperature data is %2.0f degrees Celsius,the reference voltage data is %5.3fV \r\n", temperature,vref_value);//用的是自定义打印函数,在uart.c中定义
		
	}
}

功能验证

可以通过串口调试助手查看打印结果

3.2 定时器触发DMA传输ADC转换

adc.c

#include "gd32f30x.h"
#include "adc.h"
#include "systick.h"

uint32_t adc_value[2];		//DMA传输缓冲区


void rcu_config(void)
{
    rcu_periph_clock_enable(RCU_GPIOA);  
    rcu_periph_clock_enable(RCU_GPIOC);
	
    rcu_periph_clock_enable(RCU_DMA0);
	
    rcu_periph_clock_enable(RCU_TIMER0);

    rcu_periph_clock_enable(RCU_ADC0);  //使能ADC时钟
    rcu_periph_clock_enable(RCU_ADC0);  //使能ADC时钟

		rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6);		//配置ADC预分频因子,预分频器选择CK_APB2/6
}

void gpio_config(void)
{
		gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_3|GPIO_PIN_5);		//GPIOC_PIN3:ADC0_IN13    GPIOC_PIN5:ADC0_IN15
		gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);  				//GPIOA_PIN8:TIMER0_CH0
}

void adc_config(void)
{
    adc_mode_config(ADC_DAUL_REGULAL_FOLLOWUP_FAST);  //ADC模式配置,选择所有ADC独立工作
	
    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);		//ADC数据右对齐
    adc_data_alignment_config(ADC1, ADC_DATAALIGN_RIGHT);
	
    adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);  //使能ADC_SCAN功能
    adc_special_function_config(ADC1, ADC_SCAN_MODE, ENABLE);
	
    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL,2);		//配置规则通道组,长度为2
    adc_channel_length_config(ADC1, ADC_REGULAR_CHANNEL,2);
	
    adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_13, ADC_SAMPLETIME_239POINT5);		//配置ADC0、1的规则转换序列
    adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_15, ADC_SAMPLETIME_239POINT5);
    adc_regular_channel_config(ADC1, 0, ADC_CHANNEL_15, ADC_SAMPLETIME_239POINT5);
    adc_regular_channel_config(ADC1, 1, ADC_CHANNEL_13, ADC_SAMPLETIME_239POINT5);
	
    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);		//规则通道使能
    adc_external_trigger_config(ADC1, ADC_REGULAR_CHANNEL, ENABLE);
	
    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_T0_CH0);			//定时器T0触发
    adc_external_trigger_source_config(ADC1, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);			//软件触发

    adc_enable(ADC0);
    delay_1ms(1);    
    adc_calibration_enable(ADC0);

    adc_enable(ADC1);
    delay_1ms(1);    
    adc_calibration_enable(ADC1);

    adc_dma_mode_enable(ADC0);		//使能DMA传输

}

void dma_config(void)
{
    dma_parameter_struct dma_data_parameter;		//DMA配置结构体
    dma_deinit(DMA0, DMA_CH0);

    dma_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));
    dma_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;		//外设地址不自增
    dma_data_parameter.memory_addr = (uint32_t)(adc_value);					//缓冲区地址
    dma_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;			//存储器地址自增
    dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_32BIT;
    dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_32BIT;
    dma_data_parameter.direction = DMA_PERIPHERAL_TO_MEMORY;				//外设到存储器
    dma_data_parameter.number = 2;
    dma_data_parameter.priority = DMA_PRIORITY_HIGH;  							//优先级等级高
    dma_init(DMA0, DMA_CH0, &dma_data_parameter);
	
    dma_circulation_enable(DMA0, DMA_CH0);
    dma_channel_enable(DMA0, DMA_CH0);  

	
}


void timer_config(void)
{
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;
	
    timer_initpara.prescaler         = 8399;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 9999;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER0, &timer_initpara);
	
    timer_channel_output_struct_para_init(&timer_ocintpara);
    timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
    timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
    timer_channel_output_config(TIMER0, TIMER_CH_0, &timer_ocintpara);

    timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, 3999);
    timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(TIMER0, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);
	
    timer_primary_output_config(TIMER0, ENABLE);
    timer_auto_reload_shadow_enable(TIMER0); 
    timer_enable(TIMER0);

	
}

main.c

#include <string.h>
#include "uart.h"  //调用u1_u1_printf作为打印函数
#include "gd32f30x.h"
#include "systick.h"
#include <stdio.h>
#include "stdarg.h"
#include "adc.h"
int main(void)
{
    /* system clocks configuration */
    rcu_config();
    /* configure systick */
    systick_config();  
    /* GPIO configuration */
    gpio_config();
    /* TIMER configuration */
    timer_config();
    /* DMA configuration */
    dma_config();
    /* ADC configuration */
    adc_config();
    /* configure COM port */
		uart0_init(115200);
    while(1){
        delay_1ms(2000);
        u1_printf(" the data adc_value[0] is %08X \r\n",adc_value[0]);
        u1_printf(" the data adc_value[1] is %08X \r\n",adc_value[1]);
        u1_printf("\r\n");
    }
}

功能验证

总结

        ADC的配置基本流程当中都有,关键步骤都有注释,不同模式的差别便是触发源,规则转换序列等。

标签:采样,GD32F303RCT6,转换,ADC,ADC0,通道,config,adc
From: https://blog.csdn.net/weixin_72587039/article/details/140682566

相关文章

  • 过采样SMOTE逻辑回归、SVM、随机森林、AdaBoost和XGBoost对不平衡数据分析预测
    全文链接:https://tecdat.cn/?p=37115原文出处:拓端数据部落公众号分析师:YimengLi近几年,伴随着互联网的发展,在线食品配送业务成为了新潮流。在此背景下,我们帮助客户对“在线食品交付偏好-班加罗尔地区”数据开展研究,建立印度在线食品配送平台消费者的用户画像,研究影响顾客购买意......
  • ADC滤波的10种经典算法
    A、方法:根据经验判断,确定两次采样允许的最大偏差值(设为A)每次检测到新值时判断:如果本次值与上次值之差<=A,则本次值有效如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值B、优点:能有效克服因偶然因素引起的脉冲干扰C、缺点无法抑制那种周期性的干扰......
  • ADC相关参数定义与测试方法
    1ADC静态参数1.1GainError    ADC实际传输曲线斜率偏离理想斜率的程度。即补偿失调误差之后,输出曲线最后的实际偏差。    修正失调电压误差后,额定满量程代码与理想输入信号码值之间的差值,即GainError = Full-scaleError-OffsetError。1.2 Off......
  • ADC参数ENOB、有效分辨率、无噪声分辨率的理解及计算
    1、ENOB是有效位数:        对应于AC输入,是一项有关转换器对于AC信号的非线性性能指标,表示一个ADC在特定输入频率和采样率下的动态性能;2、有效分辨率与无噪声分辨率测量的是ADC在DC下的噪声性能;        ☆不要将有效分辨率和ENOB混淆;3、最好从直流特性入手......
  • AD模数转换(ADC)在音频处理中的详细深度讲解
    AD模数转换(Analog-to-DigitalConversion,简称ADC)是将模拟信号转换为数字信号的过程。对于音频处理来说,ADC是音频录制、数字音频处理和传输的关键步骤。以下是对AD模数转换在音频方面的详细讲解:1.ADC的基本原理ADC的过程包括以下几个步骤:采样(Sampling):将连续变化的模拟信号在时......
  • 【微型气体采样泵】技术调研记录(2)相关问题
    目录一、电压波动运行特性二、电机启动与电源选择三、电池供电特性四、隔膜泵脉冲现象及其影响与对策五、调速机制5.1PWM调速5.2节流阀调速一、电压波动运行特性工业设备在标准电压下运行最为理想,但实际应用中电压常在额定值上下波动,通常允许范围在±10%内。若电......
  • Android 四大组件 Activity、Service、Broadcast、Content Provider
    一、Android四大组件Activity、Service、Broadcast、ContentProvider1、Activity:1.1、打开App内部Activity:Intentintent=newIntent(SourceActivity.this,TargetActivity.class);startActivity(intent); 1.2、打开Activity并获取返回结果(类似模式对话框): 主Activit......
  • STM32F407外设ADC配置流程及代码示例
    STM32F407外设ADC配置流程及代码示例STM32的ADC(模拟-数字转换器)是STM32微控制器系列中集成的一个关键外设,用于将模拟信号(如温度、压力、光强等传感器输出的电压或电流信号)转换为数字信号,以便微控制器能够处理和分析这些信号。ADC配置流程:时钟配置:启用GPIOF和ADC的时钟。这是......
  • MS5199T芯片解决方案以及驱动程序(国产三路5VADC)
    一、MS5199T芯片介绍MS5198T/MS5199T为适合高精度测量应用的低功耗、低噪声、三通道差分输入的16bit/24bit模数转换器。其内部集成了低噪声输入缓冲器、低噪声仪表放大器,当增益设置为64,更新速率为4.17Hz时,均方根噪声为10nV。MS5198T/MS5199T还集成了低端电源......
  • CP AUTOSAR标准之ADCDriver(AUTOSAR_SWS_ADCDriver)(更新中……)
    1简介和功能概述  本规范描述了AUTOSAR基础软件模块ADC驱动程序的功能、API和配置。ADC驱动程序针对的是逐次逼近型ADC硬件。DeltaSigmaADC转换用例不在本规范的范围内。  ADC模块初始化并控制微控制器的内部模拟数字转换器单元。它提供启动和停止转换的服务,分别启......