找回密码
 立即注册
查看: 68|回复: 11

8H8K64U-TSSOP20, ADC15通道内部固定接1.19V信号源,反推VCC电池电压

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-05-12 18:18:09

3

主题

10

回帖

60

积分

等待验证会员

积分
60
发表于 4 天前 | 显示全部楼层 |阅读模式
大家好

8h8k64u   sop20  第15通道测量电池电压用例程得不到正确结果.

但是8h8k64tl可以使用例程。vref和 vdd直接连接。


请大佬们看下应该调整哪些代码。感谢
回复

使用道具 举报 送花

3

主题

1094

回帖

899

积分

等待验证会员

积分
899
发表于 4 天前 | 显示全部楼层
针对您描述的8H8K64U SOP20型号ADC测量异常问题,结合同类芯片开发经验,建议从以下五个技术层面进行排查:

一、硬件层验证
1. 引脚功能映射确认
需重点核对8H8K64U数据手册中SOP20封装的ADC通道物理映射。某些型号的ADC通道与GPIO编号存在非线性对应关系,例如:
通道15可能实际映射到P3.2引脚(需查阅最新版数据手册)
验证PCB布局是否将电池电压接入正确的物理引脚

2. 参考电压电路优化
虽然VREF与VDD直连,但建议:
增加10μF+100nF电容并联进行电源去耦
测量实际VDD电压波动范围(建议用示波器捕获ADC采样时刻的纹波)

二、ADC模块配置差异
1. 基准源选择寄存器
检查ADCON寄存器的VREFSEL字段配置:
```c
// 正确设置内部参考源模式
ADCON |= (0x01

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

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:434
  • 最近打卡:2025-05-12 09:01:08
已绑定手机

77

主题

4900

回帖

8564

积分

超级版主

DebugLab

积分
8564
发表于 4 天前 | 显示全部楼层
15通道测量的是内部BGV
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-05-12 18:18:09

3

主题

10

回帖

60

积分

等待验证会员

积分
60
发表于 3 天前 | 显示全部楼层
Debu*** 发表于 2025-5-9 23:24
15通道测量的是内部BGV

#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);
}




8h8k64u利用这个示例代码应该能反推   电池电压。但是得到  00

4k64tl   能到37   左右  可以用

是否是某个地址需要改动,看不太懂手册。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-05-12 18:18:09

3

主题

10

回帖

60

积分

等待验证会员

积分
60
发表于 3 天前 | 显示全部楼层
加的是  10u  0.1u
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:61
  • 最近打卡:2025-05-12 09:50:54

73

主题

5922

回帖

1万

积分

超级版主

积分
12207
发表于 3 天前 | 显示全部楼层
用户请先别修改程序, 直接下载"ADC.hex"测试,下载时选择主频11.0592MHZ. 测试时, 电脑的串口助手设置115200,8,n,1。

本程序演示查询方式读取15通道ADC并计算AVREF的电压值,通过串口1(P3.1)发送给上位机,波特率115200,8,n,1.
如果将AVREF与VCC连接,则计算出的电压也是单片机工作电压。

提供两个例程:
1、01A-读取15通道10位ADC计算AVREF电压-串口1(P3.1)返回结果, 适用于所有STC8系列带10位ADC的MCU。
2、01B-读取15通道12位ADC计算AVREF电压-串口1(P3.1)返回结果,适用于所有STC8H系列带12位ADC的MCU。

10位ADC测试结果截图:
测试结果截图.png


12位ADC测试结果截图:



01A-读取15通道10位ADC计算AVREF电压-串口1(P3.1)返回结果.rar (116.59 KB, 下载次数: 1)

01B-读取15通道12位ADC计算AVREF电压-串口1(P3.1)返回结果.rar (116.83 KB, 下载次数: 2)


测试结果截图.png
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-05-12 18:18:09

3

主题

10

回帖

60

积分

等待验证会员

积分
60
发表于 前天 12:43 | 显示全部楼层
梁*** 发表于 2025-5-10 11:12
用户请先别修改程序, 直接下载"ADC.hex"测试,下载时选择主频11.0592MHZ. 测试时, 电脑的串口助手设置11520 ...

直接用hex测试。
[12:38:15.331]接收←ADC15=1483,  AVREF=0.822V
                    
[12:38:16.175]接收←ADC15=1480,  AVREF=0.823V
                    
[12:38:17.003]接收←ADC15=1472,  AVREF=0.828V
                    
[12:38:17.831]接收←ADC15=1469,  AVREF=0.830V
                    
[12:38:18.675]接收←ADC15=1468,  AVREF=0.830V
                    
[12:38:19.503]接收←ADC15=1468,  AVREF=0.830V
                    
[12:38:20.347]接收←ADC15=1468,  AVREF=0.830V
                    
[12:38:21.175]接收←ADC15=1467,  AVREF=0.831V
                    
[12:38:22.018]接收←ADC15=1467,  AVREF=0.831V
                    
[12:38:22.846]接收←ADC15=1467,  AVREF=0.831V
                    
[12:38:23.690]接收←ADC15=1468,  AVREF=0.830V
                    
[12:38:24.518]接收←ADC15=1467,  AVREF=0.831V
                    
[12:38:25.346]接收←ADC15=1469,  AVREF=0.830V
                    
[12:38:26.190]接收←ADC15=1467,  AVREF=0.831V
                    
[12:38:27.018]接收←ADC15=1467,  AVREF=0.831V
                    
[12:38:27.862]接收←ADC15=1467,  AVREF=0.831V
                    
[12:38:28.690]接收←ADC15=1468,  AVREF=0.830V
                    
[12:38:29.533]接收←ADC15=1468,  AVREF=0.830V


万用表测量vdd及笔记本供电3.28      应该能排除硬件吧

麻烦再看下

点评

我的程序: while (1) { delay_ms(500); adc = ADC_convert(15); //Bandgap v = (4096 * 1.19f) / adc; //计算对应的VCC电压, 12位ADC printf("ADC15=%u, AVREF=%.3fV\n", adc, v); } 同时打印adc值和计算的VCC  详情 回复 发表于 前天 13:41
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:61
  • 最近打卡:2025-05-12 09:50:54

73

主题

5922

回帖

1万

积分

超级版主

积分
12207
发表于 前天 13:41 | 显示全部楼层
topof*** 发表于 2025-5-11 12:43
直接用hex测试。
[12:38:15.331]接收←ADC15=1483,  AVREF=0.822V
                    

我的程序:
while (1)
{
        delay_ms(500);
        adc = ADC_convert(15);        //Bandgap
        v = (4096 * 1.19f) / adc;        //计算对应的VCC电压, 12位ADC
        printf("ADC15=%u,  AVREF=%.3fV\n", adc, v);
}
同时打印adc值和计算的VCC电压值,你的测试返回:
[12:38:15.331]接收←ADC15=1483,  AVREF=0.822V
根据adc值计算AVREF = 4096*1.19/1483=3.287V,而你的返回0.822V,这个我实在想不通,计算是普通的计算,你的测试居然也出问题,没法理解。除非拿到你的样板测试,否则我没法想象原因。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:402
  • 最近打卡:2025-05-12 09:59:48

24

主题

310

回帖

2606

积分

荣誉版主

积分
2606
发表于 前天 14:33 | 显示全部楼层
12位的结果用了10位的推算公式?差了四倍
0.822×4=3.288

点评

ADC结果是12位的,并且ADC结果也是对的,就是电压不对,很奇怪的。  详情 回复 发表于 昨天 15:47
能体会到发现一个不理解的现象然后找原因然后要么解决掉问题要么被问题解决掉的那种快乐是我的幸运
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:61
  • 最近打卡:2025-05-12 09:50:54

73

主题

5922

回帖

1万

积分

超级版主

积分
12207
发表于 昨天 15:47 | 显示全部楼层
大*** 发表于 2025-5-11 14:33
12位的结果用了10位的推算公式?差了四倍
0.822×4=3.288

ADC结果是12位的,并且ADC结果也是对的,就是电压不对,很奇怪的。

点评

“地板”楼的代码里,本该用12位的4096反推的算式被注释掉了,用的10位的1024反推的,所以结果正好变成了四分之一 3.288变成了0.822  详情 回复 发表于 昨天 18:04
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-13 00:01 , Processed in 0.145984 second(s), 119 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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