用STC8H1K08测量电池电压,数据无变化. | 已搞定
我用用STC8H1K08测量电池电压,输入电压发生变化,但读取的数据无变化.:1.主芯片为 STC8H1K08 TSSOP 20封装
2.P1.1为 VBAT_ADC输入口
3.P3.1为RXD,P3.0为RXD
下面是代码:
voidADCInit(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| B4B3B2B1B0 |
//--|--------|-------|---------|-------------|--------------------|
//--| ADCTIM | FEA8H | CSSETUP | CSHOLD | SMPDUTY |
//----------------------------------------------------------------|
ADCTIM = 0x3D;// 0b001 1 1101; //30设置 ADC 内部时序
Disable_XFR();
//SPEED:设置 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 | B3B2B1B0 |
//-|-----------|------|-----------|-----------|----------|-----------|----------------|
//-| ADC_CONTR |BCH | ADC_POWER | ADC_START | ADC_FLAG | ADC_EPWMT |ADC_CHS|
//-|-----------------------------------------------------------------------------------
//- 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 = 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 ? temp : ADCBatValue;
for(i=0;i<(ADCValueTimes-1);i++)
{
ADCBatValue += ADCBatValue;
}
// ADCBatValue -=temp;
LEDBatValue = ADCBatValue/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;
}
}
对于使用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读取数据无变化的问题。
[本文内容由国芯人工智能辅助生成,仅供参考] GPIO高阻输入配置看着没有呢
ADC参考开天斧例程:08-16路ADC轮询-每路16次ADC转换取中间8次求平均值-串口1返回结果
https://www.stcaimcu.com/data/download/DemoCode/STC8H8K64U-45MHz-LQFP64-DIP64-DEMO-CODE.zip
ercircle 发表于 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|开漏模式既可读外部状态也可对外输出(高电平或低电 |
| | |平)。如要正确读外部状态或需要对外输出高电平,需外加 |
| | |上拉电阻,否则读不到外部状态,也对外输不出高电平。 |
|------|------|-----------------------------------------------------|
//------------------------------------*/
migao 发表于 2025-6-16 17:46
请问下,GPIO高阻输入配置看着没有呢----如何配置合适?硬件?软件?
我是P1.1 ADC输入,软件如下配置:
只配置要用的引脚即可,对比下上面发的例程,再检查下别的配置~
migao 发表于 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就有数据如果不屏蔽,打印的数据就出现.
请问是啥原因造成?如何解决? migao 发表于 2025-6-16 18:13
而且我发现一个奇怪现象,
DBG_PRINTF("BAT: %d\n",ADCValue);和
DBG_PRINTF("DAT: %d\n",ADCValue);
格式与类型不符?ADCValue类型是int吗
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=6864&highlight=printf&page=1&extra=#pid60079 ercircle 发表于 2025-6-16 21:07
格式与类型不符?ADCValue类型是int吗
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=6864&hig ...
是下面这样定义的:
unsigned int ADCValue,ADCDatValue,ADCBatValue,DCDatValue,LEDBatValue,LEDBatValueTemp,LEDBatDisCharge;
migao 发表于 2025-6-17 10:10
是下面这样定义的:
unsigned int ADCValue,ADCDatValue,ADCBatValue,DCDatValue,LEDBatValue,LEDBa ...
看下上面帖子,也可以看看keil文档
ercircle 发表于 2025-6-17 10:26
看下上面帖子,也可以看看keil文档
按照上面来,没有解决问题.
页:
[1]
2