STM32F103单片机ADC功能使用

发布者:平和宁静最新更新时间:2022-01-27 来源: eefocus关键字:STM32F103  单片机  ADC功能 手机看文章 扫描二维码
随时随地手机看文章

12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。


模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。


ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生。


ADC 主要特征


● 12位分辨率


● 转换结束、注入转换结束和发生模拟看门狗事件时产生中断


● 单次和连续转换模式


● 从通道0到通道n的自动扫描模式


● 自校准


● 带内嵌数据一致性的数据对齐


● 采样间隔可以按通道分别编程


● 规则转换和注入转换均有外部触发选项


● 间断模式


● 双重模式(带2个或以上ADC的器件)


下面就用代码演示如何设置ADC单次转换模式


void ADCx_Init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    ADC_InitTypeDef ADC_InitStructure;


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);

    RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_2| GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_5; //PA1

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);


    ADC_DeInit(ADC1);


    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //工作在独立模式

    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_InitStructure.ADC_NbrOfChannel = 1; //规则转换ADC通道数

    ADC_Init(ADC1, &ADC_InitStructure);


    ADC_Cmd(ADC1, ENABLE); //使能ADC1


    ADC_ResetCalibration(ADC1); //复位校准

    while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束

    ADC_StartCalibration(ADC1); //开启AD校准

    while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束


}


首先初始化IO口,这里的初始化的是ADC抓换通道的0–5,对应的IO口PA0到PA5,将这6个IO口这是为模拟输入模式。接下来在将这几个口设置为ADC口,在设置之前首先将ADC模式复位,然后将ADC设置为单通道单词转换模式,也就是每次只转换一个通道,转换一次后就停止转换,直到接收到下一次转换命令为止。开始转换的命令是由软件来设置的。


ADC口初始化好之后,还需要一个读取转换结果的函数,用于读取指定通道的转换值。


//获取ADC值

//ch:通道号

u16 Get_Adc( u8 ch )

{

    ADC_RegularChannelConfig( ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期

    ADC_SoftwareStartConvCmd( ADC1, ENABLE ); //使能ADC1软件启动转换

    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;

}


Get_Adc()函数用于读取指定通道的ADC转换值,这里的通道必须是初始化函数中初始化过的通道,这个函数每次只读取一次通道值,为了确保转换结果的正确性,需要多次读取通道值取平均值,所以这里Get_Adc_Average()函数就是用来设置多次读取指定通道值,然后取平均值后返回。比如可以设置读取通道1,100次然后取平均值。ADC相关的设置函数就初始化好了,接下来在主函数中调用Get_Adc_Average()函数就可以读取通道值了。


int main(void)

{

    u16 adcx = 0;

    float temp;

    delay_init();        //延时函数初始化

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    uart_init(115200);

    LED_Init();



    LED0 = 1;

    LED1 = 1;

    delay_ms(500);

    LED0 = 0;

    LED1 = 0;


    ADCx_Init();


    printf("ADC test!!!rn");

    while(1)

    {

        adcx = Get_Adc_Average(ADC_Channel_0, 10);

        printf("ch0       num: %drn", adcx);

        temp = (float)adcx * (3.3 / 4096);

        adcx = temp * 1000;

        printf("ch0 adc value: %drn", adcx);


        adcx = Get_Adc_Average(ADC_Channel_1, 10);

        printf("ch1       num: %drn", adcx);

        temp = (float)adcx * (3.3 / 4096);

        adcx = temp * 1000;

        printf("ch1 adc value: %drn", adcx);


        adcx = Get_Adc_Average(ADC_Channel_2, 10);

        printf("ch2       num: %drn", adcx);

        temp = (float)adcx * (3.3 / 4096);

        adcx = temp * 1000;

        printf("ch2 adc value: %drn", adcx);


        adcx = Get_Adc_Average(ADC_Channel_3, 10);

        printf("ch3       num: %drn", adcx);

        temp = (float)adcx * (3.3 / 4096);

        adcx = temp * 1000;

        printf("ch3 adc value: %drn", adcx);


        adcx = Get_Adc_Average(ADC_Channel_4, 10);

        printf("ch4       num: %drn", adcx);

        temp = (float)adcx * (3.3 / 4096);

        adcx = temp * 1000;

        printf("ch4 adc value: %drn", adcx);


        adcx = Get_Adc_Average(ADC_Channel_5, 10);

        printf("ch5       num: %drn", adcx);

        temp = (float)adcx * (3.3 / 4096);

        adcx = temp * 1000;

        printf("ch5 adc value: %drn", adcx);


        LED0 = !LED0;

        delay_ms(500);

    }

}


在主函数中依次读取通道0到通道5的值,读取10次取平均值,然后将转换后的值打印出来。由于ADC为12位,所以转换后的最大值为4096,对应的最大电压值为3.3V,为了方便观察,将转换后的值换换位电压值。

关键字:STM32F103  单片机  ADC功能 引用地址:STM32F103单片机ADC功能使用

上一篇:STM32F103单片机驱动蜂鸣器
下一篇:STM32单片机实现DMA+ADC+UART功能

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved