【发布时间】:2020-02-08 05:15:52
【问题描述】:
我正在尝试在 STM32F042 微控制器上读取 VDDA。当 VDD 为 3.29V 时,我得到了意想不到的结果。我一定错过了一些基本的东西。
输出:
VREFINT=1917; VREFINT_CAL=1524; VDDA=2623 mV
VREFINT=1885; VREFINT_CAL=1524; VDDA=2668 mV
VREFINT=1913; VREFINT_CAL=1524; VDDA=2628 mV
VREFINT=1917; VREFINT_CAL=1524; VDDA=2623 mV
VREFINT=1917; VREFINT_CAL=1524; VDDA=2623 mV
adc_test.c:
#include <stdio.h>
#include "stm32f0xx.h"
#define VREFINT_CAL_ADDR 0x1FFFF7BA /* datasheet p. 19 */
#define VREFINT_CAL ((uint16_t*) VREFINT_CAL_ADDR)
extern void initialise_monitor_handles(void);
int main(void)
{
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; /* enable ADC peripheral clock */
RCC->CR2 |= RCC_CR2_HSI14ON; /* start ADC HSI */
while (!(RCC->CR2 & RCC_CR2_HSI14RDY)); /* wait for completion */
/* calibration */
ADC1->CR |= ADC_CR_ADCAL; /* start ADc CALibration */
while (ADC1->CR & ADC_CR_ADCAL); /* wait for completion */
ADC1->CR |= ADC_CR_ADEN; /* ADc ENable */
while (!(ADC1->ISR & ADC_ISR_ADRDY)); /* wait for completion */
ADC1->SMPR |= ADC_SMPR1_SMPR_0 | /* sampling mode: longest */
ADC_SMPR1_SMPR_1 |
ADC_SMPR1_SMPR_2;
/* VDD reference */
ADC->CCR |= ADC_CCR_VREFEN; /* VREF Enable */
ADC1->CHSELR = ADC_CHSELR_CHSEL17; /* CH17 = VREFINT */
initialise_monitor_handles(); /* enable semihosting */
while (1) {
ADC1->CR |= ADC_CR_ADSTART; /* start ADC conversion */
while (!(ADC1->ISR & ADC_ISR_EOC)); /* wait for completion */
uint32_t vdda = 3300UL * *VREFINT_CAL / ADC1->DR; /* ref. manual p. 252; constant and result in millivolts */
printf("VREFINT=%lu; VREFINT_CAL=%lu; VDDA=%lu mV\n",
(unsigned long)ADC1->DR,
(unsigned long)*VREFINT_CAL,
(unsigned long)vdda);
}
}
数据表截图:
参考手册截图
注意这是指 .3V,但我认为这是一个错字,因为上面的数据表和下面较长的公式指的是 3.3V,而 .3V 低于这部分的最低工作电压
【问题讨论】:
-
我看不出你的代码有什么明显错误,我可以确认参考手册中的
.3而不是3.3确实是一个错字(我在网上找到的副本没有有那个错误)。关于这个问题的一个疯狂猜测——你是否可能让 Vssa 引脚悬空,而不是接地? (假设您使用的是实际上具有单独 Vssa 引脚的 STM32F042 变体。)您在计算 Vdda 时的错误可疑地接近一个二极管压降,如果负参考电压浮动,这似乎是一个合理的结果。 -
这是一个有趣的想法,但是引脚(引脚 32)连接到 GND:imgur.com/gMo2GsH 有趣的是,散热垫没有连接任何东西。
-
该原理图大错特错 - 它显示了该部件的 UFQFNP32 变体的部件号,但根据 LQFP32 变体(甚至没有导热垫)标记了引脚。在 UFQFPN32 上,引脚 16 和 32 是额外的端口 B I/O 引脚,散热垫是您的唯一接地连接,绝对需要正确操作。基本上,您的芯片仅通过某些 I/O 引脚上的 ESD 保护二极管接地,而 2.62V 是芯片接收到的电源的准确测量值。
-
Owwww......你说得对。以前版本的原理图需要 LQFP32,然后改为 UFQFNP32,我猜硬件人员没有仔细阅读数据表。这看起来很糟糕......我很惊讶芯片完全可以工作,而且做得很好(在数字领域)。显然必须在董事会的下一次旋转中解决这个问题。作为权宜之计,将 PB2 和 PB8 设置为输入而不是高阻值是否有助于将芯片中的更多电路连接到地,或者 ESD 二极管是唯一的接地路径?
-
不要认为输入与 hi-Z 有任何区别。将引脚设置为输出低电平实际上可能会获得更好的接地路径,尽管这很危险——即使是短暂的输出高电平状态也可能会烧毁一些东西。如果芯片下方有一个没有走线的点,您也许可以从背面铣穿并实际连接到导热垫。 (嘿,可能会更糟 - 我见过类似的“错误足迹”电路板布局,其中两个足迹基本上旋转了 90° - 绝对没有任何东西连接到可用的引脚。)