乐此不疲 发表于 2025-4-1 12:23:21

请教!ADC采样端口没有输入时仍然有电压值是什么原因?【结贴!程序有误!】

问题的出现:我的这个时钟试运行了4个多月了,ADC0采样的电池电压监测功能一直运行正常,
昨天修改了一处时钟的非ADC相关的驱动代码,
重新烧录程序后就出现了已经配置为高阻输入用于ADC0采样的P1.0端口始终输出高电平的状况(输出3V比正常端口高电平3.2V略低),
我百思不得其解,接下来怎么弄就不会了请高手指点!!


1.所用单片机为STC8H8K64U(20引脚)。
2.ADC0通道、P1.0引脚。
3.单片机供电电压VDD=3.3V。
4.P1.0端口配置为P1M0 = 0x00; P1M1 = 0x01;      //P1.0为ADC采样口配置为高阻输入
5.采样输入电路如图:


6.测量结果及故障现象:VCC在5V至3.2V时,无论mos开关导通状态还是关闭状态,模拟输入电压V_ADC0都是3V。
7.进一步检查发现拆除R03、R04后V_ADC0的输出电压为3V,并且这个V_ADC0输出电压可以点亮串联1k电阻的LED发光管。
8.ADC代码如下:
#define BGV (*(unsigned int volatile xdata *)0xfde7)//在xdata地址0xfde7中读取内部 1.19V 参考信号电压

//----------------------------------------------------------------------------------------------------------
void ADC_Init()
{
    ADCCFG = 0x2f;      //所有通道的转换结果数据为右侧对齐模式、SYSclk/2/16(转换速度最低)
    ADCTIM = 0x3f;//设置通道选择时间、保持时间、采样时间
    ADCEXCFG = 0x07;//转换16次并取平均值(STC8H4K、STC8H8K系列芯片支持扩展寄存器设置硬件自动取平均值功能)
    NOP5();
}
//-----------------------------------------------------------------------------------------------------------
u16 ADC_Read(u8 n)
{
    ADC_RES = 0;
    ADC_RESL = 0;
    ADC_CONTR = 0x80 | 0x40 | n;//ACD模块上电0x80、使能ADC转换0x40、给定ADC通道n
    delay_ms(2);

    while((ADC_CONTR & 0x20) == 0);      //等待ADC转换标志ADC_FLAG=1

    ADC_CONTR &= ~0x20;               //清除标志ADC_FLAG
    return (((u16)ADC_RES << 8) | ADC_RESL);
}

//-----ADC数据输出函数--------------------------------------------------------------------------------------
u16 ADC_out(u8 adc_x)
{
    u16 adc_data0 = 0;
    u32 adc_data1 = 0;
//读取15通道的ADC值
    ADC_Read(15);                              //先读一次15通道并丢弃结果
    adc_data0 = ADC_Read(15);      //获得15通道16次平均值(硬件平均值运算)
//读取adc_x通道的ADC值
    ADC_Read(adc_x);                        //先读一次目标通道并丢弃结果
    adc_data1 = ADC_Read(adc_x);      //获得硬件16次平均值
    adc_data1 = BGV * adc_data1 / adc_data0; //对比ADC15通道采样值利用STC单片机内部基准电压值换算目标通道电压值(数据放大1000倍)

    return (u16)adc_data1;
}






国芯人工智能 发表于 2025-4-1 12:38:01

针对您描述的ADC采样端口P1.0在没有输入时仍然有电压值的问题,以下是一些可能的原因及相应的排查建议:

1. 代码修改引入的异常
问题分析:您在修改了非ADC相关的驱动代码后,出现了P1.0端口始终输出高电平的现象。这可能是由于代码修改意外影响了ADC相关寄存器的配置,或者引入了某些异常状态。
排查建议:
检查修改的代码是否间接影响了ADC相关寄存器的配置,尤其是与P1.0端口相关的寄存器。
确保ADC初始化代码(如ADCCFG和ADCTIM)在程序启动时正确执行,且未被后续代码覆盖或修改。
使用调试工具(如逻辑分析仪或调试器)检查P1.0端口的状态,确认其是否被意外配置为输出模式。

2. 硬件电路问题
问题分析:您提到拆除R03、R04后,VADC0的输出电压仍为3V,并且可以点亮LED。这表明P1.0端口可能存在内部上拉或外部电路异常。
排查建议:
检查P1.0端口的外部电路,确认是否存在短路、漏电或其他异常情况。
确认P1.0端口的配置是否正确(P1M0 = 0x00; P1M1 = 0x01;),确保其被配置为高阻输入模式。
检查单片机的供电电压(VDD=3.3V)是否稳定,是否存在电源噪声或波动。

3. ADC模块内部问题
问题分析:如果ADC模块内部存在故障,可能会导致采样端口出现异常电压。
排查建议:
尝试切换到其他ADC通道(如ADC1),检查是否也存在类似问题。
检查ADC参考电压(如内部1.19V参考信号)是否正常,确保ADC模块的参考电压源稳定。
如果可能,使用外部参考电压源进行测试,排除内部参考电压异常的可能性。

4. 程序逻辑问题
问题分析:程序逻辑中可能存在某些条件或状态导致P1.0端口被意外拉高。
排查建议:
检查程序逻辑,确认是否存在某些条件分支或中断服务程序意外修改了P1.0端口的状态。
在程序中添加调试信息,记录P1.0端口的状态变化,帮助定位问题。

5. 单片机硬件故障
问题分析:如果以上排查均未发现问题,可能是单片机硬件本身存在故障。
排查建议:
尝试更换同型号的单片机,确认问题是否依然存在。
如果更换单片机后问题消失,则可能是原单片机硬件损坏,需要更换。

总结
建议您按照以下步骤逐步排查:
1. 检查代码修改是否影响了ADC相关配置。
2. 确认P1.0端口的外部电路和配置是否正确。
3. 测试其他ADC通道,排除ADC模块内部故障。
4. 检查程序逻辑,确保P1.0端口状态未被意外修改。
5. 如果以上步骤均未解决问题,考虑更换单片机以排除硬件故障。

希望以上建议能帮助您定位并解决问题。如果问题仍然存在,建议进一步提供详细的电路图和代码片段,以便更深入地分析。

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

DebugLab 发表于 2025-4-1 14:14:16

检查单片机IO是否损坏,换一个单片机试试
其他功能是否正常,检查是不是哪里卡住,不能执行设置IO口为高阻的指令,或意外被设置为推挽
主时钟是否接近极限频率,如是,要正确设置IAP_TPS寄存器,如仍有异常,尝试设置IRCDB寄存器为16

梁工 发表于 2025-4-1 14:23:55

ADC输入为高阻,悬空时可以读到任意值,因为你没有给定一个电压,所以输入端时浮空的,电压会不确定。

乐此不疲 发表于 2025-4-1 18:13:26

梁工 发表于 2025-4-1 14:23
ADC输入为高阻,悬空时可以读到任意值,因为你没有给定一个电压,所以输入端时浮空的,电压会不确定。 ...
非常感谢各位对我的问题的回应,也非常感谢一楼层主对我的问题的详细回复,其实我最初对全部代码的修改仅仅更改了一个端口状态设定:
sbit ADC0_Power = P3 ^ 1;

ADC0_Power = 1;//为采样分压电阻供电
NOP10();
date = ADC_out(0); //获取标志后读取ADC0通道采样值并保存在公共变量中

NOP10();
ADC0_Power = 0;//关闭采样分压电阻供电

我仅仅是修改了最后一句的赋值,修改之前为ADC0_Power = 1;修改之后为ADC0_Power = 0;
设计硬件开关的初心就是为了省电,每次采集数据时先给采样电阻通电,采集完毕好给采样电阻断电,这个修改应该与P1.0通道无关。另外我很多测试都是在锂电池供电状态下进行的应该与“电源干扰”无关。

刚才我再次修改代码,失能了所有与ADC相关的操作,失能了所有主循环中的操作,在P1.0为准双向模式或高阻模式的两种状态下主循环中分别仅执行一句P10=0;代码,结果都一样,就是P1.0始终为3V,难到我起初修改代码的那次烧录操作就损坏了P1.0口?而单片机除了P1.0口有问题外的其他控制一切正常。不可思议!


我准备明天换掉芯片在试试吧。


乐此不疲 发表于 2025-4-1 18:27:20

梁工 发表于 2025-4-1 14:23
ADC输入为高阻,悬空时可以读到任意值,因为你没有给定一个电压,所以输入端时浮空的,电压会不确定。 ...
实际应用的步骤是P3.1=1;-->mos开关导通-->启动ADC0-->读取数据-->P3.1=0;-->mos开关关断,在mos开关关断后就没有采集数据操作了也就不理会P1.0的状态了,出现问题后发现电池图标始终显示满电状态,此后无论mos开关是否导通P1.0口电压保存3V不变了其远远超过了实际满电电压2.1V(锂电池满电4.2V,1/2分压采样)。

梁工 发表于 2025-4-1 18:55:00

乐此不疲 发表于 2025-4-1 18:27
实际应用的步骤是P3.1=1;-->mos开关导通-->启动ADC0-->读取数据-->P3.1=0;-->mos开关关断,在mos开关关断 ...

那你实际测量下MOSFET的D极电压和P1.0电压多少V?
页: [1]
查看完整版本: 请教!ADC采样端口没有输入时仍然有电压值是什么原因?【结贴!程序有误!】