STC8H8K64U的P1口问题
做个简单项目时,出现奇葩问题,P1口的P1.1、P1.2、P1.3口分别外接按键到地,3个端口都没有外接上拉电阻,程序下载到单片机P1.1口的按键有功能,P1.2和P1.3口的按键都没有功能,为了分析问题,只做按键功能测试,还是一样的问题,以下是测试代码#include<STC8.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit SetKey = P1^1;
sbit UpKey= P1^2;
sbit DnKey= P1^3;
sbit Alarm= P3^3;
void Delay1ms(void) //@12.000MHz
{
unsigned char i, j;
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
void delay(uint n) //延时
{
while(n--)
{
Delay1ms();
}
}
/*------------------------------------------------
主函数
------------------------------------------------*/
void main(void)
{
P_SW2 &= 0x7F; //关闭扩展寄存器(XFR)访问使能
P2M1=0x00;P2M0=0xf0;
P1M1=0x00;P1M0=0x00;
P3M1=0x00;P3M0=0x00;
// P1M1 |= (1 << 6); // 将 P1M1 的第6位置1
// P1M0 &= ~(1 << 6);// 将 P1M0 的第6位清零
// P1PU |= (1 << 6); // 将 P1PU 的第6位置1,使能P1.6的内部上拉
// P1=0xff;
while(1)
{
if(UpKey==0)
{
delay(10);
while(UpKey==0)
{
Alarm=0;
}
}
else Alarm=1;
if(SetKey==0)
{
delay(10);
while(SetKey==0)
{
Alarm=0;
}
}
else Alarm=1;
}
}
还有个奇葩的事情,温度传感器DS18B20接P1.6口实现不了读温度,改接P2.0、P3.6这些口都可以正常读取问题,P1.6、P2.0、P3.6如果不接DS18B20时,外部都没有外接其他元件。请帮忙看看是什么问题!
你好,关于你提到的 STC8H8K64U 单片机 P1 口按键检测异常问题(P11 有功能,P12 和 P13 无功能),结合你的描述和代码,我来做一个较为全面的分析与排查建议。
一、问题描述复述
你使用的是 STC8H8K64U 单片机,P1.1、P1.2、P1.3 分别接了按键到地,未接上拉电阻。程序中仅做按键检测测试,发现:
P1.1 按键有效;
P1.2、P1.3 按键无效;
使用的测试代码中对 P1M1 和 P1M0 设置为 0x00,即设置为“准双向口”模式;
没有使用中断,仅采用软件延时消抖检测电平变化。
二、STC8H 系列 P1 口工作模式说明
STC8H 系列单片机的 I/O 口具有多种配置方式,通过 PnM1 和 PnM0 寄存器组合控制。以下是 P1M1 和 P1M0 的典型组合及其含义:
| P1M1 | P1M0 | 模式说明 |
|------|------|--------------------|
| 0 | 0 | 准双向口(默认) |
| 0 | 1 | 推挽输出 |
| 1 | 0 | 仅为输入口 |
| 1 | 1 | 开漏输出 |
你设置的是:
c
P1M1 = 0x00;
P1M0 = 0x00;
即设置为“准双向口”,这种模式下内部带有弱上拉电阻(约 20kΩ~50kΩ),适用于按键检测等场合。
三、按键检测逻辑分析
你的按键检测代码大致如下(简化):
c
if(SetKey == 0) { ... }
这表示当按键按下时,对应 I/O 被拉低为 0,程序检测到低电平则认为按键按下。
由于你未外接上拉电阻,完全依赖单片机内部的弱上拉,此时按键能否正常检测,取决于:
1. 按键是否能将引脚可靠拉低;
2. 引脚是否被正确配置为输入/准双向口;
3. 是否存在硬件短路、焊接不良、PCB布线干扰等问题;
4. 是否被其他功能复用或锁定了引脚功能。
四、可能的问题分析
1. 引脚复用或锁定问题
STC8H 系列单片机的部分引脚可能会被某些外设功能(如定时器、ADC、串口、PWM 等)复用。虽然你没有使用这些外设,但仍需确认:
是否有其他模块(如定时器、ADC)误配置导致 P1.2、P1.3 被占用;
是否在初始化代码中遗漏了某些寄存器配置;
是否存在“端口锁定”配置(Port Swap)导致引脚映射错位。
建议检查以下寄存器:
PSW1 / PSW2:端口功能切换寄存器;
ADCCONTR:ADC 控制寄存器;
T2MOD / T2CON:定时器2控制寄存器;
PWMx相关寄存器:如果你使用了 PWM 模块。
2. 硬件问题
按键焊接不良:P1.2、P1.3 的按键是否确实可靠接地?
PCB布线问题:是否存在短路、断路、干扰?
引脚损坏:是否存在静电击穿或过流损坏?
建议使用万用表测量:
按下按键时,P1.2 和 P1.3 是否能被拉低至接近 GND;
未按下按键时,引脚电压是否接近 VCC(约 3.3V 或 5V);
是否存在引脚对地短路。
3. 软件配置问题
你的配置代码中:
c
P1M1 = 0x00;
P1M0 = 0x00;
这表示 P1 全部设置为准双向口,理论上是正确的。但要注意:
是否在代码中存在其他地方对 P1M1 或 P1M0 的修改?
是否开启了某些中断或外设,导致某些引脚被重新配置?
此外,你的代码中注释了一行:
c
// P1M1 |= (1
可能是未完成的配置代码,建议检查是否有遗漏。
五、建议的排查步骤
步骤一:最小系统测试
搭建一个最小系统(仅单片机 + 按键 + 电源),排除外围电路干扰。
步骤二:逐个测试每个按键
仅保留 P1.1 按键,确认其正常;
替换 P1.1 的按键到 P1.2、P1.3,观察是否正常;
若仍不正常,说明硬件或配置问题;
若正常,说明原按键或其线路有问题。
步骤三:修改配置为推挽输出并外部上拉
尝试修改 P1.2、P1.3 为推挽输出,并外接 4.7kΩ 上拉电阻至 VCC,再测试按键是否有效。
配置方式:
```c
P1M1 &= ~((1
[本文内容由国芯人工智能辅助生成,仅供参考] IO模式和上拉电阻这样设置:
谢谢解答!不能直接设置成准双向IO吗?就这样 P1M1=0x00;P1M0=0x00; 看数据手册上有相关描述吗? DebugLab 发表于 2025-10-13 11:53
IO模式和上拉电阻这样设置:
谢谢解答!不能直接设置成准双向IO吗?就这样 P1M1=0x00;P1M0=0x00; 为什么P1.1口可以,P1.2、P1.3不行呢?看数据手册上有相关描述吗? DebugLab 发表于 2025-10-13 11:53
IO模式和上拉电阻这样设置:
你好!按你这个改,蜂鸣器直接长鸣,测P1.1—P1.3口电压,2V左右
#include<STC8.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit SetKey = P1^1;
sbit UpKey= P1^2;
sbit DnKey= P1^3;
sbit Alarm= P3^3;
void Delay1ms(void) //@12.000MHz
{
unsigned char i, j;
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
void delay(uint n) //延时
{
while(n--)
{
Delay1ms();
}
}
/*------------------------------------------------
主函数
------------------------------------------------*/
void main(void)
{
P_SW2 &= 0x7F; //关闭扩展寄存器(XFR)访问使能
P2M1=0x00;P2M0=0xf0;
// P1M1=0x00;P1M0=0x00;
P3M1=0x00;P3M0=0x00;
P1M0 &= ~0x4e;
P1M1 = (P1M1 & ~0x40) | 0x0e;
P1PU |= 0x0e;
// P1M1 |= (1 << 6); // 将 P1M1 的第6位置1
// P1M0 &= ~(1 << 6);// 将 P1M0 的第6位清零
// P1PU |= (1 << 6); // 将 P1PU 的第6位置1,使能P1.6的内部上拉
// P1=0xff;
while(1)
{
if(UpKey==0)
{
delay(10);
while(UpKey==0)
{
Alarm=0;
}
}
else Alarm=1;
if(SetKey==0)
{
delay(10);
while(SetKey==0)
{
Alarm=0;
}
}
else Alarm=1;
}
} aayon1979 发表于 2025-10-13 14:37
谢谢解答!不能直接设置成准双向IO吗?就这样 P1M1=0x00;P1M0=0x00; 看数据手册上有相关描述吗? ...
准双向也可以,高阻只是为了防止向IO写0后强下拉无法正确读取按键,准双向注意不能向IO写0,必须是1 aayon1979 发表于 2025-10-13 14:52
你好!按你这个改,蜂鸣器直接长鸣,测P1.1—P1.3口电压,2V左右
#include
#include
2V左右是不正常的,检查硬件 DebugLab 发表于 2025-10-13 14:56
2V左右是不正常的,检查硬件
硬件是完全没问题的,这个板用stc15w408as芯片功能是都实现了的,我设置成准双向Io,端口电压就是5V,太奇葩了!P1口准双向设置如下
P_SW2 &= 0x7F; //关闭扩展寄存器(XFR)访问使能
P2M1=0x00;P2M0=0xf0;
P1M1=0x00;P1M0=0x00;
P3M1=0x00;P3M0=0x00;
P1=0xff; DebugLab 发表于 2025-10-13 14:56
2V左右是不正常的,检查硬件
硬件是完全没问题的,这个板用stc15w408as芯片功能是都实现了的,我设置成准双向Io,端口电压就是5V,太奇葩了!P1口准双向设置如下
P_SW2 &= 0x7F; //关闭扩展寄存器(XFR)访问使能
P2M1=0x00;P2M0=0xf0;
P1M1=0x00;P1M0=0x00;
P3M1=0x00;P3M0=0x00;
P1=0xff;
按你指导的设置,端口电压就是2V左右
P_SW2 &= 0x7F; //关闭扩展寄存器(XFR)访问使能
P2M1=0x00;P2M0=0xf0;
// P1M1=0x00;P1M0=0x00;
P3M1=0x00;P3M0=0x00;
// P1=0xff;
P1M0 &= ~0x4e;
P1M1 = (P1M1 & ~0x40) | 0x0e;
P1PU |= 0x0e;
页:
[1]
2