STM32自学笔记(七)ADC

1)编写adc.c文件

编写adc.c文件,里面放以下三个函数

1. Adc_Init (void):用于ADC的初始化,需要在main()中调用一次。       

(需要根据具体情况修改,在第四节会讲如何修改)

2.Get_Adc(ch):读取某个通道的AD采样值。传递参数直接填通道名,例如通道1:ADC_Channel_1

(需要根据具体情况修改,在第五节会讲如何修改)

3.Get_Adc_Average(ch,times):也是读取某个通道的AD采样值,只不过取多次的平均值,提高准确度

 #include "adc.h"
 #include "delay.h"
//初始化 ADC 
//这里我们仅以规则通道为例 
//我们默认将开启通道 0~3               
void  Adc_Init(void) 
{  
    ADC_InitTypeDef ADC_InitStructure;   
    GPIO_InitTypeDef GPIO_InitStructure; 
 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | 
                           RCC_APB2Periph_ADC1 , ENABLE );    //使能 ADC1 通道时钟  
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);  	//设置 ADC 分频因子 6  
    									//72M/6=12,ADC 最大时间不能超过 14M  
    //PA1 作为模拟通道输入引脚                           
    GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1;  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入  
    GPIO_Init(GPIOA, &GPIO_InitStructure);         //初始化 GPIOA.1 
 
    ADC_DeInit(ADC1);  //复位 ADC1,将外设 ADC1 的全部寄存器重设为缺省值  
    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_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC 数据右对齐  
    ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目  
    ADC_Init(ADC1, &ADC_InitStructure);     //根据指定的参数初始化外设 ADCx    
    
    ADC_Cmd(ADC1, ENABLE);             //使能指定的 ADC1  
    ADC_ResetCalibration(ADC1);             //开启复位校准    
    while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束  
    ADC_StartCalibration(ADC1);             //开启 AD 校准  
    while(ADC_GetCalibrationStatus(ADC1));     //等待校准结束 
}       
    //获得 ADC 值 
    //ch:通道值 0~3 
    u16 Get_Adc(u8 ch)    
    {    
        //设置指定 ADC 的规则组通道,设置它们的转化顺序和采样时间 
        ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );  
        							//通道 1,规则采样顺序值为 1,采样时间为 239.5 周期     
        ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能软件转换功能   
        while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束  
        return ADC_GetConversionValue(ADC1); //返回最近一次 ADC1 规则组的转换结果 
    } 
    u16 Get_Adc_Average(u8 ch,u8 times) 
    {  
        u32 temp_val=0;  
        u8 t;  
        for(t=0;t<times;t++)  
        {   
            temp_val+=Get_Adc(ch);   
            delay_ms(5);  
        }  
        return temp_val/times; 
    } 

 

2)编写adc.h文件

只需声明adc.c中三个函数即可

#ifndef __ADC_H
#define __ADC_H	
#include "sys.h"

void Adc_Init(void);
u16  Get_Adc(u8 ch); 
u16 Get_Adc_Average(u8 ch,u8 times); 
 
#endif 

3)在main()使用ADC

(1)ADC初始化

直接调用adc.c中的初始化函数即可

Adc_Init();       //ADC 初始化 

(2)读取ADC值

调用adc.c中的Get_Adc_Average(ch,times)

u16 adcx
...
adcx=Get_Adc_Average(ADC_Channel_1,10);  

将ADC值赋给了16位变量adcx

(3)转换为电压值

STM32的ADC为12位,参考电压为Vref

因此电压值为:V = adcx * (Vref / 4096)

但有一个需要注意的地方,前面定义的 adcx 是一个16位整型变量,而电压值是有小数的,因此需要一个float型变量来保存电压值,并通过一定技巧得到整数部分和小数部分。代码如下:

float temp
...
temp=(float)adcx*(3.3/4096);      //转换后得到的电压值 
adcx=temp;            //电压值的整数部分  float型赋给整型,结果是保留了整数部分
temp-=adcx;           //电压值的小数部分
temp*=1000;           //小数部分*1000变为整型,方便LCD显示

adcx为电压值的整数部分,temp为电压值的小数部分

4)根据配置情况修改Adc_Init (void)

stm32有多个ADC,每个ADC又有多个通道,要根据具体使用情况进行相关配置

上文代码使用了ADC1的通道1,对应的GPIO是PA1,因此GPIO的配置是按照PA1来设置的。若使用了其他通道,则需要改成对应的GPIO。

STM32F103的ADC通道与GPIO对应表如下(其余型号自己翻datesheet找下)

需要修改的代码在下面列出了

//这里用的是PA1,根据具体GPIO修改
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | 
                           RCC_APB2Periph_ADC1 , ENABLE );    //使能 ADC1 通道时钟
  
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1; 

GPIO_Init(GPIOA, &GPIO_InitStructure);         //初始化 GPIOA.1  

//这里用的是ADC1,根据具体情况改成ADCx
ADC_DeInit(ADC1);  //复位 ADC1,将外设 ADC1 的全部寄存器重设为缺省值  
 
ADC_Init(ADC1, &ADC_InitStructure);     //根据指定的参数初始化外设 ADCx  
    
ADC_Cmd(ADC1, ENABLE);             //使能指定的 ADC1  
    
ADC_ResetCalibration(ADC1);             //开启复位校准    
    
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束  
    
ADC_StartCalibration(ADC1);             //开启 AD 校准  
    
while(ADC_GetCalibrationStatus(ADC1));     //等待校准结束 

5)根据配置情况修改Get_Adc(ch)

参见上面修改Adc_Init (void)的方法,把ADC1都改为ADCx

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值