在做低功耗
产品
的时候读取
芯片
温度和当前电压是十分重要的一件事情。通过当前
供电
电压可以知晓电池电量是否低于水平值实现电池缺电报警。读取芯片温度也很重要,可以在使用内部
振荡器
的时候通过校准
算法
根据温度变化来实现实时校准芯片。如果不使用或尽量少使用外部
元器件
来实现这两个功能是摆在我们面前一个很重要的事情,遗憾的是现在网上的
资料
非常混乱,基本上直接使用总有点那么别扭。如何读取芯片电压?当然肯定是需要用
ADC
了。不过这个时候需要有一个参考电压作为比对,很多人提出在外面使用一组
LDO
实现参考电压,那样其实LDO本身也有一定能耗,在我们追求极致低消耗的时候也不适合。当然很多人说了为什么不使用PVD来做,那么我来说说,PVD本身是做电压曲线检测的,如果你要求低于2.5V就报警,你会发现如果你启动电压<2.5V的时候无法检测出来。所以还是自己做。还好STM32L0单片机在内部有一个核心电压,并且有一个寄存器VREFINT_CAL值可以用作基准参考从而计算出相当比较精准的电压。经过测量,误差还是基本满足电池供电检测的要求。如何读取芯片温度?在STM32L0下,只要读到当前电压,配合温度寄存器,就可以取得当前温度了。当前温度误差比较大,即使高精度采样,为了节省运算时间,误差还是有3度的误差,因此这个地方需要宽泛一些。
#include "
stm32
l0xx_ll_
ad
c.h" //需要这个库实现公式计算//初始化void init_adc1(void){ ADC_ChannelConfTypeDef sConfig;
ha
dc
.Instance = ADC1; hadc.Init.OversamplingMode = DISABLE; hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1; hadc.Init.Resolu
ti
on = ADC_RESOLUTION_12B;//ADC_RESOLUTION_12B; hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5; //160.5cycles如果低于39.5cycles温度采样精准度不够 hadc.Init.S
can
ConvMode = ADC_SCAN_DIRECTION_F
OR
WARD; hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc.Init.ContinuousConvMode = DISABLE; hadc.Init.DiscontinuousConvMode = DISABLE; hadc.Init.Ex
te
rnalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc.Init.
DMA
ContinuousRequests = DISABLE; hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV; hadc.Init.Overrun = ADC_O
VR
_DATA_PRESERVED; hadc.Init.LowPowerAutoW
ai
t = DISABLE; hadc.Init.LowPowe
rF
requencyMode = DISABLE; hadc.Init.LowPowerAutoPowerOff = DISABLE; if (HAL_ADC_Init(&hadc) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }/**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_VREFINT; //初始化VREFINT_CAL参考电压 sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } sConfig.Channel = ADC_CHANNEL_TE
MPS
ENSOR; //初始化芯片温度
传感器
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }}//读取adc1值uint16_t readchannel_adc1(uint32_t Channel){ ADC_ChannelConfTypeDef adcConf; uint16_t adcData = 0; /* wait the the Vrefint used by adc is set */ while (__HAL_PWR_GET_FLAG(PWR_FLAG_VREFINTRDY) == RESET) {};//启动CLK
时钟
__HAL_RCC_ADC1_CLK_ENABLE();
/*calibrate ADC if any calibraiton hardware*/ HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED );
/* Deselects all channels*/ adcConf.Channel = ADC_CHANNEL_MASK; adcConf.Rank = ADC_RANK_NONE; HAL_ADC_ConfigChannel( &hadc, &adcConf);
/* configure adc channel */ adcConf.Channel = Channel; adcConf.Rank = ADC_RANK_CHANNEL_NUMBER; HAL_ADC_ConfigChannel( &hadc, &adcConf);
/* Start the conversion process */ HAL_ADC_Start(&hadc);
/* Wait for the end of conversion */ HAL_ADC_PollForConversion( &hadc, HAL_MAX_DELAY );
/* Get the converted value of regular channel */adcData+=HAL_ADC_GetValue(&hadc);
__HAL_ADC_DISABLE(&hadc);
__HAL_RCC_ADC1_CLK_DISABLE();
return adcData;}//具体调用代码void main(void){ init_adc1(); //完成初始化 uint16_tvdda_mV=__LL_ADC_CALC_VREF
ANALOG
_VOLTAGE(readchannel_adc1(ADC_CHANNEL_VREFINT),LL_ADC_RESOLUTION_12B);//取得当前VDDA的电压,单位mV uint16_t temp_degress = __LL_ADC_CALC_TEMPERATURE(vdda_mV,readchannel_adc1(ADC_CHANNEL_TEMPSENSOR),LL_ADC_RESOLUTION_12B); //取得当前的温度,单位摄氏度}
芯片
的AD/DA口基准
电压
和
芯片
供电
电压
的关系?
速率,
芯片
在进行AD/DA转换时,用到一个基准
电压
,这个基准
电压
和
芯片
的
供电
电压
是否有关联?而且
发表于
01-14 00:40
AD5144无法通过SPI
读取
和修改内部游标值怎么解决?
STM32
作为主控
芯片
发送
读取
、修改AD5144游标值的指令;而AD5144不返回相应游标值,而是返回
STM32
下发的指令。
VDD端由5.45V模拟
发表于
12-05 08:00
求助,求推荐低
温度
系数运放和
电压
源
芯片
要在-20到40度的环境
温度
下,产生一个稳定的500-100mv左右的单一固定参考
电压
,用作系统标定。
电压
可驱动50欧姆负载。
要求
温度
系数越小越好,带宽不做要求,只要求精度。
发表于
11-23 07:12
STM32
L4、
STM32
L4+和
STM32
G4系列微控制器上的专利代码
读取
保护
电子发烧友网站提供《
STM32
L4、
STM32
L4+和
STM32
G4系列微控制器上的专利代码
读取
保护.pdf》资料免费下载
发表于
09-19 16:16
•
0
次下载
STM32
L4、
STM32
L4+和
STM32
G4系列微控制器上的专利代码
读取
保护
电子发烧友网站提供《
STM32
L4、
STM32
L4+和
STM32
G4系列微控制器上的专利代码
读取
保护.pdf》资料免费下载
发表于
08-01 10:03
•
0
次下载
使用LoRa RA-02传输
温度
传感器从
STM32
Nucleo64
读取
温度
值
电子发烧友网站提供《使用LoRa RA-02传输
温度
传感器从
STM32
Nucleo64
读取
温度
值.zip》资料免费下载
发表于
06-19 16:34
•
1
次下载