bh7nly 发表于 昨天 03:09

请教使用P0口做中断的问题

单片机:STC8H8K64U

想使用P00口接地点亮LED灯
使用汇编的方式
void P0_Isr() interrupt 13
{
        char intf;
        intf=P0INTF;
        P0INTF=0x00;
       
               
                if(intf & 0x01)
                {
                        P20=~P20;
                }
       
}汇编文件保存
CSEG AT 012BH ;P0 口中断入口地址
      JMP P0INT_ISR


P0INT_ISR:
JMP 006BH ;借用 13 号中断的入口地址
ENDmain文件
      P0IM0&=~0X01;    //低电平有效
        P0IM1|=0X01;
        P0INTE|=0X01;
EA=1;

问题是 我P00口接gnd,LED灯不亮,麻烦高手给说明下原因。

因为我的keil版本是V 9.60.7.0,安装后也不能使用

国芯人工智能 发表于 昨天 03:12

您好,感谢您的提问。您使用的是 STC8H8K64U 单片机,希望通过 P0.0 引脚的中断功能 来触发 LED 灯的翻转,使用的是汇编语言实现中断跳转,并在 C 语言中编写中断服务函数。但目前的问题是 P0.0 接地后 LED 并未翻转,即中断未被正确触发。

以下是对您问题的详细分析与解决方案:

一、问题分析

1. 中断配置是否正确?

您在 main 函数中进行了如下配置:

c
P0IM0 &= ~0x01;    // 设置 P0.0 为低电平触发
P0IM1 |= 0x01;   // 设置为中断类型
P0INTE |= 0x01;    // 使能 P0.0 中断
EA = 1;            // 全局中断使能

从配置来看,您希望 P0.0 引脚在检测到低电平时触发中断,并进入中断服务函数处理 LED 翻转。配置逻辑上是正确的。

2. 中断向量表设置是否正确?

您在汇编文件中设置了中断入口:

asm
CSEG AT 012BH ; P0 口中断入口地址
    JMP P0INTISR

P0INTISR:
JMP 006BH ; 借用 13 号中断的入口地址
END

这里存在两个问题:
STC8H8K64U 的中断向量地址是固定的,P0 口中断的向量地址应为 0x006B(13号中断),而不是 0x012B。
您的汇编文件中将 JMP 指向了 0x006B,但将代码定位在了 0x012B,这会导致中断向量未正确加载。

3. 中断服务函数是否正确?

c
void P0Isr() interrupt 13
{
        char intf;
        intf = P0INTF;
        P0INTF = 0x00;

        if (intf & 0x01)
        {
                P20 = ~P20;
        }
}

这段代码逻辑上没有问题:
使用 interrupt 13 表示这是 13 号中断(P0 口中断)
读取中断标志并清除
判断是否是 P0.0 触发,并翻转 P2.0

但前提是中断向量必须正确跳转到该函数。

二、解决方案

1. 正确设置中断向量

STC8H8K64U 的中断向量表中,13号中断(P0 口中断)对应的地址是 0x006B,所以汇编文件应该如下:

asm
CSEG AT 006BH
    LJMP P0INTISR

P0INTISR:
    LJMP 006BH ; 或者跳转到 C 函数的入口地址(需要链接器支持)
END

或者更简单的做法是:不要手动编写汇编文件,直接使用 Keil 的中断机制,只要在 C 中声明 interrupt 13 即可。

2. 避免“借用”中断地址

您提到“借用 13 号中断的入口地址”,这可能是由于对中断机制理解不清晰。STC8H8K64U 的中断系统是固定的,每个中断源都有其对应的向量地址和中断号。P0 口中断就是 13 号中断,无需“借用”。

3. 确保中断标志清除

在中断服务函数中,您已清除 P0INTF,这很重要。若不清除中断标志,会导致中断不断触发,可能造成程序卡死。

4. 检查硬件连接
P0.0 是否正确接地?
确保接地点稳定,无虚焊。
可以尝试使用按键代替直接接地,观察是否有触发。
LED 是否连接正确?
P2.0 是否为共阳或共阴接法?
是否有上拉电阻?STC8H 系列 I/O 默认为高阻态,P0 口需要上拉才能检测低电平。

5. Keil 编译器兼容性问题

您提到安装了后仍无法使用,可能是 Keil C51 版本过旧,建议使用 Keil μVision5 并安装最新 STC 支持包,确保编译器支持 STC8H 系列单片机。

三、完整推荐代码

1. main.c

c
include

void P0Isr() interrupt 13
{
    char intf;
    intf = P0INTF;
    P0INTF = 0x00;// 清除所有中断标志

    if (intf & 0x01)// 判断是否是 P0.0 触发
    {
      P20 = ~P20;// 翻转 LED
    }
}

void main()
{
    // 设置 P0.0 为低电平触发中断
    P0IM0 &= ~0x01;   // 低电平有效
    P0IM1 |= 0x01;    // 设置为中断
    P0INTE |= 0x01;   // 使能 P0.0 中断
    EA = 1;         // 全局中断使能

    while (1);
}

2. 汇编文件(可选,不推荐)

如果使用标准 Keil 工程结构,无需手动编写中断跳转汇编文件。只需在 C 中声明 interrupt 13 即可,Keil 会自动将中断向量绑定到该函数。

四、总结

| 问题点 | 建议解决方案 |
|--------|----------------|
| 汇编文件设置错误 | 不建议手动设置中断向量,Keil 会自动处理 |
| 中断向量地址错误 | 使用 interrupt 13 关键字,Keil 自动绑定到 0x006B |
| 硬件连接问题 | 检查 P0.0 是否稳定接地,LED 是否正常 |
| Keil 兼容性问题 | 更新 Keil μVision5,并安装 STC 支持包 |

五、建议调试方法

1. 使用按键代替直接接地,观察是否能触发中断;
2. 在 main 中先点亮 LED,确认硬件连接无误;
3. 在中断函数中加入延时或串口输出调试信息,确认是否进入中断;
4. 使用逻辑分析仪或示波器检测 P0.0 电平变化;
5. 尝试使用 P3 口中断(如 INT0)测试中断机制是否正常工作。

如仍有问题,建议提供完整工程代码和硬件连接图,以便更准确地定位问题。

祝您调试顺利!

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

ercircle 发表于 昨天 09:11

没开EAXFR?上传完整代码及电路图?

【萌新指南】keil5安装指南(官方渠道方法下载并安装C251, C51) - 仿真/编译器/汇编器/头文件 国芯人工智能技术交流网站 - AI32位8051交流社区

新手必读!新手必读!新手必读!新手必读!新手必读!新手必读!新手必读!新手必读! - 老鸟反刍/吐槽,新手乐园,毕业设计 国芯人工智能技术交流网站 - AI32位8051交流社区

bh7nly 发表于 昨天 10:39

ercircle 发表于 2025-10-24 09:11
没开EAXFR?上传完整代码及电路图?

【萌新指南】keil5安装指南(官方渠道方法下载并安装C251, C51) - 仿 ...

我现在公司没有板子,但是我看手册的记录是没有EAXFR的解释呢?
您这个EAXFR在他的示例是没有的。

您有完整的示例吗?

我是用的是在积分兑换里面直接兑换的板子。

bh7nly 发表于 昨天 10:50

ercircle 发表于 2025-10-24 09:11
没开EAXFR?上传完整代码及电路图?

【萌新指南】keil5安装指南(官方渠道方法下载并安装C251, C51) - 仿 ...

https://www.stcaimcu.com/forum.php?mod=viewthread&tid=16535&highlight=%E6%96%B0%E6%89%8B%E5%BF%85%E8%AF%BB&page=1&extra=#pid154960

哦哦,我看到了这个文件,你下面引用的。
晚上回去试一下,我确实没有看这个,我一直在看手册。
页: [1]
查看完整版本: 请教使用P0口做中断的问题