利用ADC15在内部固定接的1.19V的辅助固定信号源,反推其他通道
利用ADC15在内部固定接的1.19V的辅助固定信号源,反推其他通道的输入电压https://www.stcaimcu.com/forum.php?mod=viewthread&tid=3763
C语言代码
//测试工作频率为11.0592MHz
#include "stc8h.h"
#include "intrins.h"
#define FOSC 11059200UL
#define BRT (65536-(FOSC / 115200+2) / 4)
//加2操作是为了让Keil编译器
//自动实现四舍五入运算
int *BGV; //内部参考信号源值存放在idata中
//idata的EFH地址存放高字节
//idata的F0H地址存放低字节
//电压单位为毫伏(mV)
bit busy;
void UartIsr() interrupt 4
{
if(TI)
{
TI = 0;
busy = 0;
}
if(RI)
{
RI = 0;
}
}
void UartInit()
{
SCON= 0x50;
TMOD= 0x00;
TL1= BRT;
TH1= BRT >> 8;
TR1= 1;
AUXR= 0x40;
busy= 0;
}
void UartSend(char dat)
{
while(busy);
busy= 1;
SBUF= dat;
}
void ADCInit()
{
ADCTIM= 0x3f; //设置ADC内部时序
ADCCFG= 0x2f; //设置ADC时钟为系统时钟/2/16
ADC_CONTR= 0x8f; //使能ADC模块,并选择第15通道
}
int ADCRead()
{
intres;
ADC_CONTR|= 0x40; //启动AD转换
_nop_();
_nop_();
while(!(ADC_CONTR & 0x20)); //查询ADC完成标志
ADC_CONTR&= ~0x20; //清完成标志
res= (ADC_RES << 8) | ADC_RESL; //读取ADC结果
returnres;
}
void main()
{
intres;
intvcc;
inti;
P_SW2|= 0x80; //使能访问XFR
P0M0= 0x00;
P0M1= 0x00;
P1M0= 0x00;
P1M1= 0x00;
P2M0= 0x00;
P2M1= 0x00;
P3M0= 0x00;
P3M1= 0x00;
P4M0= 0x00;
P4M1= 0x00;
P5M0= 0x00;
P5M1= 0x00;
BGV= (int idata *)0xef;
ADCInit(); //ADC初始化
UartInit(); //串口初始化
ES= 1;
EA= 1;
// ADCRead();
// ADCRead(); //前两个数据建议丢弃
res= 0;
for(i=0; i<8; i++)
{
res += ADCRead(); //读取8次数据
}
res>>= 3; //取平均值
vcc= (int)(4096L * *BGV / res); //(12位ADC算法)计算VREF管脚电压,即电池电压
// vcc= (int)(1024L * *BGV / res); //(10位ADC算法)计算VREF管脚电压,即电池电压
//注意,此电压的单位为毫伏(mV)
UartSend(vcc>> 8); //输出电压值到串口
UartSend(vcc);
while(1);
}
上面的方法是使用ADC的第15通道反推外部 MCU_VCC电压 / 电池电压 的, 电池直接给MCU_VCC供电。
在ADC测量范围内,ADC的外部测量电压与ADC的测量值是成正比例的,
所以也可以使用ADC的第15通道反推外部通道输入电压,
假设
当前已获取了内部参考信号源电压为BGV,
内部参考信号源的ADC测量值为resbg,
外部通道输入电压的ADC测量值为resx,
则外部通道输入电压Vx=BGV / resbg * resx;
为啥不在内部集成一个精密一些的ref呢? 十年前在64脚stm32上这样用,这是穿越回去了吗 zxq6 发表于 2023-8-15 15:35
为啥不在内部集成一个精密一些的ref呢?
(引用自2楼)
去www.stcaimcu.com 与STC研发交流 qtechzdh 发表于 2023-8-15 22:56
十年前在64脚stm32上这样用,这是穿越回去了吗
(引用自3楼)
去www.stcaimcu.com 与STC研发交流讨论
页:
[1]