[STM32F3] STM32F303 ADC 多通道采集有问题

[复制链接]
5598|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 结果又是对的、

下面上代码


  1. // Enable ADC1 clock
  2.   if((RCC->AHBENR & RCC_AHBENR_ADC12EN) == 0)
  3.     RCC->AHBENR |= RCC_AHBENR_ADC12EN;
  4.   // Enable ADC3 clock
  5.   if((RCC->AHBENR & RCC_AHBENR_ADC34EN) == 0)
  6.     RCC->AHBENR |= RCC_AHBENR_ADC34EN;
  7.   // Enable GPIOB clock
  8.   if((RCC->AHBENR & RCC_AHBENR_GPIOBEN) == 0)
  9.     RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
  10.   // Enable DMA2 clock
  11.         if((RCC->AHBENR & RCC_AHBENR_DMA2EN) == 0)
  12.                 RCC->AHBENR |= RCC_AHBENR_DMA2EN;
  13.   
  14.   /* 设置 PB1 为模拟输入 */
  15.   GPIO_InitTypeDef GPIO_InitStructure;
  16.   GPIO_StructInit(&GPIO_InitStructure);
  17.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  18.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  19.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  20.   GPIO_Init(GPIOB, &GPIO_InitStructure);
  21.   
  22.   /* 复位 ADC */
  23.   ADC_DeInit(ADC1);
  24.   ADC_DeInit(ADC3);
  25.   
  26.   /* ADC 时钟配置为 72M/128 */
  27.   RCC_ADCCLKConfig(RCC_ADC34PLLCLK_Div128);
  28.   RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div128);

  29.   /* ADC 共用寄存器配置 */
  30.   ADC1_2->CCR &= ~ADC12_CCR_CKMODE;   // ADC 异步时钟(取自 PLL)
  31.   ADC3_4->CCR &= ~ADC34_CCR_CKMODE;
  32.   ADC1_2->CCR &= ~ADC12_CCR_MULTI;    // ADC 独立模式
  33.   ADC3_4->CCR &= ~ADC34_CCR_MULTI;
  34.   
  35.   /* ADC 通道数量、分辨率、数据对齐、转换模式和注入状态配置 */
  36.   ADC_InitTypeDef ADC_InitStructure;
  37.   ADC_StructInit(&ADC_InitStructure);
  38.   ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;
  39.   ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;
  40.   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  41.   ADC_InitStructure.ADC_NbrOfRegChannel = 2;
  42.   ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  43.   ADC_Init(ADC3, &ADC_InitStructure);
  44.   ADC_InitStructure.ADC_NbrOfRegChannel = 1;
  45.   ADC_Init(ADC1, &ADC_InitStructure);
  46.   
  47.   /* 打开温度传感器和内部参考电压到 ADC 通道的模拟开关 */
  48.   ADC1_2->CCR |= ADC12_CCR_TSEN;
  49.   ADC3_4->CCR |= ADC34_CCR_VREFEN;
  50.   
  51.   /* ADC 通道配置 */
  52.   ADC_RegularChannelConfig(ADC1, ADC_Channel_TempSensor, 1, ADC_SampleTime_1Cycles5);
  53.   ADC_RegularChannelConfig(ADC3, ADC_Channel_1, 1, ADC_SampleTime_1Cycles5);
  54.   ADC_RegularChannelConfig(ADC3, ADC_Channel_Vrefint, 2, ADC_SampleTime_1Cycles5);

  55.   /* DMA 初始化操作 */
  56.   DMA2_Channel5->CNDTR = 2;
  57.         DMA2_Channel5->CMAR = (uint32_t)adcdr;
  58.         DMA2_Channel5->CPAR = (uint32_t)&ADC3->DR;
  59.         DMA2_Channel5->CCR =
  60.                                         DMA_M2M_Disable |
  61.                                         DMA_Priority_Low |
  62.                                         DMA_MemoryDataSize_HalfWord |        
  63.                                         DMA_PeripheralDataSize_HalfWord |
  64.                                         DMA_MemoryInc_Enable |
  65.                                         DMA_PeripheralInc_Disable |
  66.                                         DMA_Mode_Circular |
  67.                                         DMA_DIR_PeripheralSRC |
  68.                                   DMA_CCR_EN;
  69.   /* 设置 ADC3 的 DMA 为循环模式 */
  70.   ADC3->CFGR |= ADC_CFGR_DMACFG;
  71.   /* ADC3 DMA 启动 */
  72.   ADC3->CFGR |= ADC_CFGR_DMAEN;
  73.   
  74.   /* ADC 启用电压稳定器 */
  75.   ADC_VoltageRegulatorCmd(ADC1, ENABLE);
  76.   ADC_VoltageRegulatorCmd(ADC3, ENABLE);
  77.   delay(1000);  // Delay >= 10us
  78.   
  79.   /**** ADC 校正 ****/
  80.   /* 设置为校准 单端(single-end) 通道 */
  81.   ADC1->CR &= ~ADC_CR_ADCALDIF;
  82.   ADC3->CR &= ~ADC_CR_ADCALDIF;
  83.   /* 开启校正 */
  84.   ADC1->CR |= ADC_CR_ADCAL;
  85.   ADC3->CR |= ADC_CR_ADCAL;
  86.   /* 等待校正完成 */
  87.   while(ADC1->CR & ADC_CR_ADCAL);
  88.   while(ADC3->CR & ADC_CR_ADCAL);
  89.   uint32_t calibration_factor = ADC3->CALFACT & 0x0000007f;
  90.   
  91.   /* 启动 ADC */
  92.   ADC1->CR |= ADC_CR_ADEN;
  93.   ADC3->CR |= ADC_CR_ADEN;
  94.   /* 等待 ADC 启动完成 */
  95.   while(!(ADC1->ISR & ADC_ISR_ADRD));
  96.   while(!(ADC3->ISR & ADC_ISR_ADRD));
  97.   
  98.   /* 启动 ADC 转换 */
  99.   ADC1->CR |= ADC_CR_ADSTART;
  100.   ADC3->CR |= ADC_CR_ADSTART;

评论

想问下你这个问题解决了么?我目前内部温度传感器读值4095 内部参考是正确的  发表于 2021-11-2 12:02
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 | 显示全部楼层
没人给个提示吗
玄德 发表于 2015-12-24 16:53 | 显示全部楼层
本帖最后由 玄德 于 2015-12-24 16:55 编辑


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

 楼主| Volftooth 发表于 2015-12-25 14:34 | 显示全部楼层
玄德 发表于 2015-12-24 16:53
AD不会这么差。
先仔细查硬件,再外接个电压信号试试。

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

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

越来越不懂了、


我是主要想用内部参考电压来校正校准、
 楼主| Volftooth 发表于 2016-1-12 11:07 | 显示全部楼层
这问题好多天了有大神指点一下吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

14

主题

61

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部