• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

STM32F103C8T6四路AD采集数据显示在oled屏上非DMA传输方式附百度网盘下载链接

武飞扬头像
趣你的嵌入式
帮助1

本文采用四路AD采集光照强度、烟雾浓度、一氧化碳、空气质量等四个物理量,并采用中位值平均滤波(防脉冲干扰平均滤波法)算法对偶然出现的脉冲性干扰,消除由其引起的采样值偏差。

  1. ADC简介

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

  1. 主要用到的ADC参数和函数

  1.  
    void ADC1_Init(void)
  2.  
    {
  3.  
    GPIO_InitTypeDef GPIO_InitStructure;
  4.  
    ADC_InitTypeDef ADC_InitStructure;
  5.  
     
  6.  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
  7.  
     
  8.  
    RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置 ADC 分频因子 6
  9.  
     
  10.  
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
  11.  
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
  12.  
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  13.  
    GPIO_Init(GPIOA,&GPIO_InitStructure);
  14.  
     
  15.  
    ADC_DeInit(ADC1); //将外设 ADC1 的全部寄存器重设为缺省值
  16.  
     
  17.  
    ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//连续转化模式设置
  18.  
    ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//数据左对齐
  19.  
    ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//软件触发
  20.  
    ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//独立模式
  21.  
    ADC_InitStructure.ADC_NbrOfChannel=1;//通道数
  22.  
    ADC_InitStructure.ADC_ScanConvMode=DISABLE;//扫描模式设置
  23.  
    ADC_Init(ADC1,&ADC_InitStructure);
  24.  
     
  25.  
    ADC_Cmd(ADC1,ENABLE);//使能指定ADC外设
  26.  
     
  27.  
    ADC_ResetCalibration(ADC1);//使能复位校准
  28.  
    while(ADC_GetResetCalibrationStatus(ADC1));//等待复位校准结束
  29.  
    ADC_StartCalibration(ADC1);//开启AD校准
  30.  
    while(ADC_GetCalibrationStatus(ADC1));//等待AD校准结束
  31.  
    }
  32.  
     
  33.  
    u16 Get_ADC_Value(u8 channel)//ADC采样
  34.  
    {
  35.  
    ADC_RegularChannelConfig(ADC1,channel,1,ADC_SampleTime_239Cycles5);
  36.  
    ADC_SoftwareStartConvCmd(ADC1,ENABLE);
  37.  
    while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
  38.  
    return ADC_GetConversionValue(ADC1);
  39.  
    }
学新通

void ADC_DeInit(ADC_TypeDef* ADCx) :将外设 ADCx 的全部寄存器重设为缺省值 ADC_ContinuousConvMode:用来设置是否开启连续转换模式,单次转换:DISABLE;连续转换:ENABLE,因为我们是单次转换,所以设置为DISABLE

ADC_DataAlign:用来设置 ADC 数据对齐方式是左对齐还是右对齐,ADC转换后的数据被保存到数据寄存器中(ADC_DR)的0~15位或16~32位,数据宽度为16位,ADC转换精度12位。左对齐则是把ADC转换后的数值最高位D12与存储区域的最高位Bit15对齐,存储区域的低4位无意义。右对齐则是ADC转换的数值最低位D0保存在存储区域的最低位Bit0,高四位无意义

ADC_ExternalTrigConv:用来设置启动规则转换组转换的外部事件 ,ADC在收到触发信号后才开始进行模数转换

学新通

ADC_Mode:ADC的模式非常多,包括独立模式,注入同步模式等等,而不同的ADC是共用通道的,当两个ADC采集同一个通道的先后顺序、时间间隔不同时,就会有多种模式。我们只使用了一个ADC,所以选择独立模式,参数为 ADC_Mode_Independent。

学新通

ADC_NbrOfChannel:保存要进行ADC数据转换的通道数,可以为1 ~ 16个。这里我们是单次采集一个通道,所以值为 1即可

ADC_ScanConvMode:用来设置是否开启扫描模式,当有多个通道需要采集信号时,可以把ADC配置为按一定的顺序轮流采集各通道的值。如果采集多个通道,必须开启此模式。这里我们是单次采集一个通道的信号,这里我们选择不开启 : DISABLE

注:以下函数都没有写形参和返回值,仅仅写出了它的功能,具体参见STM32F103固件库说明手册

ADC_Init():根据 ADC_InitStruct 中指定的参数初始化外设 ADCx 的寄存器

ADC_Cmd():使能或者失能指定的 ADC,:函数 ADC_Cmd 只能在其他 ADC 设置函数之后被调用

ADC_ResetCalibration(): 重置指定的 ADC 的校准寄存器

ADC_GetResetCalibrationStatus(): 获取 ADC 重置校准寄存器的状态 ,返回值: ADC 重置校准寄存器的新状态(SET 或者 RESET) ,当值为RESET时重置成功

ADC_StartCalibration():开始指定 ADC 的校准状态

ADC_GetCalibrationStatus(): 获取指定 ADC 的校准程序 ,返回值: ADC 校准的新状态

ADC_RegularChannelConfig ():设置指定 ADC 的规则组通道,设置它们的转化顺序和采样时间,RANK值是指在进行多通道扫描时,本通道的扫描顺序。例如通道4、5、6、7的RANK值被分配为4、3、2、1,则在ADC扫描时,扫描的顺序为通道7、6、5、4 。

ADC_SampleTime:用于配置本通道的采样周期,这里的周期指的是ADCCLK的时钟周期,ADC时钟频率越高,转换速度就越快,但ADC时钟有上限值,不能超过14Mhz。ADC的时钟(ADCCLK)为ADC预分频器的输出,而ADC预分频器的输入则为高速外设时钟(PCLK2)。PCLK2的常用时钟频率为72Mhz,可设置PCLK2为2、4、6、8分频。因为ADCCLK必须低于14Mhz,所以ADCCLK最高频率为PCLK2的8分频,即ADCCLK = 9Mhz.

STM32的ADC采样时间计算公式:T=采样周期+12.5个周期

本实验中ADC通道的转换时间:T= (239.5+12.5)x(1÷12) = 21us

注:12.5为固定周期

ADC_SoftwareStartConvCmd():使能或者失能指定的 ADC 的软件转换启动功能

ADC_GetFlagStatus();检查制定 ADC 标志位置 1 与否

学新通

ADC_FLAG 的值

u16 ADC_GetConversionValue(ADC_TypeDef* ADCx) :返回最近一次 ADCx 规则组的转换结果

  1. 中位值平均滤波(防脉冲干扰平均滤波法)

方法:“中位值滤波法" “算术平均滤波法”

连续采样N个数据,去掉一个最大值和一个最小值,然后计算N-2个数据的算术平均值,N值的选取:3~14

优点:融合了两种滤波的优点。对于偶然出现的脉冲性干扰,可消除有其引起的采样值偏差。对周期干扰有良好的抑制作用,平滑度高,适于高频振荡的系统。

缺点:测量速度慢。

这里采用了一个二维数组来分别存储四个AD通道的采样值,然后分别进行计算,具体代码如下:

  1.  
    void middleAverageFilter() //中位值平均滤波(防脉冲干扰平均滤波法)
  2.  
    {
  3.  
    u16 i,j,k,g;
  4.  
    u16 temp;
  5.  
    u16 Sum_Value[ADC_Value_Size] = {0};
  6.  
    u16 value_buf[ADC_Value_Size][ADC_Value_Number] = {0};
  7.  
    for(g = 0 ; g < ADC_Value_Size ; g )
  8.  
    {
  9.  
    for(i = 0; i < ADC_Value_Number; i )
  10.  
    {
  11.  
    value_buf[g][i] = Get_ADC_Value(g 0x04);
  12.  
     
  13.  
    }
  14.  
    }
  15.  
     
  16.  
    /*从小到大冒泡排序*/
  17.  
    for(g = 0 ; g < ADC_Value_Size ; g )
  18.  
    {
  19.  
    for(j = 0; j < ADC_Value_Number-1; j )
  20.  
    {
  21.  
    for(k = 0; k < ADC_Value_Number-j-1; k )
  22.  
    {
  23.  
    if(value_buf[k] > value_buf[k 1])
  24.  
    {
  25.  
    temp = value_buf[g][k];
  26.  
    value_buf[g][k] = value_buf[g][k 1];
  27.  
    value_buf[g][k 1] = temp;
  28.  
     
  29.  
    }
  30.  
    }
  31.  
    }
  32.  
    }
  33.  
    for(g = 0 ; g < ADC_Value_Size ; g )
  34.  
    {
  35.  
    for(i = 1; i < ADC_Value_Number-1; i )
  36.  
    {
  37.  
    Sum_Value[g] = value_buf[g][i];
  38.  
    }
  39.  
    }
  40.  
    Light_value =4096 - Sum_Value[0]/(ADC_Value_Number-2);
  41.  
    m7_value=Sum_Value[1]/(ADC_Value_Number-2);
  42.  
    m135_value =4096 - Sum_Value[2]/(ADC_Value_Number-2);
  43.  
    m2_value = Sum_Value[3]/(ADC_Value_Number-2);
  44.  
    }
学新通
  1. 传感器

本实验用到了 MQ-2 烟雾传感器、MQ-7一氧化碳传感器、MQ-135空气质量传感器和光敏电阻传感器。传感器这里就不再介绍啦,大家有传感器就应该有资料的,直接连在对应的引脚就可以用啦

学新通
学新通

4. 实验现象

学新通
  1. 百度网盘下载链接

链接:https://pan.百度.com/s/1SpTvf2CjtPRw3GmdaW4xTA

提取码:1k6q

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgabjhe
系列文章
更多 icon
同类精品
更多 icon
继续加载