一、相关重要库函数
ADC通用初始化函数ADC_Commonlnit
void ADC_Commonlnit(ADC_CommonlnitTypeDef* ADC_CommonlnitStruct);
结构:
typedef struct
{
//参数用来配置ADC_CCR寄存器的相关参数
uint32_t ADC_Mode;//多重ADC选择模式,单通道独立模式
uint32_t ADC_Prescaler;//ADC预分频。ADC时钟是APB2经过预分频得来的。预分频系数可选择2、4、6、8分频,选择预分频系数要注意:经过预分频后的数不能超过32兆。
uint32_t ADC_DMAAccessMode;//DMA访问模式。是否开启DMA模式
uint32_t ADC_TowSamplingDelay;//2个采样阶段之间的延迟。决定延迟多少个周期:5~20个周期
} ADC_CommonlnitTypeDef;
举例:
void ADC_Commonlnit(ADC_CommonlnitTypeDef* ADC_CommonlnitStruct)
ADC_CommonlnitTypeDef ADC_CommonlnitABC;
ADC_CommonlnitABC.ADC_Mode=ADC_Mode_Independent;//独立模式
ADC_CommonlnitABC.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟
ADC_CommonlnitABC.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;//DMA失能
ADC_CommonlnitABC.ADC_Prescaler=ADC_Prescaler_Div4;//预分频系数为4
ADC_Commonlnit(&ADC_CommonlnitStructure);
ADC初始化函数ADC_Init
void ADC_Init(ADC_TypeDef* ADCx,ADC_InitTypeDef* ADC_InitStruct);
结构:
typedef struct
{
//配置某一个ADC的相关参数
uint32_t ADC_Resolution;//ADC分辨率。ADC的分辨率可以为12、10、8、6四种分辨率
FunctionalState ADC_ScanConvMode;//是否使用扫描模式。实际上是选择控制寄存器ADC_CR1的第八位Scan位
FunctionalState ADC_ContinuousConvMode;//设置连续或者单次转换。ENABLE和DISABLE
uint32_t ADC_ExternalTrigConvEdge;//外部触发使能。上升、下降、双边沿或不使用
uint32_t ADC_ExternalTrigConv;//触发方式。真正设置触发方式,配置具体的触发事件
uint32_t ADC_DataAlign;//对齐方式。左对齐、右对齐
uint8_t ADC_NbrOfChannel;//规则通道的序列长度。设置有多少个规则通道,单通道设置为1即可
}ADC_InitTypeDef;
举例:
void ADC_Init(ADC_TypeDef* ADCx,ADC_InitTypeDef*ADC_InitStruct);
ADC_InitTypeDef ADC_InitADC;
ADC_InitADC.ADC_Resolution=ADC_Resplution_12b;//12位模式,分辨率
ADC_InitADC.ADC_ScanConvMode=DISABLE;//非扫描模式
ADC_InitADC.ADC_ContinuousConvMode=DISABLE;//关闭连续转换模式
ADC_InitADC.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
ADC_InitADC.ADC_DataAlign=ADC_DataAlign_Right;//右对齐
ADC_InitADC.ADC_NbrOfConversion=1;//1个转换在规则序列中。通道数一个
ADC_Init(ADC1,&ADC_InitStructure);//ADC初始化
ADC使能函数ADC_Cmd
void ADC_Cmd(ADC_TypeDef* ADCx,FunctionalState NewState);
举例:
ADC_Cmd(ADC1,ENABLE);//使能ADC1
ADC使能软件转换函数ADC_SoftwareStartConvCmd
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx,FunctionalState NewState)
举例:
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//使能ADC1的软件转换启动
//ADC_Init函数中若设置禁止外部触发使能,则就用ADC_SoftwareStartConvCmd函数使能软件转换启动
ADC规则通道配置函数ADC_RegularChannelConfig
void ADC_RegularChannelConfig(ADC_TypeDef*ADCx,uint8_t ADC_Channel,uint8_t Rank,uint8_t ADC_SampleTime);
ADC_RegularChannelConfig(ADC1,ADC_Channel_5,1,ADC_SampleTime_480Cycles);
//使用ADC1,使用通道5,规则通道序列为1,采用480个周期
//ADC_TypeDef*ADCx:哪一个ADC
//uint8_t ADC_Channel:哪一个通道
//uint8_t ADC_Rank:规则通道的序列
//uint8_t ADC_SampleTime:采用多少个周期
ADC获取转换结果函数ADC_GetConversionValue
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
ADC_GetConversionValue(ADC1);//获取ADC1的转换结果
//实际上是读取ADC1的数据寄存器
二、举例具体实验
实验目的:ADC1的通道5(PA5)进行单次转换
1、开启PA口时钟和ADC1时钟,设置PA1为模拟输入。
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
GPIO_Init();//在GPIO_Init中设置模拟输入
2、复位ADC1,同时设置ADC1分频因子。
ADC_DeInit();//F4中复位ADC不用写具体参数,只用调用ADC_DeInit()函数就行
3、初始化ADC_CCR寄存器。
ADC_Commonlnit();//设置ADC的通用参数
4、初始化ADC1参数,设置ADC1的工作模式以及规则序列的相关信息。
void ADC_Init(ADC_TypeDef*ADCx,ADC_InitTypeDef*ADC_InitStruct);
5、使能ADC。
ADC_Cmd(ADC1,ENABLE);
6、配置规则通道参数。
ADC_RegularChannelConfig();
//读取参数前要设置相关规则通道参数
7、开启软件转换。
ADC_SoftwareStartConvCmd(ADC1);
8、等待转换完成,读取ADC值。
ADC_GetConversionValue(ADC1);
在实验中会设置两个函数,第一个函数完成1—5的步骤,第二个完成6—8的步骤
adc.h中的代码:
#ifndef _ADC_H
#define _ADC_H
#include "sys.h"
void Adc_Init(void);//ADC通道初始化。完成1~5步骤
u16 Get_Adc(u8 ch);//获得某个通道值。完成6~7步骤
u16 Get_Adc_Average(u8 ch,u8 times);//得到某个通道给定次数采样的平均值。多次调用Get_Adc函数取平均值
adc.c中的代码
#include "adc.h"
#include "delay.h"
#include "sys.h"
void Adc_Init(void)//ADC通道初始化,仅是配置ADC1的相关参数
{
//GPIO初始化
GPIO_InitTypeDef GPIO_InitABC;
//ADC相关参数设置
ADC_CommonlnitTypeDef ADC_CommonlnitABC;
//ADC初始化参数
ADC_InitTypeDef ADC_InitABC;
//使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
//PA5设置为模拟输入
GPIO_InitABC.GPIO_Pin=GPIO_Pin5;
GPIO_InitABC.GPIO_Mode=GPIO_Mode_AN;//模拟输入
GPIO_InitABC.GPIO_Speed=GPIO_Speed_100MHz;
GPIO_InitABC.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA,&GPIO_InitABC);
//复位ADC
ADC_DeInit();//不用写具体ADC,只用复位就行
ADC_CommonlnitABC.ADC_DAMSccessMode=ADC_DMAAccessMode_Disable;//不使用DMA
ADC_CommonlnitABC.ADC_Mode=ADC_Mode_Independent;//独立模式
ADC_CommonlnitABC.ADC_Prescaler=ADC_Prescaler_Div4;//PCLK2时钟算出的是84兆。分频后不能超过36兆,故选择4分频
ADC_CommonlnitABC.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;
ADC_Commonlnit(&ADC_CommonlnitABC);
//第四步
ADC_InitABC.ADC_Resolution=ADC_Resolution_12b;//分辨率为12位。有6、8、10、12
ADC_InitABC.ADC_ScanConvMode=DISABLE;//非扫描模式
ADC_InitABC.ADC_ContinousConvMode=DISABLE;//关闭连续转换模式
ADC_InitABC.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
ADC_InitABC.ADC_DataAlign=ADC_DataAlign_Right;//右对齐
ADC_InitABC.ADC_NbrOfConversion=1;//1个转换在规则序列中。单通道一次转换
ADC_Init(ADC1,&ADC_InitABC);
//第五步调用ADC使能函数
ADC_Cmd(ADC1,ENABLE);
}
u16 Get_Adc(u8 ch)//调用具体的ADC通道,使用ADC通道5
{
//规则通道的配置。第一个参数是确定哪一个ADC,第二个参数是它的通道(入口参数ch是通道所以第二个参数是ch)(范围通道0~18),第三个参数是这个通道在这个规则序列中第几个转换,第四个参数是采样时间3个周期到480个周期任选
ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_480Cycles);
//ADC规则通道配置完毕
//调用软件开启转换,呼应上一个函数选择禁止触发检测
ADC_SoftwareStartConv(ADC1);//开启转换ADC1
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);//等待转换结束结束。转换结束之后就是1,0就是转换没结束。RESET就是没结束。如果和RESET值相等就是转换没结束,相等取1,再取反为0,就会一直等待。也可以写成while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC))
return ADC_GetConversionValue(ADC1);//获取转换值并返回
}
u16 Get_Adc_Average(u8 ch,u8 times)//多次调用u16 Get_Adc()函数并计算平均值
{
u32 temp=0;
u8 t;
for(t=0;t<times;t++)
{
temp+=Get_Adc(ch);//将times次的结果相加得总和temp
delay_ms(5);
}
return temp/times;//将综合temp除以times,得到平均值并返回
}