找回密码
 立即注册
楼主: YY2018

芯片AI8H1K08通过内部1.19V测量芯片电池电压正确但是测量P32引脚ADC10电压一直不正常

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:9
  • 最近打卡:2025-07-29 19:51:44
已绑定手机

3

主题

16

回帖

87

积分

注册会员

积分
87
发表于 2025-7-14 00:01:59 | 显示全部楼层
神农鼎 发表于 2025-7-13 23:00
8H1K08-36I-TSSOP20的ADC是10位,
0 ~ 1023

40944b0539b30686b8f63020da69626.png   
芯片的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通道电压




点评

分别测量10通道和15通道: P3.2脚电压 u32 = 1.19*adc10/adc15;  详情 回复 发表于 2025-7-14 10:34
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:9
  • 最近打卡:2025-07-29 19:51:44
已绑定手机

3

主题

16

回帖

87

积分

注册会员

积分
87
发表于 2025-7-14 08:59:34 | 显示全部楼层

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/16  OF
    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;

        return  result;
}
//*********************************************
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

                }
       
        }

}





回复 支持 反对

使用道具 举报 送花

3

主题

247

回帖

-795

积分

等待验证会员

积分
-795
发表于 2025-7-14 09:08:00 | 显示全部楼层
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参考电压不稳定、通道冲突、电源管理逻辑或软件配置不当引起,需结合硬件设计与软件逻辑综合分析。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:137
  • 最近打卡:2025-07-31 12:11:20

76

主题

6281

回帖

1万

积分

超级版主

积分
13347
发表于 2025-7-14 10:34:53 | 显示全部楼层
YY2*** 发表于 2025-7-14 00:01
芯片的5 6 7脚都有接,我现在就是可以测出来芯片的供电电压,用可调电源测试过,在给芯片供电电压是5.0 ...

分别测量10通道和15通道:
P3.2脚电压 u32 = 1.19*adc10/adc15;
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:513
  • 最近打卡:2025-07-31 08:58:47
已绑定手机

87

主题

5532

回帖

1万

积分

超级版主

DebugLab

积分
10123
发表于 2025-7-14 12:17:12 | 显示全部楼层
测试通过的程序供参考
截图202507141224441310.jpg
截图202507141240282838.jpg
使用AiCube生成工程,USB转双串口工具测试
截图202507141220581681.jpg
你使用的8H1K08无USB功能,可以移植一下
串口程序参考:
https://www.stcaimcu.com/thread-16321-1-1.html
CDC发送VREF.zip (48.39 KB, 下载次数: 2)

点评

10位ADC,两个4096UL改成1024UL  详情 回复 发表于 2025-7-14 16:11
AI8H1K08-36I-QFN20/TSSOP20/SOP16 是10位ADC, 应无下面 4096,是 1024 [attachimg]108452[/attachimg]  详情 回复 发表于 2025-7-14 16:03
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:144
  • 最近打卡:2025-07-31 10:37:58

760

主题

1万

回帖

1万

积分

管理员

积分
18139
发表于 2025-7-14 16:03:09 | 显示全部楼层
Debu*** 发表于 2025-7-14 12:17
测试通过的程序供参考


AI8H1K08-36I-QFN20/TSSOP20/SOP16 是10位ADC,
应无下面 4096,是 1024

截图202507141602111679.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:513
  • 最近打卡:2025-07-31 08:58:47
已绑定手机

87

主题

5532

回帖

1万

积分

超级版主

DebugLab

积分
10123
发表于 2025-7-14 16:11:09 | 显示全部楼层
Debu*** 发表于 2025-7-14 12:17
测试通过的程序供参考

10位ADC,两个4096UL改成1024UL
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:9
  • 最近打卡:2025-07-29 19:51:44
已绑定手机

3

主题

16

回帖

87

积分

注册会员

积分
87
发表于 2025-7-14 18:33:49 | 显示全部楼层
梁*** 发表于 2025-7-14 10:34
分别测量10通道和15通道:
P3.2脚电压 u32 = 1.19*adc10/adc15;

好的,我试一下,谢谢
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:9
  • 最近打卡:2025-07-29 19:51:44
已绑定手机

3

主题

16

回帖

87

积分

注册会员

积分
87
发表于 2025-7-14 18:34:51 | 显示全部楼层
Debu*** 发表于 2025-7-14 12:17
测试通过的程序供参考

谢谢您

点评

注意: 参与运算的所有数据,数据类型相同 等号两端数据类型相同 [attachimg]108483[/attachimg]  详情 回复 发表于 2025-7-14 19:39
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:9
  • 最近打卡:2025-07-29 19:51:44
已绑定手机

3

主题

16

回帖

87

积分

注册会员

积分
87
发表于 2025-7-14 18:35:09 | 显示全部楼层
Debu*** 发表于 2025-7-14 16:11
10位ADC,两个4096UL改成1024UL

好的,谢谢大神指点
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-8-1 01:54 , Processed in 0.138103 second(s), 97 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表