STC8H8K64U Vref脚测不到电压
如题,换了两个不同批次的芯片一样的程序,测试版芯片就ok换新买的芯片就没有数值。mcu采用1s锂电降压到3.3v供电,电源为锂电池,用73k电阻接电池正极两串分压接地取1/2电池电压接入VRef引脚,
取两次电压之和得到检测电压,程序如下:
void ADCinit()
{
P_SW2|=0x80;
ADCTIM=0x3f;
P_SW2&=0x7f;
ADCCFG = 0x2f; //设置ADC时钟为系统时钟/2/16/16
ADC_CONTR = 0x80;
}
/************ADC数据显示************/
void ShowResult(uint cl)
{
uint ADCbg;
uchar a1;
// P1M0 = 0x00; //设置P1.7为ADC口
//P1M1 = 0xff;
for(a1=0;a1<8;a1++)
{
ADC_CONTR |= cl; //使能ADC模块 选择15通道
ADC_CONTR |= 0x40; //启动AD转换
_nop_();
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & 0x20)); //查询ADC完成标志
ADC_CONTR &= ~0x20; //清完成标志
ADCbg=(ADC_RES<<8)|ADC_RESL;
if(a1==3)//第一次采样
{
Vx=(uint)(4096L**BGV/ADCbg);
}
if(a1==7)//第二次采样累加
{
Vx=Vx+(uint)(4096L**BGV/ADCbg);
}
}
用isp里面的例程如下:
#include "reg51.h"
#include "intrins.h"
#define FOSC 11059200UL
#define BRT (65536 - FOSC / 115200 / 4)
sfr AUXR = 0x8e;
sfr ADC_CONTR = 0xbc;
sfr ADC_RES = 0xbd;
sfr ADC_RESL = 0xbe;
sfr ADCCFG = 0xde;
sfr P_SW2 = 0xba;
#define ADCTIM(*(unsigned char volatile xdata *)0xfea8)
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sfr P5M1 = 0xc9;
sfr P5M0 = 0xca;
int *BGV; //内部1.19V参考信号源值存放在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()
{
P_SW2 |= 0x80;
ADCTIM = 0x3f; //设置ADC内部时序
P_SW2 &= 0x7f;
ADCCFG = 0x2f; //设置ADC时钟为系统时钟/2/16
ADC_CONTR = 0x8f; //使能ADC模块,并选择第15通道
}
int ADCRead()
{
int res;
ADC_CONTR |= 0x40; //启动AD转换
_nop_();
_nop_();
while (!(ADC_CONTR & 0x20)); //查询ADC完成标志
ADC_CONTR &= ~0x20; //清完成标志
res = (ADC_RES << 8) | ADC_RESL; //读取ADC结果
return res;
}
void main()
{
int res;
int vcc;
int i;
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)(1024L * *BGV / res); //(10位ADC算法)计算VREF管脚电压,即电池电压
vcc = (int)(4096L * *BGV / res); //(12位ADC算法)计算VREF管脚电压,即电池电压
//注意,此电压的单位为毫伏(mV)
UartSend(vcc >> 8); //输出电压值到串口
UartSend(vcc);
while (1);
}
串口返回数据00 00
同一块板子换老的测试版芯片返回数据08 4f或者08 4d
芯片图片如下:
serafim 发表于 2023-5-30 13:43
大概找到问题8h8k的BGV在rom存放地址是?
可以参考手册范例程序哦!
自己的程序时钟用内部33.1776MHz频率
例程用11.0592MHz
大概找到问题8h8k的BGV在rom存放地址是? 7.4.6u固件只能从IPID中取 第一步,用STC官方例子测试。
第二部,再修改、移植程序。
Vref要接稳定的电压,你从电池座1/2分压送Vref,电压降不稳定,但不至于转换不到读数。并且Vref对地要接一个103~104的电容。 楼主用的有2个版本,请直接使用 其中的量产版本 D 版本研发生产
https://www.stcaimcu.com/data/attachment/forum/202305/30/123217igo1fzn4tnzgqwm1.jpg
原理图的PDF也发上来,梁工好帮你分析
73k串联分压给vref做基准?我记得一般基准是有电流要求的,还是弄个跟随器或者减小分压电阻的阻值。 xhbwork 发表于 2023-6-8 08:12
73k串联分压给vref做基准?我记得一般基准是有电流要求的,还是弄个跟随器或者减小分压电阻的阻值。 ...
STC8H外部ADC_VRef+管脚需要的供电电流和允许的供电电压是多少?
===1,ADC_VRef+管脚需要的供电电流 ?< 1mA, 所有的基准源都可以满足要求
===2,ADC_VRef+管脚允许的供电电压: 2.4V =< ADC_VREF <=VCC/AVcc
https://www.stcaimcu.com/data/attachment/forum/202301/12/123610xoxnddlzx9zad9cu.png
https://www.stcaimcu.com/data/attachment/forum/202301/12/123610eurcs111xz1hruhx.png
STC32位8051芯片 发表于 2023-6-8 09:05
帮你回答问题的,不是请教问题{:lol:}
页:
[1]
2