你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F302 差分ADC异常,采集跳动

[复制链接]
lideyu88 提问时间:2019-8-15 07:51 /
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOF, ENABLE);  

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3
    | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_4;
  GPIO_Init(GPIOF, &GPIO_InitStructure);  
  //ADC Init
  RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div1);
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);

  ADC_StructInit(&ADC_InitStructure);
  /* Calibration procedure */
  ADC_VoltageRegulatorCmd(ADC1, ENABLE);
  ADC_VoltageRegulatorCmd(ADC2, ENABLE);
  vTaskDelay(10);

  ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Differential);
  ADC_StartCalibration(ADC1);
  ADC_SelectCalibrationMode(ADC2, ADC_CalibrationMode_Differential);
  ADC_StartCalibration(ADC2);  

  while(ADC_GetCalibrationStatus(ADC1) != RESET );
  calibration_value1 = ADC_GetCalibrationValue(ADC1);
  while(ADC_GetCalibrationStatus(ADC2) != RESET );
  calibration_value2 = ADC_GetCalibrationValue(ADC2);  

  /* ADC Dual mode configuration */     
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_RegSimul;                                                                    
  ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;                    
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;            
  ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_Circular;                  
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = 10;         

  ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
  /* */  
  ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;//ADC_ContinuousConvMode_Enable;
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_5;//Event5 = TIM4_CC4 event          Event12 = TIM4_TROG event
  ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_RisingEdge;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;   
  ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;  
  ADC_InitStructure.ADC_NbrOfRegChannel = 4;
  ADC_Init(ADC1, &ADC_InitStructure);
  ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
  ADC_Init(ADC2, &ADC_InitStructure);  

  /* ADC1 regular channel7 and channel8 configuration */
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_61Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_61Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_61Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_61Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 5, ADC_SampleTime_61Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 6, ADC_SampleTime_61Cycles5);//与ADC2共用CH6,错时使用
  ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 7, ADC_SampleTime_61Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 8, ADC_SampleTime_61Cycles5);

  ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_61Cycles5);
  ADC_RegularChannelConfig(ADC2, ADC_Channel_2, 2, ADC_SampleTime_61Cycles5);
  ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 3, ADC_SampleTime_61Cycles5);
  ADC_RegularChannelConfig(ADC2, ADC_Channel_4, 4, ADC_SampleTime_61Cycles5);
  ADC_RegularChannelConfig(ADC2, ADC_Channel_9, 5, ADC_SampleTime_61Cycles5);
  ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 6, ADC_SampleTime_61Cycles5);
  ADC_RegularChannelConfig(ADC2, ADC_Channel_5, 7, ADC_SampleTime_61Cycles5);
  ADC_RegularChannelConfig(ADC2, ADC_Channel_6, 8, ADC_SampleTime_61Cycles5);//与ADC1共用CH6,错时使用

  ADC_SelectDifferentialMode(ADC1, ADC_Channel_1, ENABLE);      //差分通道
  ADC_SelectDifferentialMode(ADC1, ADC_Channel_3, ENABLE);      
  ADC_SelectDifferentialMode(ADC1, ADC_Channel_5, ENABLE);      
  ADC_SelectDifferentialMode(ADC1, ADC_Channel_7, ENABLE);      

  ADC_SelectDifferentialMode(ADC2, ADC_Channel_1, ENABLE);      //差分通道
  ADC_SelectDifferentialMode(ADC2, ADC_Channel_3, ENABLE);      
  ADC_SelectDifferentialMode(ADC2, ADC_Channel_9, ENABLE);      
  ADC_SelectDifferentialMode(ADC2, ADC_Channel_5, ENABLE);   

    /* Configures the ADC DMA */
  ADC_DMAConfig(ADC1, ADC_DMAMode_Circular);
  /* Enable the ADC DMA */
  ADC_DMACmd(ADC1, ENABLE);

  /* Enable ADC1 and ADC2 */
  ADC_Cmd(ADC1, ENABLE);
  ADC_Cmd(ADC2, ENABLE);

    /* wait for ADC1 ADRDY */
  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY));

  /* wait for ADC2 ADRDY */
  while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_RDY));

  vTaskDelay(10);
  //DMA Init
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC_CDR_ADDRESS;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCDualConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 300*4;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(DMA1_Channel1, &DMA_InitStructure);

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
  DMA_Cmd(DMA1_Channel1, ENABLE);
  //TIM4 Init
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
  /* TIM4 configuration ------------------------------------------------------*/
  /* Time Base configuration */
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  TIM_TimeBaseStructure.TIM_Period = 24000-1;        //72M/3K = 24K   
  TIM_TimeBaseStructure.TIM_Prescaler = 0;      
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;   
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
  /* TIM4 channel1 configuration in PWM mode */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;      
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;         
  TIM_OCInitStructure.TIM_Pulse = 0x0FFF;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;  
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;      
  TIM_OC4Init(TIM4, &TIM_OCInitStructure);  

  TIM_SelectOutputTrigger(TIM4, TIM_TRGOSource_OC4Ref);
  /* TIM4 counter enable */
  TIM_Cmd(TIM4, ENABLE);

  /* TIM4 main Output Enable */
  TIM_CtrlPWMOutputs(TIM4, ENABLE);
  ADC_StartConversion(ADC1);

采集直流数据,采集变化非常大。采集值有100左右的变化。
另外,如果不添加  ADC_StartConversion(ADC1);,采集是不会开始的,不知道哪里没有配置好。


<
收藏 评论10 发布时间:2019-8-15 07:51

举报

10个回答
lideyu88 回答时间:2019-8-15 09:11:40
差分,单极性,都试过,跳动非常厉害。比如,量程3V,输入电压1.6V,每200次采集平均滤波后,结果还在1.54~1.68V之间跳动。
我的目标是可以不准,毕竟可以校准的。但不能跳动,要稳。

mmuuss586 回答时间:2019-8-15 09:24:02
模拟电源,参考电压,输入信号都稳定吗
mmuuss586 回答时间:2019-8-15 09:24:36
一步步排查;
可以先接个标准的稳定信号先测试下,比如接电池
lideyu88 回答时间:2019-8-15 09:25:54
mmuuss586 发表于 2019-8-15 09:24
一步步排查;
可以先接个标准的稳定信号先测试下,比如接电池

是的,我的信号是电池。
lideyu88 回答时间:2019-8-15 09:35:48
输入V-=1.487V,V+=2.235V,参考=2.997V,部分采集值 微信图片_20190815093446.png
xself 回答时间:2019-8-15 09:36:22
理论上来说应该不会这样子。被测试的信号号是电池,还需要考虑参考电压是否稳定。再者就是芯片、参考地、被测试信号地,三者地线是否连接可靠。
xself 回答时间:2019-8-15 09:38:14
不使用DMA ,单个通道ADC测试结果如何,先排队是硬件还是软件导致。
wenyangzeng 回答时间:2019-8-15 09:47:27
楼主的代码中DMA缓冲区长度是300*4,貌似分成4组对应4个差分通道,而ADC1与ADC2好像共用了这些缓冲区,看似ADC1与ADC2的数据重叠了。
lideyu88 回答时间:2019-8-15 09:55:00
xself 发表于 2019-8-15 09:38
不使用DMA ,单个通道ADC测试结果如何,先排队是硬件还是软件导致。

单通道采集同样的情况,能过确认的是外部电压是稳定的,没有变化。
12下一页

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版