找回密码
 立即注册
查看: 156|回复: 6

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

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:441
  • 最近打卡:2025-05-02 09:05:39

45

主题

176

回帖

1735

积分

金牌会员

积分
1735
发表于 2025-4-1 12:23:21 | 显示全部楼层 |阅读模式
问题的出现:我的这个时钟试运行了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.采样输入电路如图:
666.jpg

6.测量结果及故障现象:VCC在5V至3.2V时,无论mos开关导通状态还是关闭状态,模拟输入电压V_ADC0都是3V。
7.进一步检查发现拆除R03、R04后V_ADC0的输出电压为3V,并且这个V_ADC0输出电压可以点亮串联1k电阻的LED发光管。
8.ADC代码如下:
  1. #define BGV (*(unsigned int volatile xdata *)0xfde7)//在xdata地址0xfde7中读取内部 1.19V 参考信号电压
  2. //----------------------------------------------------------------------------------------------------------
  3. void ADC_Init()
  4. {
  5.     ADCCFG = 0x2f;        //所有通道的转换结果数据为右侧对齐模式、SYSclk/2/16(转换速度最低)
  6.     ADCTIM = 0x3f;  //设置通道选择时间、保持时间、采样时间
  7.     ADCEXCFG = 0x07;//转换16次并取平均值(STC8H4K、STC8H8K系列芯片支持扩展寄存器设置硬件自动取平均值功能)
  8.     NOP5();
  9. }
  10. //-----------------------------------------------------------------------------------------------------------
  11. u16 ADC_Read(u8 n)
  12. {
  13.     ADC_RES = 0;
  14.     ADC_RESL = 0;
  15.     ADC_CONTR = 0x80 | 0x40 | n;//ACD模块上电0x80、使能ADC转换0x40、给定ADC通道n
  16.     delay_ms(2);
  17.     while((ADC_CONTR & 0x20) == 0);        //等待ADC转换标志ADC_FLAG=1
  18.     ADC_CONTR &= ~0x20;                 //清除标志ADC_FLAG
  19.     return (((u16)ADC_RES << 8) | ADC_RESL);
  20. }
  21. //-----ADC数据输出函数--------------------------------------------------------------------------------------
  22. u16 ADC_out(u8 adc_x)
  23. {
  24.     u16 adc_data0 = 0;
  25.     u32 adc_data1 = 0;
  26. //读取15通道的ADC值
  27.     ADC_Read(15);                                //先读一次15通道并丢弃结果
  28.     adc_data0 = ADC_Read(15);        //获得15通道16次平均值(硬件平均值运算)
  29. //读取adc_x通道的ADC值
  30.     ADC_Read(adc_x);                        //先读一次目标通道并丢弃结果
  31.     adc_data1 = ADC_Read(adc_x);        //获得硬件16次平均值
  32.     adc_data1 = BGV * adc_data1 / adc_data0; //对比ADC15通道采样值利用STC单片机内部基准电压值换算目标通道电压值(数据放大1000倍)
  33.     return (u16)adc_data1;
  34. }
复制代码







回复

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 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. 如果以上步骤均未解决问题,考虑更换单片机以排除硬件故障。

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

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

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:424
  • 最近打卡:2025-05-02 14:37:11
已绑定手机

77

主题

4849

回帖

8382

积分

超级版主

DebugLab

积分
8382
发表于 2025-4-1 14:14:16 | 显示全部楼层
检查单片机IO是否损坏,换一个单片机试试
其他功能是否正常,检查是不是哪里卡住,不能执行设置IO口为高阻的指令,或意外被设置为推挽
主时钟是否接近极限频率,如是,要正确设置IAP_TPS寄存器,如仍有异常,尝试设置IRCDB寄存器为16
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:51
  • 最近打卡:2025-05-02 10:07:51

73

主题

5883

回帖

1万

积分

超级版主

积分
12079
发表于 2025-4-1 14:23:55 | 显示全部楼层
ADC输入为高阻,悬空时可以读到任意值,因为你没有给定一个电压,所以输入端时浮空的,电压会不确定。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:441
  • 最近打卡:2025-05-02 09:05:39

45

主题

176

回帖

1735

积分

金牌会员

积分
1735
发表于 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口有问题外的其他控制一切正常。不可思议!


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


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:441
  • 最近打卡:2025-05-02 09:05:39

45

主题

176

回帖

1735

积分

金牌会员

积分
1735
发表于 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分压采样)。

点评

那你实际测量下MOSFET的D极电压和P1.0电压多少V?  详情 回复 发表于 2025-4-1 18:55
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:51
  • 最近打卡:2025-05-02 10:07:51

73

主题

5883

回帖

1万

积分

超级版主

积分
12079
发表于 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?
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 18:00 , Processed in 0.120405 second(s), 94 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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