打印
[STM32F3]

STM32F303 ADC 多通道采集有问题

[复制链接]
5257|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Volftooth|  楼主 | 2015-12-22 17:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Volftooth 于 2016-1-12 11:10 编辑

程序里面用到了内部测温Vts、内部参考电压Vrefint和一个外部模拟输入口ADC_CH1、其中测温使用的 ADC1、内部参考电压和外部输入使用的是 ADC3、

当同时启用所有通道时、只有外部的 CH1 测得的数据是对的、
其余的温度和内部参考电压测出来的结果都不正确、

内部温度通道测出来的值一直都是 4095、
内部参考电压的值在 2200 上下浮动、但内部的 REFINT_CAL 的值是 1553、所以计算出来的 Vdda 结果不正确、

ADC[0]:1996
ADC[1]:2201, Vdda=2.328V

但是如果只启动内部参考电压的通道、不用直它通道则测出来的 Vrefint 结果又是对的、

下面上代码


// Enable ADC1 clock
  if((RCC->AHBENR & RCC_AHBENR_ADC12EN) == 0)
    RCC->AHBENR |= RCC_AHBENR_ADC12EN;
  // Enable ADC3 clock
  if((RCC->AHBENR & RCC_AHBENR_ADC34EN) == 0)
    RCC->AHBENR |= RCC_AHBENR_ADC34EN;
  // Enable GPIOB clock
  if((RCC->AHBENR & RCC_AHBENR_GPIOBEN) == 0)
    RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
  // Enable DMA2 clock
        if((RCC->AHBENR & RCC_AHBENR_DMA2EN) == 0)
                RCC->AHBENR |= RCC_AHBENR_DMA2EN;
  
  /* 设置 PB1 为模拟输入 */
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_StructInit(&GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  /* 复位 ADC */
  ADC_DeInit(ADC1);
  ADC_DeInit(ADC3);
  
  /* ADC 时钟配置为 72M/128 */
  RCC_ADCCLKConfig(RCC_ADC34PLLCLK_Div128);
  RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div128);

  /* ADC 共用寄存器配置 */
  ADC1_2->CCR &= ~ADC12_CCR_CKMODE;   // ADC 异步时钟(取自 PLL)
  ADC3_4->CCR &= ~ADC34_CCR_CKMODE;
  ADC1_2->CCR &= ~ADC12_CCR_MULTI;    // ADC 独立模式
  ADC3_4->CCR &= ~ADC34_CCR_MULTI;
  
  /* ADC 通道数量、分辨率、数据对齐、转换模式和注入状态配置 */
  ADC_InitTypeDef ADC_InitStructure;
  ADC_StructInit(&ADC_InitStructure);
  ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;
  ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfRegChannel = 2;
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_Init(ADC3, &ADC_InitStructure);
  ADC_InitStructure.ADC_NbrOfRegChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);
  
  /* 打开温度传感器和内部参考电压到 ADC 通道的模拟开关 */
  ADC1_2->CCR |= ADC12_CCR_TSEN;
  ADC3_4->CCR |= ADC34_CCR_VREFEN;
  
  /* ADC 通道配置 */
  ADC_RegularChannelConfig(ADC1, ADC_Channel_TempSensor, 1, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC3, ADC_Channel_1, 1, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC3, ADC_Channel_Vrefint, 2, ADC_SampleTime_1Cycles5);

  /* DMA 初始化操作 */
  DMA2_Channel5->CNDTR = 2;
        DMA2_Channel5->CMAR = (uint32_t)adcdr;
        DMA2_Channel5->CPAR = (uint32_t)&ADC3->DR;
        DMA2_Channel5->CCR =
                                        DMA_M2M_Disable |
                                        DMA_Priority_Low |
                                        DMA_MemoryDataSize_HalfWord |        
                                        DMA_PeripheralDataSize_HalfWord |
                                        DMA_MemoryInc_Enable |
                                        DMA_PeripheralInc_Disable |
                                        DMA_Mode_Circular |
                                        DMA_DIR_PeripheralSRC |
                                  DMA_CCR_EN;
  /* 设置 ADC3 的 DMA 为循环模式 */
  ADC3->CFGR |= ADC_CFGR_DMACFG;
  /* ADC3 DMA 启动 */
  ADC3->CFGR |= ADC_CFGR_DMAEN;
  
  /* ADC 启用电压稳定器 */
  ADC_VoltageRegulatorCmd(ADC1, ENABLE);
  ADC_VoltageRegulatorCmd(ADC3, ENABLE);
  delay(1000);  // Delay >= 10us
  
  /**** ADC 校正 ****/
  /* 设置为校准 单端(single-end) 通道 */
  ADC1->CR &= ~ADC_CR_ADCALDIF;
  ADC3->CR &= ~ADC_CR_ADCALDIF;
  /* 开启校正 */
  ADC1->CR |= ADC_CR_ADCAL;
  ADC3->CR |= ADC_CR_ADCAL;
  /* 等待校正完成 */
  while(ADC1->CR & ADC_CR_ADCAL);
  while(ADC3->CR & ADC_CR_ADCAL);
  uint32_t calibration_factor = ADC3->CALFACT & 0x0000007f;
  
  /* 启动 ADC */
  ADC1->CR |= ADC_CR_ADEN;
  ADC3->CR |= ADC_CR_ADEN;
  /* 等待 ADC 启动完成 */
  while(!(ADC1->ISR & ADC_ISR_ADRD));
  while(!(ADC3->ISR & ADC_ISR_ADRD));
  
  /* 启动 ADC 转换 */
  ADC1->CR |= ADC_CR_ADSTART;
  ADC3->CR |= ADC_CR_ADSTART;
评论
sunshine8899 2021-11-2 12:02 回复TA
想问下你这个问题解决了么?我目前内部温度传感器读值4095 内部参考是正确的 
沙发
paderboy| | 2015-12-22 17:31 | 只看该作者
F3系列的ADC也是需要校准一下。。。你看看是不是这个问题。。

使用特权

评论回复
板凳
Volftooth|  楼主 | 2015-12-23 14:28 | 只看该作者
paderboy 发表于 2015-12-22 17:31
F3系列的ADC也是需要校准一下。。。你看看是不是这个问题。。

我做校准了啊、而且就算不校准也不可能差那么多吧?

使用特权

评论回复
地板
Volftooth|  楼主 | 2015-12-24 16:04 | 只看该作者
没人给个提示吗

使用特权

评论回复
5
玄德| | 2015-12-24 16:53 | 只看该作者
本帖最后由 玄德 于 2015-12-24 16:55 编辑


AD不会这么差。
先仔细查硬件,再外接个电压信号试试。

使用特权

评论回复
6
Volftooth|  楼主 | 2015-12-25 14:34 | 只看该作者
玄德 发表于 2015-12-24 16:53
AD不会这么差。
先仔细查硬件,再外接个电压信号试试。

测外部电压还可以、跳动很少的、准确度也可以、

但是测内部参考电压就出问题了、但是如果将 VBATEN 也打开就测得正常了、
但是我在手册上没发现 Vbat 和 Vrefint 有关联啊?

越来越不懂了、


我是主要想用内部参考电压来校正校准、

使用特权

评论回复
7
Volftooth|  楼主 | 2016-1-12 11:07 | 只看该作者
这问题好多天了有大神指点一下吗?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:好想睡觉好想睡觉!! 困困困困困

14

主题

61

帖子

1

粉丝