使用冒泡排序法,对各通道的连续五次采样结果取平均值

u16 ADC1_AveragValue(u16 ADC_Value[N][M])
{
    u16 ADC1_Value[N];
    u8 i = 0;
    u8 j = 0;
    u16 temp = 0;
    u16 ADC1_Av = 0;
    for (i = 0;i < N;i++)
    {
              ADC1_Value[i] = ADC_Value[i][0];
    }
    /*冒泡排序*/
    for(i=0; i<N-1; i++)
    {
//内循环选择要进行比较的数
        for(j=0; j<N-1-i; j++)
        {
             if(ADC1_Value[j]>ADC1_Value[j+1])
             {
                    temp=ADC1_Value[j];
                    ADC1_Value[j]=ADC1_Value[j+1];
                    ADC1_Value[j+1]=temp;
             }
        }
    }
    /*去掉最大值和最小值*/
    for (i = 0; i<N-2;i++)
    {
        ADC1_Av += ADC1_Value[i+1];
        
    }
    /*取平均值*/
    ADC1_Av = ADC1_Av/4;
    return ADC1_Av;
    
}













STM32的内部自带12位ADC,其特点如下:
(1)12位分辨率,最短时钟周期为14个,时钟周期可调,分别可以调整为14、20、26、41、54、68、252,因此当时钟为14MHz时候,最快转换时间为1us;
(2)供电电压为2.4V到3.6V,注意stm32的最低供电电压可以是2V,但是使用ADC时候,必须达到2.4V以上;
(3)输入电压范围:0<vin< VCC
(4)最小量化单位为:LSB=Vref+/4096mV;
(5)为逐次比较型AD;
处理AD转换的方法有两个:一个是常用的中断,另一个是DMA,相对来说,DMA模式下的效率要高,所以这里研究DMA下的ADC。
3、实验目标:通过ADC1的11通道采集外部电压,然后又DMA传送到缓存,然后通过串口发到到PC上。
4、实验程序:


1. 配置ADC等资源
2. 配置时钟
3. 参数配置
点“ADC1”?
Mode: 模式为独立模式。
Dataalignment数据对齐:右对齐
ScanConversionMode:扫描转换模式,如果使用了一个ADC下的多个采集通道,需要选择Enable模式,否则只会转换设置的第一个通道。
ContinuousConversMode连续转换模式
DiscontinuousConversionMode:不连续转换模式
NVIC部分开启DMA中断,关闭中断模式的中断使能。
Memory:勾选此项,转换数据将存在Memory中,并且地址自加连续存放。此功能对某个通道连续多次采样很好用,采样数据会自动填满一个数组,方便软件滤波。
Mode:选循环模式,填满数组后自动从头刷新。
DataWidth数据长度:如果是12位AD转换,此处选半字。

4.程序实现
在STM32CubeMX生成好的程序基础上。
在main设置一个uhADCxConvertedValue2的全局变量数组。类型为Uint16_t。
在main函数的初始化区后,while(1)区前,添加:
if(HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&uhADCxConvertedValue2,100)!=HAL_OK)Error_Handler();
ADC1启动,并开始连续转换,转换结果会放在uhADCxConvertedValue2数组中,大小是100。因为是连续转换,所以数组中存放的是最近100次转换结果。

5软件滤波
滤波子函数:可以计算100个点的滤波结果。
此函数为中值平均滑动滤波,当然,滑动是ADC的DMA自动实现的。
  1. uint16_t ADC_Average(__IOuint16_t*buff,uint16_tnum,uint16_tthreshold)
  2. {
  3. uint32_tsigma=0;
  4. uint16_ti=0,j=0,temp=0;
  5. uint16_ttemp_buff[num];
  6. for(i=0;i<(num-1);i++)
  7.                {
  8. for(j=0;j<(num-1);j++)
  9. {
  10. if(temp_buff[j]<temp_buff[j+1])
  11. {
  12. temp=temp_buff[j];
  13. temp_buff[j]=temp_buff[j+1];
  14. temp_buff[j+1]=temp;
  15. }
  16. }
  17. }
  18. for(i=threshold;i<(num-threshold);i++){
  19. sigma=sigma+buff[i];
  20. }
  21. temp=(uint16_t)(sigma/(num-threshold*2));return(temp);
  22. }
复制代码

 










posted @ 2020-07-05 21:50  dreamrj  阅读(1177)  评论(0编辑  收藏  举报