cancel
Showing results for 
Search instead for 
Did you mean: 

When HCLK is reduced from 48MHz to 1Mhz, the internal reference voltage is read much larger which is wrong

XuefengJi
Associate

I'm using STM32F030F4, when use 48MHz HSI, everything seems ok, and the internal voltage reference is read as 1.24v. But when reduce the HCLK from 48MHz to 1MHz, the ADC seems work abnormal, the internal voltage is read as 1.41V. I tried different HCLK 48MHz, 8MHz, 4MHz, 2MHz, the internal voltage are all read about 1.22~1.24V, when 1MHz, it's 1.41V. Paste the ADC_config() code below. Does anyone ever have this problem?

=============================================

static void DAC_Config(void)

{

 DAC_InitTypeDef  DAC_InitStructure;

 GPIO_InitTypeDef  GPIO_InitStructure;

 /* Enable GPIOA clock */

 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

  

 /* Configure PA.04 (DAC_OUT1) in analog mode -------------------------*/

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

 GPIO_Init(GPIOA, &GPIO_InitStructure);

 /* Enable DAC clock */

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);

  

 /* DAC channel1 Configuration */

 DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;

 DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;

 DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;

 DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;

 /* DAC Channel1 Init */

 DAC_Init(DAC_Channel_1, &DAC_InitStructure);

  

 /* Enable DAC Channel1 */

 DAC_Cmd(DAC_Channel_1, ENABLE);

}

static void ADC_Config(void)

{

 ADC_InitTypeDef     ADC_InitStructure;

 GPIO_InitTypeDef     GPIO_InitStructure;

 DMA_InitTypeDef     DMA_InitStructure;

NVIC_InitTypeDef     NVIC_InitStructure;

 /* ADC1 and TIM1 Periph clock enable */

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

  

 /* Configure ADC Channels as analog input */

 GPIO_InitStructure.GPIO_Pin = PTC_PIN;//PA5, ADC_IN5

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

 GPIO_Init(PTC_PORT, &GPIO_InitStructure);

  

GPIO_InitStructure.GPIO_Pin = PWR_PIN;//PA6, ADC_IN6

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

 GPIO_Init(PWR_PORT, &GPIO_InitStructure);

  

GPIO_InitStructure.GPIO_Pin = SELFTEST_PIN;//PA0, ADC_IN0

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

 GPIO_Init(SELFTEST_PORT, &GPIO_InitStructure);

  

 /* ADC1 DeInit */  

 ADC_DeInit(ADC1);

  

 /* Initialize ADC structure */

 ADC_StructInit(&ADC_InitStructure);

  

 /* Configure the ADC1 in continous mode withe a resolution equal to 12 bits */

 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 

 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;   

 //ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC4;

 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

 ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;

 ADC_Init(ADC1, &ADC_InitStructure); 

  

 /* Convert the ADC1 Channel11 and channel10 with 239.5 Cycles as sampling time */ 

 ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_55_5Cycles);

 ADC_ChannelConfig(ADC1, ADC_Channel_5 , ADC_SampleTime_55_5Cycles);

 ADC_ChannelConfig(ADC1, ADC_Channel_6 , ADC_SampleTime_55_5Cycles);

  

/* Convert the ADC1 temperature sensor with 55.5 Cycles as sampling time */ 

 ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor , ADC_SampleTime_55_5Cycles);  

 ADC_TempSensorCmd(ENABLE);

  

 /* Convert the ADC1 Vref with 55.5 Cycles as sampling time */ 

 ADC_ChannelConfig(ADC1, ADC_Channel_Vrefint , ADC_SampleTime_55_5Cycles); 

 ADC_VrefintCmd(ENABLE);

  

 /* Convert the ADC1 Vbat with 55.5 Cycles as sampling time 

 ADC_ChannelConfig(ADC1, ADC_Channel_Vbat , ADC_SampleTime_28_5Cycles);  

 ADC_VbatCmd(ENABLE);*/ 

  

 /* ADC Calibration */

 ADC_GetCalibrationFactor(ADC1);

  

/* ADC DMA request in circular mode */

 ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_OneShot);

  

/* DMA1 clock enable */

 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);

 /* DMA1 Channel1 Config--for ADC */

 //DMA_DeInit(DMA1_Channel1);

 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;

 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RegularConvData_Tab;

 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

 DMA_InitStructure.DMA_BufferSize = 5;

 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

 DMA_InitStructure.DMA_Priority = DMA_Priority_High;

 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

 DMA_Init(DMA1_Channel1, &DMA_InitStructure);

//DMA interrupt

DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);//interrupt when transfer complete

 /* Enable DMA1 channel1 IRQ Channel */

 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;

 NVIC_InitStructure.NVIC_IRQChannelPriority = 1;

 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

 NVIC_Init(&NVIC_InitStructure);

 /* DMA1 Channel1 enable */

 DMA_Cmd(DMA1_Channel1, ENABLE);

  

/* Enable ADC_DMA */

 ADC_DMACmd(ADC1, ENABLE);  

  

 /* Enable the ADC peripheral */

 ADC_Cmd(ADC1, ENABLE);   

  

 /* Wait the ADRDY flag */

 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY)); 

  

 /* ADC1 regular Software Start Conv */ 

 ADC_StartOfConversion(ADC1);

}

2 REPLIES 2
Danish1
Lead II

Where in ADC_InitStructure do you set the clock-mode? It might be ADCCLK (HSI14 asynchronous) or PCLK/2 or PCLK/4.

The ADC may be clocked at any rate between 0.6 and 14 MHz (ref: Data sheet 6.3.16 12-bit ADC Characteristics).

If APB is 48 MHz, PCLK/4 will be within spec.

If APB is 1 MHz, PCLK/2 and PCLK/4 are out-of-spec so you might expect errors in conversion result.

Hope this helps,

Danish

XuefengJi
Associate

Thanks Danish, change the ADC clock source ​can solve the problem! But some different situation from document you use. I didn't explicit set the ADC clock source, but seems the default setting is 14MHz clock. When I explicit set clock source to 14MHz, the problem still there. But when change clock source to PCLK/2 or PCLK/4, the problem solved! The internal voltage read OK(1.24V) and seems other channel is also correct reading. The PCLK is still 1MHz. I don't know why...I'm referring DM00091010 document, and didn't see the ADC clock limitation. Which document are you using?

=============works well under PCLK 1MHz=================

static void ADC_Config(void)

{

 ADC_InitTypeDef     ADC_InitStructure;

 GPIO_InitTypeDef     GPIO_InitStructure;

 DMA_InitTypeDef     DMA_InitStructure;

NVIC_InitTypeDef     NVIC_InitStructure;

 /* ADC1 and TIM1 Periph clock enable */

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

  

 /* Configure ADC Channels as analog input */

 GPIO_InitStructure.GPIO_Pin = PTC_PIN;//PA5, ADC_IN5

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

 GPIO_Init(PTC_PORT, &GPIO_InitStructure);

  

GPIO_InitStructure.GPIO_Pin = PWR_PIN;//PA6, ADC_IN6

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

 GPIO_Init(PWR_PORT, &GPIO_InitStructure);

  

GPIO_InitStructure.GPIO_Pin = SELFTEST_PIN;//PA0, ADC_IN0

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

 GPIO_Init(SELFTEST_PORT, &GPIO_InitStructure);

  

 /* ADC1 DeInit */  

 ADC_DeInit(ADC1);

  

/* ADC clock mode*/

ADC_ClockModeConfig(ADC1, ADC_ClockMode_SynClkDiv2);

 /* Initialize ADC structure */

 ADC_StructInit(&ADC_InitStructure);

  

 /* Configure the ADC1 in continous mode withe a resolution equal to 12 bits */

 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 

 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;   

 //ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC4;

 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

 ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;

 ADC_Init(ADC1, &ADC_InitStructure); 

  

 /* Convert the ADC1 Channel11 and channel10 with 239.5 Cycles as sampling time */ 

 ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_55_5Cycles);

 ADC_ChannelConfig(ADC1, ADC_Channel_5 , ADC_SampleTime_55_5Cycles);

 ADC_ChannelConfig(ADC1, ADC_Channel_6 , ADC_SampleTime_55_5Cycles);

  

/* Convert the ADC1 temperature sensor with 55.5 Cycles as sampling time */ 

 ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor , ADC_SampleTime_55_5Cycles);  

 ADC_TempSensorCmd(ENABLE);

  

 /* Convert the ADC1 Vref with 55.5 Cycles as sampling time */ 

 ADC_ChannelConfig(ADC1, ADC_Channel_Vrefint , ADC_SampleTime_55_5Cycles); 

 ADC_VrefintCmd(ENABLE);

  

 /* Convert the ADC1 Vbat with 55.5 Cycles as sampling time 

 ADC_ChannelConfig(ADC1, ADC_Channel_Vbat , ADC_SampleTime_28_5Cycles);  

 ADC_VbatCmd(ENABLE);*/ 

  

 /* ADC Calibration */

 ADC_GetCalibrationFactor(ADC1);

  

/* ADC DMA request in circular mode */

 ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_OneShot);

  

/* DMA1 clock enable */

 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);

 /* DMA1 Channel1 Config--for ADC */

 //DMA_DeInit(DMA1_Channel1);

 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;

 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RegularConvData_Tab;

 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

 DMA_InitStructure.DMA_BufferSize = 5;

 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

 DMA_InitStructure.DMA_Priority = DMA_Priority_High;

 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

 DMA_Init(DMA1_Channel1, &DMA_InitStructure);

//DMA interrupt

DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);//interrupt when transfer complete

 /* Enable DMA1 channel1 IRQ Channel */

 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;

 NVIC_InitStructure.NVIC_IRQChannelPriority = 1;

 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

 NVIC_Init(&NVIC_InitStructure);

 /* DMA1 Channel1 enable */

 DMA_Cmd(DMA1_Channel1, ENABLE);

  

/* Enable ADC_DMA */

 ADC_DMACmd(ADC1, ENABLE);  

  

 /* Enable the ADC peripheral */

 ADC_Cmd(ADC1, ENABLE);   

  

 /* Wait the ADRDY flag */

 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY)); 

  

 /* ADC1 regular Software Start Conv */ 

 ADC_StartOfConversion(ADC1);

}