YY2018 发表于 2025-7-14 00:01:59

神农鼎 发表于 2025-7-13 23:00
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通道电压




YY2018 发表于 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/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

                }
       
        }

}





国芯人工智能 发表于 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参考电压不稳定、通道冲突、电源管理逻辑或软件配置不当引起,需结合硬件设计与软件逻辑综合分析。

[本文内容由国芯人工智能辅助生成,仅供参考]

梁工 发表于 2025-7-14 10:34:53

YY2018 发表于 2025-7-14 00:01
芯片的5 6 7脚都有接,我现在就是可以测出来芯片的供电电压,用可调电源测试过,在给芯片供电电压是5.0 ...

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

DebugLab 发表于 2025-7-14 12:17:12

测试通过的程序供参考


使用AiCube生成工程,USB转双串口工具测试

你使用的8H1K08无USB功能,可以移植一下
串口程序参考:
https://www.stcaimcu.com/thread-16321-1-1.html


神农鼎 发表于 2025-7-14 16:03:09

DebugLab 发表于 2025-7-14 12:17
测试通过的程序供参考





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


DebugLab 发表于 2025-7-14 16:11:09

DebugLab 发表于 2025-7-14 12:17
测试通过的程序供参考




10位ADC,两个4096UL改成1024UL

YY2018 发表于 2025-7-14 18:33:49

梁工 发表于 2025-7-14 10:34
分别测量10通道和15通道:
P3.2脚电压 u32 = 1.19*adc10/adc15;

好的,我试一下,谢谢

YY2018 发表于 2025-7-14 18:34:51

DebugLab 发表于 2025-7-14 12:17
测试通过的程序供参考




谢谢您

YY2018 发表于 2025-7-14 18:35:09

DebugLab 发表于 2025-7-14 16:11
10位ADC,两个4096UL改成1024UL

好的,谢谢大神指点
页: 1 [2] 3
查看完整版本: 芯片AI8H1K08通过内部1.19V测量芯片电池电压正确但是测量P32引脚ADC10电压一直不正常