STM32入门之ADC学习总结

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Trans1ent/article/details/77970997

学习板为stm32F103VET

1 STM32的ADC简单介绍

  1.1拥有3个ADC,可以单独使用,也可以使用双重模式(目前就学习了单独使用),

  1.2stm32的ADC是12位的模数转换器(所以这里存在左对齐和右对齐两种模式,左对齐得到的数值要除以16),

  1.3具有18通道可测量16个外部和2个内部信号源(使用较多的就是测量外部信号),各通道具有4种模式:单次,连续,扫描,间断

  1.4不要让ADC的时钟超过14M,ADC在APB2上,所以一般设置6分频,

  1.5ADC转换分为2个通道组,规则和注入通道组,可以把注入理解为中断(这里不太懂,日后加强)

 

2 STM32ADC的一些重要寄存器

  2.1 ADC_CR1和ADC_CR2

  ADC_CR1的第8位SCAN位,设置扫描模式,1:开启 ;0:关闭

  ADC_CR1的16-19位共4位设置ADC的操作模式,本次学习,只使用了独立模式,所以设置为0000

  ADC_CR2的第0位ADCON用于开关ADC转换器

  ADC_CR2的第1位CONT用于设置是否连续转换,本次学习使用单次转换,设置为0

  ADC_CR2的第11位ALIGN用于设置ADC_DR(AD转换结束读取的数据)的对齐方式

  ADC_CR2的第17-19位用于选择启动规则转换组转换的外部事件,详情查阅dataSheet,本次使用软件触发(SWSTART),该3位设置为111

  2.2 ADC_SMPR1和ADC_SMPR2

  这两个寄存器用于设置通道0~17的采样时间,(SMPR1包括10-17通道,SMPR2包括0-9通道)每个通道占用3个位:

  000-111  8种采样时间,本次学习使用111:239.5周期

  2.3 ADC_SQR1~3

  2.4 ADC_DR

    AD转化结果都将被存在这个寄存器里面(有左对齐和右对齐2种方式)

  2.5 ADC_SR

  位1 EOC:转换结束标志位(1:转换完成,由软件清除或读取ADC_DR后自动清除)

  位2 JEOC:注入通道转换结束标志位

  位3 JSTRT:注入通道开始位

  位4 STRT:规则通道开始位

  用的较多的是位1,用于判断AD转换结束后,读取转换结果


3 使用库函数完成本次的简单ADC转换的例子

void RCC_Configuration(void){
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);    //USART用于将AD转换结果输出到电脑查看
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);    //ADC
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
}

//管脚配置
void GPIO_Configuration(void){
    //UASRT    PA9 and PA10
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;    //TX
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;    //RX
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

    //ADC

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;   //PA0作为模拟量输入
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    
}


void USART_Configuration(void){
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;  //无校验
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //无硬件控制
    USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
    
    USART_Init(USART1,&USART_InitStructure);
    
    USART_Cmd(USART1,ENABLE);
    
    USART_ClearFlag(USART1,USART_FLAG_TC);   //先清除发送完成标志位,防止第一次发送出现异常
}

void ADC_Configuration(void){
    ADC_InitTypeDef ADC_InitStructure;
    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;  //只进行1个通道进行规则转换

    ADC_Init(ADC1,&ADC_InitStructure);

    ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_239Cycles5);  //确定ADC1的通道0,采用时间为239.5周期

    ADC_Cmd(ADC1,ENABLE);


    ADC_ResetCalibration(ADC1);    //开始复位校验
    while(ADC_GetResetCalibrationStatus(ADC1));    //

    ADC_StartCalibration(ADC1);//开始AD校验
    while(ADC_GetCalibrationStatus(ADC1));

    ADC_SoftwareStartConvCmd(ADC1,ENABLE);    //手动开启ADC转换
}


主函数:

int fputc(int ch,FILE* f){
    USART_SendData(USART1,(u8)ch);
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
    return ch;
}

int main(void){

    u32 ad = 0;

    RCC_Configuration();
    GPIO_Configuration();
    NVIC_Configuration();
    USART_Configuration();
    ADC_Configuration();
    while(1){

       ad = 0;

       for(i=0;i<50;i++){  //获取50次,取平均值,提高精度
         ADC_SoftwareStartConvCmd(ADC1,ENABLE);
         while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
         ad=ad+ADC_GetConversionValue(ADC1);
      }
      
      ad=ad/50;
      printf("ad =%f\r\n",3.3/4095*ad);

     delay_ms(1000);

    }
}












展开阅读全文

没有更多推荐了,返回首页