【应用笔记】APM32F4xx_ADC应用笔记

引言

本应用笔记提供如何在APM32F4xx系列上配置和应用ADC接口的指南,包括接口框图、代码实现和应用方法。

APM32F4xx微控制器内置最多三个12位的逐次逼近型ADC,三个ADC共享最多21个外部输入通道和3个内部通道,并提供自校准功能。内部通道分别提供测量芯片内置温度传感器电压、参考电压以及备份电源电压的功能。各个A/D转换通道支持单次、连续、扫描和间断的转换方式。ADC转换的结果可以设置成左对齐或右对齐来存储在16位的数据寄存器中,并且支持DMA访问和设置模拟看门狗

ADC简介

模数转换器,ADC(Analog to Digital Converter),是一个将模拟信号转换为数字信号的器件(电路),例如将温度、湿度、压力、位置等信息转换为数字信号。但由于数字信号本身不具有实际意义,仅仅表示一个相对大小。所以ADC都需要一个参考模拟量(REF)作为转换的标准。

图 1 ADC框图

ADC分类

ADC按工作原理可以分成直接ADC和间接ADC。主要有以下几种:

并联比较型ADC;

逐次逼近型ADC;

双积分型ADC。

其中逐次逼近型ADC是一种直接ADC。由于其采样速率中等,分辨率中等,且位数较多时使用元器件较少等原因(成本较低),所以被广泛应用于集成ADC中。

 

图 2 ADC分类

A/D转换原理

A/D转换的作用是将时间、幅值连续的模拟信号转换为时间、幅值离散的数字信号。所以,A/D转换一般要经过采样保持量化编码四个过程。

A/D转换步骤

采样和保持

采样是指在时间上将模拟信号离散化,即是将时间上连续的信号转为一系列等时间间隔的信号离散序列。其中离散信号脉冲的幅度取决于输入模拟量。

量化和编码

量化是用有限个幅度值近似原来连续变化的幅度值,把模拟信号的连续幅度变为有限数量的有一定间隔的离散值。而编码则是按照一定的规律,把量化后的值用二进制数字表示。下图列举了12bits ADC的FSR为3.3V时的量化到编码的过程。其中:

N:分辨率,用于对输入进行量化的位数。理论上,n位输出的ADC能区分2n个不同等级的模拟输入电压。如下图所示,能分辨的最小输入电压步长LSB = FSR / 2n = 806uV;

FSR: Full-Scale Range,满量程;

LSB: Least Significant Bit,最低有效位;

MSB: Most Significant Bit,最高有效位。

 

图 3 量化和编码

转换时间

转换时间是指ADC从转换控制信号触发开始,到输出端得到稳定的数字信号所经过的时间。该时间受ADC类型、ADC时钟和外部输入阻抗等因素影响。

APM32中的ADC

APM32中的ADC是逐次逼近型ADC(Successive Approximation ADC),是逐个产生比较电压VREF,并逐次与输入电压分别比较,以逐渐逼近的方式进行A/D转换的。

SAR ADC的转换原理是把输入的模拟信号按规定的时间间隔采样(采样),并与一系列标准的数字信号相比较,数字信号逐次收敛,直至两种信号相等为止(量化),最后输出代表此信号的二进制数(编码)。

ADC的结构

结构上主要包括采样保持电路(S/H),比较器(COMPARATOR,COMP),SAR逻辑控制电路、时钟(CLOCK)和时序(TIMING)控制电路及DAC电路。

 

图 4 ADC结构

S/H电路

被采样的脉冲宽度一般是很短的,在下一个采样脉冲到来之前,要暂时保持所采得的样值脉冲幅度,以便进行后续转换。所以,在采样电路之后要加保持电路。下图是一个简单的采样保持电路配置框图。

 

图 5 S/H电路

DAC电路

大多SAR ADC的DAC都使用电容式DAC来提供内在的跟踪/保持功能。电容式DAC是采用电荷再分配原理来产生模拟输出电压的。电容式DAC由N个具有二进制权重值的电容器阵列再加上一个“虚拟LSB”电容器组成。

转换步骤

转换步骤数等于 ADC的分辨率,比如10bits ADC就有10个转换步骤,每个 ADC 时钟产生一个数据位。以下步骤以10bits ADC为例。采样和保持的状态,可以参考上述的S/H等效电路来理解。下面着重看下量化和编码的状态。

量化和编码状态

该状态下,每个 ADCCLK 执行一个步骤,每一步完成后 ADC 输出一位数。采用二分法进行逐次逼近到 ADC 的精度(位数)。整个转换过程如下图所示。

图 6 量化和编码状态

转换例子

比如2.5V输入到以3.3V为参考电压的SAR ADC中,则转换过程如下所示。

第一个逼近步骤时,MSB先设置为1。DAC以1/2 REF去和VIN比较,若VIN > 1/2 REF,则保持MSB = 1(反之则MSB = 0)。等待下一个ADCCLK,执行下一步。

图 7 ADC转换逼近步骤1

第二个逼近步骤时,MSB往后移动1个bit,再以3/4 REF去和VIN进行比较,若VIN > 3/4 REF,则保持MSB = 1(反之则MSB = 0)。等待下一个ADCCLK,执行下一步,一直到所有bit确定,然后输出编码值。

图 8 ADC转换逼近步骤2

转换时间

APM32F4xx中的ADC转换时间 = 采样周期 + 转换周期。

采样周期

采样周期设置决定,要注意的是,该值需要和外部电路的输入阻抗匹配。从而保证在采用阶段,采样保持电容有足够的时间充电。

转换周期

该值取决于ADC的转换精度,APM32F4xx的SAR ADC默认为12bits,可配置为12、10、8、6bits。

表格 1 ADC精度和转换周期关系

序号

ADC精度

转换周期

1

12 bits

12 x ADCCLK

2

10 bits

10 x ADCCLK

3

8 bits

8 x ADCCLK

4

6 bits

6 x ADCCLK

转换数值

ADC 转换的数值 = (VIN x 2n) / VREF,n为ADC的分辨率。以上述12bits的ADC为例,则

ADC 转换的数值 = (VIN x 4096) / VREF。

ADC的配置和应用

转换周期

输入通道

MINI Board已经将部分ADC的通道通过排针接出,可以根据设计需求使用相关IO。ADC采样容易受外接干扰,使用时注意引脚间的抗干扰设计,以及避免ADC引脚和其他功能电路共用的情况。  

电压输入范围

ADC的电压输入范围为VREF- ~ VREF+,MINI板上的VSSA和VREF-接入GND,而VDDA和VREF+接入VDD,所以在MINI板上的ADC电压输入范围是0V ~ 3.3V。

软件设计

软件设计上只讲解关键的配置,部分查询和逻辑代码未设计,详细可直接参考本应用说明配套的例程。

ADC初始化结构体

ADC_Config_T结构体定义在APM32F4xx_adc.h文件中,具体定义如下:

/**

 * @brief ADC configuration Mode

 */

typedef struct

{

    ADC_RESOLUTION_T    resolution;

    uint8_t             scanConvMode;

    uint8_t             continuousConvMode;

    ADC_EXT_TRIG_EDGE_T extTrigEdge;

    ADC_EXT_TRIG_CONV_T extTrigConv;

    ADC_DATA_ALIGN_T    dataAlign;

    uint8_t             nbrOfChannel;

} ADC_Config_T;

结构体中的参数含义:

resolution:用于配置ADC的分辨率,可以配ADC的分辨率为12bit、10bit、8bit和6bit。如本应用说明SAR ADC转换原理所述,ADC的分辨率配置越高,相对的转换时间也越长;

scanConvMode:用于配置是否使扫描模式,一般单通道A/D转换应用时配置为DISABLE,多通道A/D转换应用时配置为ENABLE;

continuousConvMode:用于配置是单次转换,还是启用自动连续转换模式;

extTrigEdge:用于配置外部触发的极性,如果未使能外部触发,可配置为ADC_EXT_TRIG_EDGE_NONE;

extTrigConv:用于配置外部触发源;

dataAlign:用于配置ADC转换结果的数据对齐方式,一般按照习惯,我们配置为右对齐模式;

nbrOfChannel:用于配置A/D转换通道的数目。

ADC通用初始化结构体

ADC_ CommonConfig _T结构体定义在APM32F4xx_adc.h文件中,具体定义如下:

/**

 * @brief ADC Common Init structure definition

 */

typedef struct

{

    ADC_MODE_T         mode;

    ADC_PRESCALER_T    prescaler;

    ADC_ACCESS_MODE_T  accessMode;

    ADC_TWO_SAMPLING_T twoSampling;

} ADC_CommonConfig_T;

结构体中的参数含义:

mode:用于配置ADC的工作模式,有独立模式、双重模式和三重模式的配置项可供选择;

prescaler:用于配置ADC时钟的分频系数,ADC时钟由PCLK2提供。PCLK2除以prescaler就是ADC的时钟;

accessMode:用于配置DMA模式;

twoSampling:用于配置两个采样阶段间的延迟。

单通道转换软件设计

以“ADC_ContinuousConversion”例程为例。

配置ADC

开启GPIO时钟后,配置GPIO为模拟输入模式。

/*!

 * @brief       ADC Init

 *

 * @param       None

 *

 * @retval      None

 */

void ADC_Init(void)

{

    GPIO_Config_T   gpioConfig;

    ADC_Config_T    adcConfig;

    /** Enable GPIOA clock */

    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);

    /** ADC channel 0 configuration */

    GPIO_ConfigStructInit(&gpioConfig);

    gpioConfig.mode    = GPIO_MODE_AN;

    gpioConfig.pupd    = GPIO_PUPD_NOPULL;

    gpioConfig.pin     = GPIO_PIN_0;

    GPIO_Config(GPIOA, &gpioConfig);

配置ADC工作方式,开启连续转换模式。

/** Enable ADC clock */

    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);

    /** ADC configuration */

    ADC_Reset();

    ADC_ConfigStructInit(&adcConfig);

    adcConfig.resolution          = ADC_RESOLUTION_12BIT;

    adcConfig.continuousConvMode  = ENABLE;

    adcConfig.dataAlign           = ADC_DATA_ALIGN_RIGHT;

    adcConfig.extTrigEdge         = ADC_EXT_TRIG_EDGE_NONE;

    adcConfig.scanConvMode        = DISABLE;

    ADC_Config(ADC1, &adcConfig);

配置开启ADC中断,使能ADC并软件触发转换。

/** ADC channel 0 Convert configuration */

ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_0, 1, ADC_SAMPLETIME_112CYCLES);

    /** Enable complete conversion interupt */

    ADC_EnableInterrupt(ADC1, ADC_INT_EOC);

    /** NVIC configuration */

    NVIC_EnableIRQRequest(ADC_IRQn, 1, 1);

    /** Enable ADC */

    ADC_Enable(ADC1);

    /** ADC start conversion */

    ADC_SoftwareStartConv(ADC1);

}

ADC中断服务函数

检测到转换完成后,回调该中断服务函数。并读取此时的ADC转换值,然后将其转换成对应电压值,该值受量化误差和硬件抗干扰能力所影响。这里转换出来的电压单位是mV。

/*!

 * @brief       ADC interrupt service routine

 *

 * @param       None

 *

 * @retval      None

 */

void ADC_Isr(void)

{

    uint16_t adcData = 0;

    uint16_t voltage = 0;

    if (ADC_ReadStatusFlag(ADC1, ADC_FLAG_EOC))

    {

        ADC_ClearStatusFlag(ADC1, ADC_FLAG_EOC);

        adcData = ADC_ReadConversionValue(ADC1);

        voltage = (adcData * 3300) / 4095;

        printf("\r\n voltage : %d mV\r\n", voltage);

    }

}

多通道扫描软件设计

以“ADC_MultiChannelScan”例程为例。

定义公共信息

这里定义了本样例采样的通道数为3个通道,并定义了将用于DMA存储ADC各通道扫描数据的数组adcData[ADC_CH_SIZE]。另外还宏定义了ADC规则数据寄存器的地址为ADC_DR_ADDR。以上这些信息都会用于后续配置和应用中。

/** save adc data*/

#define ADC_CH_SIZE         3

#define ADC_DR_ADDR         ((uint32_t)ADC1_BASE + 0x4C)

uint16_t adcData[ADC_CH_SIZE];

配置DMA

将ADC的规则寄存器地址设置为DMA访问的寄存器地址,设置寄存器递增并规定buffer的大小为3,最后开启循环模式。

DMA的不同通道和数据流规定了其所属的外设,使用时要注意。

/*!

 * @brief       DMA Init

 *

 * @param       None

 *

 * @retval      None

 */

void DMA_Init(void)

{

    DMA_Config_T dmaConfig;

   

    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_DMA2);

   

    dmaConfig.peripheralBaseAddr = ADC_DR_ADDR;

    dmaConfig.memoryBaseAddr = (uint32_t)&adcData;

    dmaConfig.dir = DMA_DIR_PERIPHERALTOMEMORY;

    dmaConfig.bufferSize = ADC_CH_SIZE;

    dmaConfig.peripheralInc = DMA_PERIPHERAL_INC_DISABLE;

    dmaConfig.memoryInc = DMA_MEMORY_INC_ENABLE;

    dmaConfig.peripheralDataSize = DMA_PERIPHERAL_DATA_SIZE_HALFWORD;

    dmaConfig.memoryDataSize = DMA_MEMORY_DATA_SIZE_HALFWORD;

    dmaConfig.loopMode = DMA_MODE_CIRCULAR;

    dmaConfig.priority = DMA_PRIORITY_HIGH;

    dmaConfig.fifoMode = DMA_FIFOMODE_DISABLE;

    dmaConfig.fifoThreshold = DMA_FIFOTHRESHOLD_HALFFULL;

    dmaConfig.memoryBurst = DMA_MEMORYBURST_SINGLE;

    dmaConfig.peripheralBurst = DMA_PERIPHERALBURST_SINGLE;

    dmaConfig.channel = DMA_CHANNEL_0;

    DMA_Config(DMA2_Stream0,&dmaConfig);

   

    DMA_Enable(DMA2_Stream0);

}

配置ADC

和单通道转换配置顺序一样,首先将要扫描的三个通道开启相应时钟和配置为模拟输入模式。

/*!

 * @brief       ADC Init

 *

 * @param       None

 *

 * @retval      None

 */

void ADC_Init(void)

{

    GPIO_Config_T           gpioConfig;

    ADC_Config_T            adcConfig;

    ADC_CommonConfig_T      adcCommonConfig;

    /** Enable GPIOA clock */

    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);

    /** ADC channel 0 configuration */

    GPIO_ConfigStructInit(&gpioConfig);

    gpioConfig.mode    = GPIO_MODE_AN;

    gpioConfig.pupd    = GPIO_PUPD_NOPULL;

    gpioConfig.pin     = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2;

    GPIO_Config(GPIOA, &gpioConfig);

接着是ADC的通用配置。

    /** Enable ADC clock */

    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);

    /** ADC configuration */

    ADC_Reset();

   

    adcCommonConfig.mode            = ADC_MODE_INDEPENDENT;

    adcCommonConfig.prescaler       = ADC_PRESCALER_DIV2;

    adcCommonConfig.accessMode      = ADC_ACCESS_MODE_DISABLED;

    adcCommonConfig.twoSampling     = ADC_TWO_SAMPLING_20CYCLES;

    ADC_CommonConfig(&adcCommonConfig);

然后是ADC工作模式的配置,这里配置为连续扫描模式,并设置转换通道数为3个。

    ADC_ConfigStructInit(&adcConfig);

    adcConfig.resolution            = ADC_RESOLUTION_12BIT;

    adcConfig.scanConvMode          = ENABLE;

    adcConfig.continuousConvMode    = ENABLE;

    adcConfig.dataAlign             = ADC_DATA_ALIGN_RIGHT;

    adcConfig.extTrigEdge           = ADC_EXT_TRIG_EDGE_NONE;

    adcConfig.extTrigConv           = ADC_EXT_TRIG_CONV_TMR1_CC1;

    adcConfig.nbrOfChannel          = ADC_CH_SIZE;

    ADC_Config(ADC1, &adcConfig);

配置各通道的转换顺序及采样周期。

/** ADC channel Convert configuration */

ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_0,

ADC_SAMPLETIME_480CYCLES);

ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_1, 2, ADC_SAMPLETIME_480CYCLES);

ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_2, 3, ADC_SAMPLETIME_480CYCLES);

最后开启DMA、使能ADC并触发转换。到这里多通道扫描的配置就完成了,接着直接轮询ADC转换值存储的数组即可获得各通道的扫描值。

    /** Config DMA*/

    DMA_Init();

   

    /** Enable ADC DMA Request*/

    ADC_EnableDMARequest(ADC1);

   

    /** Enable ADC DMA*/

    ADC_EnableDMA(ADC1);

    /** Enable ADC */

    ADC_Enable(ADC1);

    /** ADC start conversion */

    ADC_SoftwareStartConv(ADC1);

}

提高采样精度的硬件方法

1. 保证参考电压噪声最小化;

2. IO引脚串扰最小化;

3. 加入屏蔽减少EMI;

4. PCB将模拟和数字分开布局和铺设。

提高采样精度的软件方法

采样平均

在硬件抗干扰能力不足的情况下,我们可以牺牲采用速率,采用软件方法进行滤波,从而得到更加稳定的采样值。

数字信号滤波

可通过数字低通、高通等滤波器进行软件滤波。比如知道被测信号中的噪声来自50 Hz供电线,通过适当的数字滤波,可以只抑制50 Hz频率并传输无此噪声的数据信号。

ADC软件校准

如果采样值较为固定,但离目标值相差大,还可以利用线性拟合(线性校准曲线)的方式让采样值更接近目标值。

采样

首先基于标准源表采样足够多的点,如下表(点数越多,拟合越准确)。

表格 2 采样表

序号

采样值(mV)

目标值(mV)

1

96.7

100

2

194.5

200

3

498.8

500

4

796

800

5

1495

1500

拟合

在数学工具(Matlab或Excel等)中做线性拟合(线性、多项式、指数皆可),得到校准公式和相关系数R值。

 

图 9 拟合

校准

用拟合步骤中得到的校准公式对采样值进行校准。

表格 3采样表

序号

采样值(mV)

目标值(mV)

校准值(mV)

1

96.7

100

100.1

2

194.5

200

197.9

3

498.8

500

502.5

4

796

800

799.9

5

1495

1500

1499.4

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值