请教STM32F030F4P6怎么使用内部参考电压?

2019-07-21 05:29发布

大家好,最近我在做一个精密的放大电路,需要12位的ADC,看中了STM32F030F4P6,ADC位数高,价格便宜。现在我碰到了一个问题,就是想使用它内部的参考电压,因为外接电压接了其他的负载,因此肯定抖动不小的,想使用内部的参考电压为ADC提供一个抖动较少的参考电压。但看了数据手册,感觉非常疑惑,手册中提到:1 channel for internal reference voltage (VREFINT),The internal voltage reference (VREFINT) provides a stable (bandgap) voltage output for the ADC and Comparators. VREFINT is internally connected to the ADC_IN17 input channel. The precise voltage of VREFINT is individually measured for each part by ST during production test and stored in the system memory area. It is accessible in read-only mode.
我比较疑惑了,内部参考电压接到ADC_IN17,怎么使用它呢?和AVR单片机内部的选择参考电压大不相同啊。求大神指点,谢谢!
我看到网上有人这样说:
具体方法是在测量某个通道的电压值之前,先读出参照电压的ADC测量数值,记为ADrefint;再读出要测量通道的ADC转换数值,记为ADchx;则要测量的电压为: Vchx = Vrefint * (ADchx/ADrefint) 其中Vrefint为参照电压=1.20V。 不知道这样对不对呢?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
it_do_just
1楼-- · 2019-07-21 10:22
本帖最后由 229382777@qq.com 于 2016-4-3 14:34 编辑

http://www.51hei.com/bbs/dpj-40944-1.html
这上面讲的比较清楚,因为内部参考电压1.2V比较稳定,不断通过内部通道ADC_IN17获取到ADC转换值,
然后根据公式:(1.2/ADC转换值) * 4096(12位精度)      就可以得到VDDA的电压值,从而检测电源,另外如果是想测试其他通道的电压值,直接读取对应通道的ADC转换值以后进行相乘就好了:(1.2/ADC转换值) * 其他通道ADC转换值
1.png
2.png
3.png

代码:
[mw_shl_code=c,true]/**
  * @brief  ADC Configuration
  * @param  None
  * @retval None
  */
static void ADC_Config(void)
{
  ADC_InitTypeDef     ADC_InitStructure;
  GPIO_InitTypeDef    GPIO_InitStructure;
  
  /* GPIOC Periph clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  
  /* ADC1 Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  
  /* Configure ADC Channel 0 as analog input */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  /* ADCs DeInit */  
  ADC_DeInit(ADC1);
  
  /* Initialize ADC structure */
  ADC_StructInit(&ADC_InitStructure);
        ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
        ADC_Init(ADC1, &ADC_InitStructure);
       
        /* Convert the ADC1 Channel 0 with 239.5 Cycles as sampling time */
  ADC_ChannelConfig(ADC1, ADC_Channel_Vrefint , ADC_SampleTime_239_5Cycles);
        ADC_VrefintCmd(ENABLE);
       
  /* 得到基准电压校准值 */
        VREFINT_CAL = *(__IO uint16_t *)(0X1FFFF7BA);
       
        /* ADC Calibration */
  ADC_GetCalibrationFactor(ADC1);
       
        /* 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);
}

// 主函数
int main(void)
{
        delay_ms(200);
        ADC_Config();
        UART1_Init();
       
        while(1)
        {
                VREFINT_DATA =ADC_GetConversionValue(ADC1);
                VDDA_VAL = (3.3*VREFINT_CAL)/VREFINT_DATA;
                printf(" VDDA:%.3fV ",VDDA_VAL);
                while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
                delay_ms(1000);
        }
}[/mw_shl_code]



正点原子
2楼-- · 2019-07-21 12:13
帮顶.....
yuyouliang
3楼-- · 2019-07-21 18:08
 精彩回答 2  元偷偷看……
yutuo
4楼-- · 2019-07-21 20:16
受教,谢谢

一周热门 更多>