OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 73|回复: 0

STM32F407的ADC采样不稳定

[复制链接]

2

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2023-10-20
在线时间
13 小时
发表于 7 天前 | 显示全部楼层 |阅读模式
1金钱
各位大佬,麻烦问一下我这个ADC为啥这么飘,用的FreeRTOS系统,REF电源用的REF3025。
ADC配置如下:
  1. #define  ADC_TRANSFORM_NUM   (3) //ADC转换次数
  2. #define  ADC_CHANNEL_NUM    (4) //ADC通道数目


  3. uint8_t ADC1_ConvertStartFlag = ADC_CONVERT_END;
  4. uint16_t g_usInChipAdcChannelAverageValue[ADC_CHANNEL_NUM];
  5. uint16_t uhADCConvertedValue[ADC_TRANSFORM_NUM][ADC_CHANNEL_NUM];
  6.   

  7. /*初始化部分*/
  8. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
  9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟


  10. DMA_InitStructure.DMA_Channel             = DMA_Channel_0;
  11.     DMA_InitStructure.DMA_MemoryBurst         = DMA_MemoryBurst_Single;             //非 burst 模式
  12.     DMA_InitStructure.DMA_PeripheralBurst     = DMA_PeripheralBurst_Single;         //非 burst 模式
  13.     DMA_InitStructure.DMA_Priority            = DMA_Priority_High;                  //DMA通道 x拥有高优先级
  14.     DMA_InitStructure.DMA_PeripheralDataSize  = DMA_PeripheralDataSize_HalfWord;    //外设端单次 Single 传输数据大小为 16 bits。
  15.     DMA_InitStructure.DMA_MemoryDataSize      = DMA_MemoryDataSize_HalfWord;        //内存端单次 Single 传输数据大小为 16 bits。
  16.     DMA_InitStructure.DMA_PeripheralInc       = DMA_PeripheralInc_Disable;          //外设地址递增禁止
  17.     DMA_InitStructure.DMA_MemoryInc           = DMA_MemoryInc_Enable;               //内存地址递增使能
  18.     DMA_InitStructure.DMA_Mode                = DMA_Mode_Circular;                  //NDTR归零后自动重装。可以在中断中结束ADC采样,下次启动转换不用初始化DMA。
  19.     DMA_InitStructure.DMA_DIR                 = DMA_DIR_PeripheralToMemory;         //数据传输方向,从外设ADC发送到内存读取
  20.     DMA_InitStructure.DMA_FIFOMode            = DMA_FIFOMode_Disable;               //使用 direct 模式,禁用 FIFO
  21.     DMA_InitStructure.DMA_FIFOThreshold       = DMA_FIFOThreshold_HalfFull;     
  22.     DMA_InitStructure.DMA_BufferSize          = ADC_TRANSFORM_NUM * ADC_CHANNEL_NUM;                          
  23.     DMA_InitStructure.DMA_PeripheralBaseAddr  = (uint32_t) & (ADC1->DR);               
  24.     DMA_InitStructure.DMA_Memory0BaseAddr     = (uint32_t)&uhADCConvertedValue;                    
  25.     DMA_Init(DMA2_Stream0, &DMA_InitStructure);

  26.     DMA_Cmd(DMA2_Stream0, ENABLE);


  27.         DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
  28.     DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);



  29.         NVIC_InitTypeDef NVIC_InitStructure;

  30.     NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
  31.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  32.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
  33.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  34.     NVIC_Init(&NVIC_InitStructure);



  35.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;//PA5 通道5
  36.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
  37.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
  38.     GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化  



  39.         ADC_CommonInitTypeDef ADC_CommonInitStructure;
  40.     ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div6;                   //ADC分频参数为2,ADCCLK =  APB2CLK/2 = 84/2 = 32Mhz。
  41.     ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;                      //ADC123独立模式
  42.     ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;       //多ADC模式的DMA禁止。其实不用配置,因为多ADC模式已经禁止了。
  43.     ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles; //多ADC模式下interleaved模式的两个和alternative模式下两个 ADC 之间的时间间隔。
  44.     ADC_CommonInit(&ADC_CommonInitStructure);



  45. ADC_InitTypeDef ADC_InitStructure;

  46.     ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;                      //12位采样精度。
  47.     ADC_InitStructure.ADC_ScanConvMode = ENABLE;                                //Scan模式使能,
  48.     ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //禁用外部触发模式。
  49.     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;       //外部触发禁止情况下,该参数无效。
  50.     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                      //数据对齐采用右对齐模式。
  51.     ADC_InitStructure.ADC_NbrOfConversion = 4;                                  //通道组中的待采样通道个数为 。
  52.     ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                          //DMA模式下使能连续采样模式。单次触发可以连续的进行采样操作。
  53.                                                                                 //见 STM32F4xx 英文参考手册 page 423。ADC_CR2寄存器的 CONT 位说明。
  54.                                                                                 //连续模式使能后。采样将连续执行直到 CONT 软件清零。
  55.                                                                                 //当然连续采样的开始还是需要软件触发或者外部触发的。
  56.     ADC_Init(ADC1, &ADC_InitStructure);
  57.     //TODO::可以根据实际情况调整采样时间。
  58. //  ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_480Cycles); //通道采样时间配制。采样时间为480 ADCCLK 转换时间12 ADCCLK。
  59.     ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_112Cycles);
  60.     ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_56Cycles);
  61.     ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 3, ADC_SampleTime_56Cycles);
  62.     ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 4, ADC_SampleTime_56Cycles);

  63.     ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
  64.     ADC_DMACmd(ADC1, ENABLE);

  65.     ADC_Cmd(ADC1, ENABLE);






  66. void DMA2_Stream0_IRQHandler(void)
  67. {
  68.     if (SET == DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))
  69.     {
  70.         DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0); //清除 DMA 中断标示。
  71.          
  72.          
  73.         ADC1_ConvertStartFlag = ADC_CONVERT_END;              //标示本次ADC转换结束。
  74.                                                               //STM32F4xx不能像STM32F103那样的直接通过清零触发源停止转换。
  75.          
  76.         ADC_ContinuousModeCmd(ADC1, DISABLE);                 //确保该bit可以在 ADCON 置位的情况下进行修改。确保是可以的。
  77.     }
  78. }



  79. /*该函数定时调用*/
  80. void ADC1_GetVolt(void)
  81. {

  82.    float advalue;
  83.     uint8_t i=0,j=0, k=0;
  84.     uint16_t AxtractData[ADC_CHANNEL_NUM][ADC_TRANSFORM_NUM] = {0};
  85.     uint16_t usTemp;
  86.     uint32_t uiSum[ADC_CHANNEL_NUM] = {0};

  87.     ADC_ContinuousModeCmd(ADC1, ENABLE); //启动 ADC1 连续采样模式
  88.     ADC_SoftwareStartConv(ADC1);         //ADC1 采样使能

  89.     ADC1_ConvertStartFlag = ADC_CONVERT_START;
  90.     while (ADC_CONVERT_END != ADC1_ConvertStartFlag)
  91.         ; //等待采样结束



  92.      /*****************取出每个ADC通道的值 ***************/
  93.     for(i=0;i<ADC_TRANSFORM_NUM;i++)        //
  94.     {
  95.         for(j=0;j<ADC_CHANNEL_NUM;j++)  //
  96.         {
  97.             AxtractData[j][i] = uhADCConvertedValue[i][j];
  98.         }        
  99.     }



  100.   /***************************排序****************************/
  101.     for( k=0;k<ADC_CHANNEL_NUM;k++ )
  102.     {
  103.         for( i=1;i<ADC_TRANSFORM_NUM;i++ )
  104.         {
  105.             usTemp=AxtractData[k][i];                         //usTemp为插入的元素
  106.             j=i-1;
  107.             while( ( j>=0 ) && ( usTemp<AxtractData[k][j] ) ) //查找array[i-1] 后比它小的数
  108.             {
  109.                 AxtractData[k][j+1]=AxtractData[k][j];
  110.                 j--;
  111.             }
  112.             AxtractData[k][j+1]=usTemp;                       //插入数据
  113.         }
  114.     }



  115.      /******************计算每个ADC通道平均值******************/
  116.     for( i=0;i<ADC_CHANNEL_NUM;i++ )        
  117.     {
  118.         for( j=1;j<ADC_TRANSFORM_NUM-1;j++ )//去掉一个最大值和最小值
  119.         {
  120.             uiSum[i] += AxtractData[i][j];
  121.         }         
  122.         g_usInChipAdcChannelAverageValue[i] = uiSum[i]/(ADC_TRANSFORM_NUM-2);
  123.          
  124.     }

  125. }
复制代码
这是以200ms获取一次g_usInChipAdcChannelAverageValue[1]得到的数据

3855
3839
3848
3837
3842
3850
3841
3831
3823
3861
3837
3835
3838
3851
3839
3839
3856
3864
3846
3843
3841
3839
3837
3829
3848
3858
3845
3831
3868
3833
3835
3830
3837
3848
3833
3831
3847
3839
3827
3839
3846
3848
3839
3845
3858
3837
3845
3843
3864
3833
3839
3843
3856
3845
3845
3848
3846
3832
3842
3838
3823
3831

数值波动很大,不知道是不是软件配置有问题?还是电源的纹波引起的

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-8-7 17:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表