1.ADC在STM32进行数据采集时十分重要。通过ADC可以将外界的数字信号转换为模拟信号,以满足采样的需求。(资料参考于正点原子)
STM32 拥有 1~3 个 ADC ( STM32F101/102 系列只有 1 个 ADC ),这些 ADC 可以独立使用,
也可以使用双重模式(提高采样率)。 STM32 的 ADC 是 12 位逐次逼近型的模拟数字转换器。
它有 18 个通道,可测量 16 个外部和 2 个内部信号源。各通道的 A/D 转换可以单次、连续、扫
描或间断模式执行。 ADC 的结果可以左对齐或右对齐方式存储在 16 位数据寄存器中。
模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高 / 低阀值。
STM32 将 ADC 的转换分为 2 个通道组:规则通道组和注入通道组。 注入通道的转换可以打断规则通道的转换, 在注入通道被转换完成之 后,规则通道才得以继续转换。
配置ADC的基本步骤为:
(1)使能相应的时钟。
(2)配置相应的引脚和引脚对应的ADC。
(3)配置ADC的通道信息。
(4)进行ADC校准,并开启ADC。
2.ADC的相关寄存器:
(1) ADC 控制寄存器( ADC_CR1 和 ADC_CR2 ):
ADC_CR1:
ADC_CR2:
(2) ADC 采样事件寄存器( ADC_SMPR1 和 ADC_SMPR2 ):
ADC_SMPR1:
ADC_SMPR2:
(3) ADC 规则序列寄存器( ADC_SQR1~3 ):
(4) ADC 规则数据寄存器 (ADC_DR):
(5) ADC 状态寄存器( ADC_SR): 该寄存器保存了 ADC 转换时的各种状态。
3.代码:本文只展示adc和main部分的代码,完整的工程可结合前面的文章。
(1)adc.h:
#ifndef __ADC_H
#define __ADC_H#include "stm32f10x.h"
#include <stdio.h>void adc_init(void);#endif
(2) adc.c
#include "adc.h"void adc_init(void)
{//¶¨ÒåGPIOºÍADCÏà¹ØµÄ½á¹¹ÌåGPIO_InitTypeDef GPIO_InitStructure;ADC_InitTypeDef ADC_InitStructure;//ʹÄÜGPIOAºÍADC1µÄʱÖÓ£ºRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1,ENABLE);//ÉèÖÃADCµÄʱÖÓ£ºRCC_ADCCLKConfig(RCC_PCLK2_Div6); //ÉèÖÃΪ6·ÖƵ£¬72/6=12£¬×î´ó²»Äܳ¬¹ý14M//ÅäÖÃPA1Òý½Å£ºGPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //Ä£ÄâÊäÈëGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//ÅäÖÃADCµÄÏà¹ØÐÅÏ¢£ºADC_DeInit(ADC1); //¸´Î»ADC,ʹµÃADCµÄËùÓмĴæÆ÷µÄֵΪȱʡֵADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADCµÄ¹¤×÷ģʽADC_InitStructure.ADC_ScanConvMode = DISABLE; //ÊÇ·ñɨÃ裬µ¥Í¨µÀʱ²»ÐèҪɨÃèADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //ÊÇ·ñÁ¬Ðøת»»ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //ADCµÄ´¥·¢·½Ê½£¬ÕâÀïÑ¡ÔñÈí¼þ´¥·¢ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //Ö¸¶¨ADCÊý¾ÝÓÒ¶ÔÆëADC_InitStructure.ADC_NbrOfChannel = 1; //ÉèÖÃADCÒª½øÐÐת»»µÄͨµÀÊýÁ¿ADC_Init(ADC1,&ADC_InitStructure); //ÅäÖÃADC1µÄ³õʼ»¯ADC_Cmd(ADC1,ENABLE); //ʹÄÜADC1//ÉèÖÃADC1µÄ¹æÔòת»»Í¨µÀ£ºADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5); //ADC1,ͨµÀ1£¬¹æÔòת»»Ë³ÐòΪ1£¬²ÉÑùʱ¼äΪ239.5¸öÖÜÆÚ//Ò»¶¨Òª½øÐÐУ׼£¬·ñÔò»áÓ°Ïì²ÉÑùµÄ׼ȷÐÔADC_ResetCalibration(ADC1); //adc1¸´Î»Ð£×¼while(ADC_GetResetCalibrationStatus(ADC1)); //µÈ´ý¸´Î»Ð£×¼½áÊøADC_StartCalibration(ADC1); //¿ªÆôADCУ׼while(ADC_GetCalibrationStatus(ADC1)); //µÈ´ýУ׼Íê³É//ADC_SoftwareStartConvCmd(ADC1, ENABLE); //Èí¼þ¿ªÆôADCת»»
}
(3) main.c:
#include "stm32f10x.h"
#include "USART.h"
#include <stdio.h>
#include "adc.h"extern u8 data;int main(void)
{uint16_t adc;float temp;//ÖжÏÓÅÏȼ¶·Ö×飺NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//³õʼ»¯´®¿ÚUSART1:usart_init(9600);adc_init();while(1){ADC_SoftwareStartConvCmd(ADC1, ENABLE); //Èí¼þ¿ªÆôADCת»» while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)) //µÈ´ýADCת»»Íê³Éadc = ADC_GetConversionValue(ADC1); //»ñȡת»»½á¹ûtemp = (float)adc*(3.3/4096); //3.3/4096Ϊ²ÉÑù¾«¶È£¬3.3vµÄÁ¿³Ì£¬12λADCÔòΪ4096. printf("ADC = %f\r\n",temp);}return 0;
}
4. 运行结果:
5.总结:
本文介绍了STM32的ADC,在设计ADC采样时需要去了解相应的寄存器功能,然后利用结构体信息完成初始化。ADC在使用之前应该先进行校准,以提高采样的精确度。此外,需要注意在配置ADC的时钟时不能超过14M。