找回密码
 立即注册
查看: 48|回复: 10

用STC8H1K08测量电池电压,数据无变化.

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-06-17 09:39:01
已绑定手机

2

主题

5

回帖

46

积分

新手上路

积分
46
发表于 前天 15:35 | 显示全部楼层 |阅读模式
    我用用STC8H1K08测量电池电压,输入电压发生变化,但读取的数据无变化.:
1.主芯片为 STC8H1K08 TSSOP 20封装
2.P1.1为 VBAT_ADC输入口
3.P3.1为RXD,P3.0为RXD
    下面是代码:

void  ADCInit(void)
{
        Enable_XFR();
//端口数字信号输入使能控制寄存器 PxIE
//PxIE 0:禁止数字信号输入。若 I/O被当作比较器输入口、ADC 输入口或者触摸按键输入口等模拟口时,
//                进入时钟停振模式前,必须设置为 0,否则会有额外的耗电。
//PxIE 1:使能数字信号输入。若 I/O被当作数字口时,必须设置为 1,否 MCU无法读取外部端口的电平。
//        P1IE &= 0xFD;        //1: 使能数字信号输入,1.1作为ADC输入,置0
        P1IE |= 0xFF;        //1: 使能数字信号输入       
        P3IE |= 0x03;        //,3.1/3.0作为RX/TX输入输出口
       

        P1INTE |= 0x02;        //1:使能 Pn.x 口中断功能
        P1INTF &= 0xFD;        //0:中断请求标志位需软件清 0

        P3INTE |= 0x03;        //1:使能 Pn.x 口中断功能
        P3INTF &= 0xFC;        //中断请求标志位需软件清 0


//--------------------------------------------------------
//--ADC时序控制寄存器
//----------------------------------------------------------------
//--|  符号  |  地址 |    B7   |  B6  |  B5  | B4  B3  B2  B1  B0 |
//--|--------|-------|---------|-------------|--------------------|
//--| ADCTIM | FEA8H | CSSETUP | CSHOLD[1:0] |    SMPDUTY[4:0]    |
//----------------------------------------------------------------|
        ADCTIM = 0x3D;// 0b001 1 1101;        //30  设置 ADC 内部时序

        Disable_XFR();

//SPEED[3:0]:设置 ADC 工作时钟频率{FADC=SYSclk/2/(SPEED+1)}        
        ADCCFG = 0x0F;        //SYSclk/2/16
//RESFMT:ADC 转换结果格式控制位
//1:转换结果右对齐。ADC_RES 保存结果的高 2位,ADC_RESL 保存结果的低 8 位
        ADCCFG |= 0x20;
       
//ADC控制寄存器
//-------------------------------------------------------------------------------------
//-|    符号   | 地址 |      B7   |     B6    |     B5   |     B4    | B3  B2  B1  B0 |
//-|-----------|------|-----------|-----------|----------|-----------|----------------|
//-| ADC_CONTR |  BCH | ADC_POWER | ADC_START | ADC_FLAG | ADC_EPWMT |  ADC_CHS[3:0]  |
//-|-----------------------------------------------------------------------------------
//- ADC_FLAG:ADC转换完成中断请求标志。需要软件清零。        
        ADC_CONTR &= 0xDF;        //ADC_FLAG:ADC转换完成中断请求标志。需要软件清零。


        ADC_CONTR |= 0x01;                //0001,开启P1.1 VBAT_ACD转换口
        ADC_CONTR &= 0xF1;
       
//ADC_POWER:ADC 电源控制位
//0:关闭 ADC 电源
//1:打开 ADC 电源。
//建议进入空闲模式和掉电模式前将 ADC 电源关闭,以降低功耗
        OpenPowerADC();        //1:打开 ADC 电源。
//ADC_START:ADC 转换启动控制位。写入 1 后开始 ADC 转换,转换完成后硬件自动将此位清零。
//0:无影响。即使 ADC 已经开始转换工作,写 0也不会停止 A/D转换。
//1:开始 ADC 转换,转换完成后硬件自动将此位清零。

//        OpenADCStart();

//EADC:A/D转换中断允许位。
//0:禁止 A/D转换中断
//1:允许 A/D转换中断
        IE |= 0x20;        //1:允许 A/D转换中断
}



void ADCChange(void)
{
        if(AllFlag.Flag.ADC_Change_Stop_Flag ==0)
        {
                ADCValue = 0;
                if((ADC_CONTR & 0x0F) == 0x0F)
                {
                        DBG_PRINTF(" -----VBAT_ACD bigan: ");

                        ADC_CONTR |= 0x01;                //0001,开启P1.1 VBAT_ACD转换口
                        ADC_CONTR &= 0xF1;
        }
        else //if((ADC_CONTR & 0x0F) == 0x0F)
        {
                        DBG_PRINTF("+++++ VBAT_ACD OK: ");
                        ADC_CONTR |= 0x0F;
                //        ADC_CONTR &=0xFC;
        }
                AllFlag.Flag.ADC_Change_Stop_Flag = 1;
                ADCChargeTime = 0;
                ADC_CONTR &= 0xDF;        //ADC_FLAG:ADC转换完成中断请求标志  需要软件清零
                OpenADCStart();
        }
        else if(ADCChargeTime > TimeParameter50ms)   // 50ms
        {
                ADCChargeTime = 0;
                ADC_CONTR &= 0xDF;
                OpenADCStart();
        }
}


void ADCChargeFunction(void)
{
        unsigned char i;
//        unsigned int temp=1025;
        ADCChange();
        if(AllFlag.Flag.ADC_Change_Finish_Flag)
        {//0xEFF0 = 0x0004A3F7
        //        if((ADC_CONTR & 0x0F) == 0x0C)
                if((ADC_CONTR & 0x0F) == 0x0F)
                {//0x0C Bat VBAT
                        ADCBatValue[ADCValueTimes++] = ADCValue;
                //        ADCBatValue = ADCValue;
                //        LEDBatValue = ADCBatValue;
                        DBG_PRINTF("BAT: %d\n",ADCValue);
                }
                else if((ADC_CONTR & 0x0F) == 0x01)
                {//0x0E Dat DC_DAT
                        DCDatValue = ADCValue;
                  DBG_PRINTF("DAT: %d\n",ADCValue);
                        if(DCDatValue > DC_DAT_Value)
                        {
                                AllFlag.Flag.DC_DAT_Value_Flag = 1;
                                AllFlag.Flag.INT3_ISR_Flag = 1;
                        }
                        else
                        {
                                AllFlag.Flag.DC_DAT_Value_Flag = 0;
                                AllFlag.Flag.INT3_ISR_Flag = 0;
                        //        CloseAllLED();
                        }
                }
                if(ADCValueTimes >= sizeof(ADCBatValue)/sizeof(unsigned int))
                {
                //        for(i=0;i<ADCValueTimes;i++)
                //                temp = temp <= ADCBatValue[i] ? temp : ADCBatValue[i];
                        for(i=0;i<(ADCValueTimes-1);i++)
                        {
                                ADCBatValue[0] += ADCBatValue[i+1];
                        }
                //        ADCBatValue[0] -=temp;
                        LEDBatValue = ADCBatValue[0]/ADCValueTimes;
                printf("LEDBatValue :%d \n",LEDBatValue);
                       

                        ADCValueTimes = 0;
                }
                AllFlag.Flag.ADC_Change_Finish_Flag = 0;
//                  DBG_PRINTF("00000AllFlag.Flag.ADC_Change_Finish_Flag =: %d\n",AllFlag.Flag.ADC_Change_Finish_Flag);
                AllFlag.Flag.ADC_Change_Stop_Flag = 0;
        }
}



米高
回复

使用道具 举报 送花

3

主题

698

回帖

107

积分

等待验证会员

积分
107
发表于 前天 15:38 | 显示全部楼层
对于使用STC8H1K08测量电池电压,若数据无变化但输入电压发生变化,可能是因为输入电压的范围不足导致ADC无法准确测量。以下是一些可能的解决方案:

1. 检查ADC的输入电压范围:  
   STC8H1K08的ADC测量精度取决于其输入电压范围。建议确保输入电压的范围足够大,以覆盖电池电压的范围(通常在0.4V至3.3V)。如果输入电压范围过小,可能需要调整ADC的配置,例如调整内部的电阻或增加适当的安全保护电路。

2. 检查ADC的输入端口配置:  
   检查PxIE和P3IE的设置,确保它们正确配置为使能数字信号输入。PxIE设为1表示使能,P3IE设为1表示使能RX/TX端口。

3. 检查ADC内部电路:  
   确保ADC内部电路的电阻匹配和电源稳定。电源可能不稳定或电阻不匹配可能导致输入信号无法准确捕获。

4. 检查ADC的时序控制寄存器:  
   确保ADC的时序控制寄存器PxIE和P3IE正确设置为1,以确保ADC能够正确捕获电压信号。

5. 检查ADC的中断功能:  
   检查PxINTE和P3INTE的设置,确保中断功能正确工作。中断请求标志位需软件清0。

6. 调试ADC的内部电路:  
   如果以上步骤均未解决问题,可能需要调试ADC内部电路,检查引脚连接是否正确,以及任何潜在的损坏或短路。

7. 使用电源保护:  
   如果电源不稳定,使用电源保护电路(如DC保护、PMOS或FET)可能有助于提高ADC的稳定性。

8. 检查外部电源的稳定性:  
   若外部电源不稳定,可能导致ADC无法正常工作,进而影响电压测量结果。

通过以上步骤,您可以逐步排查并解决输入电压发生变化但ADC读取数据无变化的问题。

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

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:209
  • 最近打卡:2025-06-17 08:51:39
已绑定手机

68

主题

1926

回帖

4312

积分

荣誉版主

无情的代码机器

积分
4312
发表于 前天 16:47 | 显示全部楼层
GPIO高阻输入配置看着没有呢

ADC参考开天斧例程:08-16路ADC轮询-每路16次ADC转换取中间8次求平均值-串口1返回结果
https://www.stcaimcu.com/data/do ... DIP64-DEMO-CODE.zip
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-06-17 09:39:01
已绑定手机

2

主题

5

回帖

46

积分

新手上路

积分
46
发表于 前天 17:46 | 显示全部楼层
erci*** 发表于 2025-6-16 16:47
GPIO高阻输入配置看着没有呢

ADC参考开天斧例程:08-16路ADC轮询-每路16次ADC转换取中间8次求平均值-串口1 ...

请问下,GPIO高阻输入配置看着没有呢----如何配置合适?硬件?软件?
我是P1.1 ADC输入,软件如下配置:

        P1M1 = 0x00;
        P1M0 = 0x00;
        
        P1M1 |= 0xf3;
          P1PU &= 0xf1;        //0:禁止端口内部的 4.1K上拉电阻

借鉴:

/*--------------------------------------
|------|------|-----------------------------------------------------|
| PnM1 | PnM0 |   I/O口工作模式                                     |
|------|------|-----------------------------------------------------|
|      |      |准双向口(传统8051端口模式,弱上拉)                 |
|   0  |   0  |灌电流可达20mA,拉电流为270~150μA(存在制造误差)   |
|------|------|-----------------------------------------------------|
|   0  |   1  |推挽输出(强上拉输出,可达20mA,要加限流电阻)       |
|------|------|-----------------------------------------------------|
|   1  |   0  |高阻输入(电流既不能流入也不能流出)                 |
|------|------|-----------------------------------------------------|
|      |      |开漏输出(Open-Drain),内部上拉电阻断开             |
|   1  |   1  |开漏模式既可读外部状态也可对外输出(高电平或低电     |
|      |      |平)。如要正确读外部状态或需要对外输出高电平,需外加 |
|      |      |上拉电阻,否则读不到外部状态,也对外输不出高电平。   |
|------|------|-----------------------------------------------------|
//------------------------------------*/

        

点评

只配置要用的引脚即可,对比下上面发的例程,再检查下别的配置~ [attachimg]104736[/attachimg]  详情 回复 发表于 前天 18:10
米高
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:209
  • 最近打卡:2025-06-17 08:51:39
已绑定手机

68

主题

1926

回帖

4312

积分

荣誉版主

无情的代码机器

积分
4312
发表于 前天 18:10 | 显示全部楼层
mig*** 发表于 2025-6-16 17:46
请问下,GPIO高阻输入配置看着没有呢----如何配置合适?硬件?软件?
我是P1.1 ADC输入,软件如下配置:


只配置要用的引脚即可,对比下上面发的例程,再检查下别的配置~
截图202506161809265918.jpg
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-06-17 09:39:01
已绑定手机

2

主题

5

回帖

46

积分

新手上路

积分
46
发表于 前天 18:13 | 显示全部楼层
mig*** 发表于 2025-6-16 17:46
请问下,GPIO高阻输入配置看着没有呢----如何配置合适?硬件?软件?
我是P1.1 ADC输入,软件如下配置:

而且我发现一个奇怪现象,
DBG_PRINTF("BAT: %d\n",ADCValue);和
DBG_PRINTF("DAT: %d\n",ADCValue);
这两句屏蔽任何一个或两个,

DBG_PRINTF("LEDBatValue :%d \n",LEDBatValue);
LEDBatValue打印的数据LEDBatValue或BAT
DAT就为0,同时,没屏蔽的BAT或者DAT就有数据如果不屏蔽,打印的数据就出现.
请问是啥原因造成?如何解决?

点评

格式与类型不符?ADCValue类型是int吗 https://www.stcaimcu.com/forum.php?mod=viewthread&tid=6864&highlight=printf&page=1&extra=#pid60079  详情 回复 发表于 前天 21:07
米高
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:209
  • 最近打卡:2025-06-17 08:51:39
已绑定手机

68

主题

1926

回帖

4312

积分

荣誉版主

无情的代码机器

积分
4312
发表于 前天 21:07 | 显示全部楼层
mig*** 发表于 2025-6-16 18:13
而且我发现一个奇怪现象,
DBG_PRINTF("BAT: %d\n",ADCValue);和
DBG_PRINTF("DAT: %d\n",ADCValue);

格式与类型不符?ADCValue类型是int吗
https://www.stcaimcu.com/forum.p ... amp;extra=#pid60079
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-06-17 09:39:01
已绑定手机

2

主题

5

回帖

46

积分

新手上路

积分
46
发表于 昨天 10:10 | 显示全部楼层
erci*** 发表于 2025-6-16 21:07
格式与类型不符?ADCValue类型是int吗
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=6864&hig ...

是下面这样定义的:
unsigned int ADCValue,ADCDatValue[5],ADCBatValue[5],DCDatValue,LEDBatValue,LEDBatValueTemp,LEDBatDisCharge;

点评

看下上面帖子,也可以看看keil文档 [attachimg]104792[/attachimg]  详情 回复 发表于 昨天 10:26
米高
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:209
  • 最近打卡:2025-06-17 08:51:39
已绑定手机

68

主题

1926

回帖

4312

积分

荣誉版主

无情的代码机器

积分
4312
发表于 昨天 10:26 | 显示全部楼层
mig*** 发表于 2025-6-17 10:10
是下面这样定义的:
unsigned int ADCValue,ADCDatValue[5],ADCBatValue[5],DCDatValue,LEDBatValue,LEDBa ...

看下上面帖子,也可以看看keil文档

截图202506171026349139.jpg
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-06-17 09:39:01
已绑定手机

2

主题

5

回帖

46

积分

新手上路

积分
46
发表于 昨天 13:49 | 显示全部楼层
erci*** 发表于 2025-6-17 10:26
看下上面帖子,也可以看看keil文档

按照上面来,没有解决问题.

点评

此处应该上传完整工程,不然大家帮不到你啊~  详情 回复 发表于 昨天 13:57
米高
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-6-18 00:25 , Processed in 0.146207 second(s), 108 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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