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。