8H1K08-36I-TSSOP20的ADC是10位,
0 ~ 1023
芯片的5 6 7脚都有接,我现在就是可以测出来芯片的供电电压,用可调电源测试过,在给芯片供电电压是5.08V,串口打印的是13 EA也就是5098(5.098V),给芯片供电调到4.22V时,串口打印的是10 A1也就是4257(4.257V)
在给芯片供电调到3.83V时,串口打印的是0F 18也就是3864(3.864V),说明通过内部1.19V反推出来的电池电压是准确的,为什么我用这个电池电压的值去参与P3.2也就是ADC10通道的ADC计算电压就不正常,换成P1.0也就是ADC0通道也是一样不正常。
不知道是哪里的问题。在已经反推出芯片供电电压的值了,是不是就可以用这个芯片电压值去参与ADC的计算来获得其对应的ADC通道电压
AI8H1K08-QFN20芯片ADC一但通过内部1.19V测量供电电压时原本正常的P1.0电压就不正常
AI8H1K08-QFN20芯片ADC一但通过内部1.19V测量供电电压时原本正常的P1.0电压就不正常,为什么呢?在没有通过1.19V测量芯片供电电压时,P1.0-ADC0采集的电压正常(ADC0-P1.0参考电压为电源5.09V通过串口1发送电压数据显示OK)
硬件连接:
芯片采用AI8H1K08-QFN20
芯片供电采用USB供电,测量芯片供电电压为5.09V
芯片的6脚ADC_VRef+和供电VCC 5脚接在一起。
芯片的16脚也就是P1.0(ADC0通道)通过电位器中心脚连接到芯片供电
调节电位器P1.0脚电压会变化,通过串口1进行打印输出,在没有加测量
(Read_VCC()//读取芯片供电VCC)函数时P1.0电压变化正,常用万用表测量
电压与串口打印数据基本一致(串口1接的数据是03DE=990 万用表测量为:0.99V BCCC=3020 3.02V)
说明P1.0的ADC转换电压正确
为什么在加入 (Read_VCC()//读取芯片供电VCC函数是就不正常了?
在加入 (Read_VCC()//读取芯片供电VCC函数时P1.0 ADC电压就不正确了?
但是这个 (Read_VCC()//读取芯片供电VCC函数读取的芯片供电电压又是正常的,为什么呢?
完整程序:
#include<AI8H.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
int *BGV;
int VCC,resMCU;
bit B_TX_Busy = 0; //发送忙标志
static char time_cous=0;
bit Time_flag=0;
bit Send_flag=0;
float res=0,Volate=0;
uint ADD=0;
sbit led1=P3^6;
sbit led2=P3^5;
//*********************************************
void Delay10ms(void) //@24.000MHz
{
unsigned char data i, j, k;
i = 2;
j = 56;
k = 172;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
//*********************************************
void port_init()
{
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x0E;
P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
P6M0 = 0x00;
P6M1 = 0x00;
}
//*********************************************
void Timer0_Init(void) //10毫秒@24.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xE0; //设置定时初始值
TH0 = 0xB1; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
}
//*********************************************
void Uart1_Init(void) //9600bps@24.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x8F; //设置定时初始值
T2H = 0xFD; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
ES = 1; //使能串口1中断
}
//*********************************************
void Uart1SendData(uchar ch)
{
while(B_TX_Busy); //不忙后发送数据
SBUF = ch; //写数据到UART数据寄存器
B_TX_Busy = 1;
}
//*********************************************
void Uart1_Isr(void) interrupt 4
{
if (TI) //检测串口1发送中断
{
TI = 0; //清除串口1发送中断请求位
B_TX_Busy = 0;
}
if (RI) //检测串口1接收中断
{
RI = 0; //清除串口1接收中断请求位
}
}
//*********************************************
void Timer0_Isr(void) interrupt 1
{//10ms
time_cous++;
if(time_cous>99)//100*10=1000ms=1s
{
time_cous=0;
Time_flag=!Time_flag;
Send_flag=1;
}
}
//*********************************************
void ADC_init()
{
P1M0 = 0x00; //设置P1.0为ADC口
P1M1 = 0x01;
P_SW2 |= 0x80;
ADCTIM = 0x3f; //设置ADC内部时序
P_SW2 &= 0x7f;
ADCCFG = 0x2f; //设置ADC时钟为系统时钟/2/16OF
ADC_CONTR = 0x80; //使能ADC模块
}
//*********************************************
uint ADC_aul()
{
uint result;
ADC_CONTR |= 0x40; //启动AD转换
_nop_();
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & 0x20)); //查询ADC完成标志
ADC_CONTR &= ~0x20; //清完成标志
result=(ADC_RES << 8) | ADC_RESL; //读取ADC结果--ADCCFG = 0x2f;
// result = (ADC_RES << 2) | (ADC_RESL & 0x03); //组合10位结果 --ADCCFG = 0x0f;
returnresult;
}
//*********************************************
void adc_Volate()
{
char i=0;
res = 0;
for (i=0; i<8; i++)
{
res += ADC_aul(); //读取8次数据
}
res /=8; //取平均值
Volate=(res * 5.09) / 1023.0; // 计算实际电压值
ADD=Volate*1000;
}
//*********************************************
int ADCRead()//芯片VCC
{
int resX;
// ADC_CONTR|=0x40; //启动转换 芯片VCC-OK
ADC_CONTR|=0x4F; //启动转换 不管是40还是4F测量的芯片供电电压都正确
_nop_();
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR&0x20));//查询ADC完成标志
ADC_CONTR&=~0x20; //清完成标志
resX=(ADC_RES<<8)|ADC_RESL;
return resX;
}
//*********************************************
void Read_VCC() //读取芯片供电VCC
{
char i=0;
resMCU=0;
for(i=0;i<8;i++)
{
resMCU+=ADCRead();
}
resMCU>>=3; //8次
VCC=(int)(1024L* *BGV/resMCU); //获取电池电压--测量是4.24,万用表测量是4.21 OK
}
void main()
{
Delay10ms();
port_init();
Timer0_Init(); //10毫秒@24.000MHz
Uart1_Init(); //9600bps@24.000MHz
EA=1;
ADC_init();
BGV=(int idata*)0xef; //读取内部1.19V电压
while(1)
{
if(Send_flag==1)
{
Send_flag=0;
Uart1SendData(33); //串口1发送33测试串口1用OK
Uart1SendData(*BGV >> 8); //串口1发送内部1.19V参考信号源的高字节OK
Uart1SendData(*BGV); //串口1发送内部1.19V参考信号源的低字节OK
adc_Volate(); //读取P1.0-ADC0通道电压 OK
Uart1SendData( ADD >> 8); //03
Uart1SendData( ADD); //DE 串口1接的数据是03DE=990 万用表测量为:0.99V BCCC=3020 3.02V
Read_VCC(); //读取芯片供电VCC--加入这个函数ADC0-P1.0的数据就不正常
//但是读电池电压的值正常,也就是这个功能会影响到其他ADC通道测量
Uart1SendData(VCC >> 8); //串口1发送芯片供电VCC的高字节 ok
Uart1SendData(VCC); //串口1发送芯片供电VCC的低字节 ok
}
}
}
AI8H1K08-QFN20芯片在使用ADC采集P10电压时,若同时调用ReadVCC()函数读取内部供电电压,导致P10电压显示异常,可能是由于以下原因造成的:
1. ADC参考电压受干扰
AI8H1K08的ADC采集依赖于参考电压(VREF+)。根据描述,芯片的6脚ADCVRef+与VCC(5脚)相连,意味着ADC的参考电压为系统供电电压(509V)。当调用ReadVCC()函数时,该函数可能通过内部电路对VCC进行测量,此过程可能引入噪声或瞬态干扰,影响ADC参考电压的稳定性,从而导致ADC采集结果异常。
2. ADC通道冲突或资源占用
ReadVCC()函数可能使用了同一ADC通道或共享资源,例如ADC0。如果该函数在执行过程中占用了ADC0通道,可能导致P10(ADC0)的采集被中断或覆盖,造成采集数据不准确。
3. 电源管理机制影响
芯片内部可能存在电源管理逻辑,在调用ReadVCC()时,系统可能临时调整供电状态或进入低功耗模式,进而影响ADC采集精度。尤其是在USB供电条件下,电压波动或电流变化可能加剧这种影响。
4. 软件逻辑问题
若ReadVCC()函数在程序中未正确初始化或配置ADC通道,可能导致ADC工作异常。例如,ADC寄存器设置错误、采样时间不足或未启用ADC模块等,均可能引起采集数据失真。
5. 硬件连接与滤波不足
尽管P10通过电位器接入,但若未在ADC输入端添加适当的滤波电路(如RC低通滤波),外部噪声或高频干扰可能在ADC采集时被放大,尤其在系统运行多个功能时更为明显。
建议排查步骤:
检查ReadVCC()函数是否使用了ADC0通道,避免与P10采集冲突;
确保ADC参考电压稳定,必要时外接独立参考电压源;
在ADC输入端增加滤波电路,提升信号质量;
优化ADC采样时序,确保各功能模块之间无资源冲突;
测试不同供电条件下的ADC性能,确认是否存在电源波动影响。
综上,该现象可能由ADC参考电压不稳定、通道冲突、电源管理逻辑或软件配置不当引起,需结合硬件设计与软件逻辑综合分析。
[本文内容由国芯人工智能辅助生成,仅供参考] YY2018 发表于 2025-7-14 00:01
芯片的5 6 7脚都有接,我现在就是可以测出来芯片的供电电压,用可调电源测试过,在给芯片供电电压是5.0 ...
分别测量10通道和15通道:
P3.2脚电压 u32 = 1.19*adc10/adc15; 测试通过的程序供参考
使用AiCube生成工程,USB转双串口工具测试
你使用的8H1K08无USB功能,可以移植一下
串口程序参考:
https://www.stcaimcu.com/thread-16321-1-1.html
DebugLab 发表于 2025-7-14 12:17
测试通过的程序供参考
AI8H1K08-36I-QFN20/TSSOP20/SOP16 是10位ADC,
应无下面 4096,是 1024
DebugLab 发表于 2025-7-14 12:17
测试通过的程序供参考
10位ADC,两个4096UL改成1024UL 梁工 发表于 2025-7-14 10:34
分别测量10通道和15通道:
P3.2脚电压 u32 = 1.19*adc10/adc15;
好的,我试一下,谢谢 DebugLab 发表于 2025-7-14 12:17
测试通过的程序供参考
谢谢您 DebugLab 发表于 2025-7-14 16:11
10位ADC,两个4096UL改成1024UL
好的,谢谢大神指点