本帖最后由 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;
|