您的位置:首页 > 其它

STM32入门之ADC学习总结

2017-09-13 21:03 288 查看
学习板为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_
884a
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);

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: