本帖最后由 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;
|
想问下你这个问题解决了么?我目前内部温度传感器读值4095 内部参考是正确的