找回密码
 立即注册
查看: 53|回复: 5

请教使用P0口做中断的问题-还是没解决问题已跟帖,麻烦会的帮忙解答一下,谢谢

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:474
  • 最近打卡:2025-10-25 00:09:12
已绑定手机

3

主题

14

回帖

1473

积分

金牌会员

积分
1473
发表于 前天 03:09 | 显示全部楼层 |阅读模式
单片机:STC8H8K64U

想使用P00口接地点亮LED灯
使用汇编的方式
  1. void P0_Isr() interrupt 13
  2. {
  3.         char intf;
  4.         intf=P0INTF;
  5.         P0INTF=0x00;
  6.         
  7.                
  8.                 if(intf & 0x01)
  9.                 {
  10.                         P20=~P20;
  11.                 }
  12.         
  13. }
复制代码
汇编文件保存
  1. CSEG AT 012BH ;P0 口中断入口地址
  2.         JMP P0INT_ISR
  3. P0INT_ISR:
  4. JMP 006BH ;借用 13 号中断的入口地址
  5. END
复制代码
main文件
  1.         P0IM0&=~0X01;    //低电平有效
  2.         P0IM1|=0X01;
  3.         P0INTE|=0X01;
  4. EA=1;
复制代码


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

因为我的keil版本是V 9.60.7.0,安装 截图202510240302457553.jpg 后也不能使用
回复

使用道具 举报 送花

3

主题

1849

回帖

546

积分

等待验证会员

积分
546
发表于 前天 03:12 | 显示全部楼层
您好,感谢您的提问。您使用的是 STC8H8K64U 单片机,希望通过 P0.0 引脚的中断功能 来触发 LED 灯的翻转,使用的是汇编语言实现中断跳转,并在 C 语言中编写中断服务函数。但目前的问题是 P0.0 接地后 LED 并未翻转,即中断未被正确触发。

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

一、问题分析

1. 中断配置是否正确?

您在 main 函数中进行了如下配置:
  1. c
  2. P0IM0 &= ~0x01;    // 设置 P0.0 为低电平触发
  3. P0IM1 |= 0x01;     // 设置为中断类型
  4. P0INTE |= 0x01;    // 使能 P0.0 中断
  5. EA = 1;            // 全局中断使能
复制代码

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

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

您在汇编文件中设置了中断入口:
  1. asm
  2. CSEG AT 012BH ; P0 口中断入口地址
  3.     JMP P0INTISR
  4. P0INTISR:
  5. JMP 006BH ; 借用 13 号中断的入口地址
  6. END
复制代码

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

3. 中断服务函数是否正确?
  1. c
  2. void P0Isr() interrupt 13
  3. {
  4.         char intf;
  5.         intf = P0INTF;
  6.         P0INTF = 0x00;
  7.         if (intf & 0x01)
  8.         {
  9.                 P20 = ~P20;
  10.         }
  11. }
复制代码

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

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

二、解决方案

1. 正确设置中断向量

STC8H8K64U 的中断向量表中,13号中断(P0 口中断)对应的地址是 0x006B,所以汇编文件应该如下:
  1. asm
  2. CSEG AT 006BH
  3.     LJMP P0INTISR
  4. P0INTISR:
  5.     LJMP 006BH ; 或者跳转到 C 函数的入口地址(需要链接器支持)
  6. 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
  1. c
  2. include
  3. void P0Isr() interrupt 13
  4. {
  5.     char intf;
  6.     intf = P0INTF;
  7.     P0INTF = 0x00;  // 清除所有中断标志
  8.     if (intf & 0x01)  // 判断是否是 P0.0 触发
  9.     {
  10.         P20 = ~P20;  // 翻转 LED
  11.     }
  12. }
  13. void main()
  14. {
  15.     // 设置 P0.0 为低电平触发中断
  16.     P0IM0 &= ~0x01;   // 低电平有效
  17.     P0IM1 |= 0x01;    // 设置为中断
  18.     P0INTE |= 0x01;   // 使能 P0.0 中断
  19.     EA = 1;           // 全局中断使能
  20.     while (1);
  21. }
复制代码

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)测试中断机制是否正常工作。

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

祝您调试顺利!

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

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:338
  • 最近打卡:2025-10-25 16:43:59
已绑定手机

90

主题

3309

回帖

7395

积分

荣誉版主

无情的代码机器

积分
7395
发表于 前天 09:11 | 显示全部楼层
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:474
  • 最近打卡:2025-10-25 00:09:12
已绑定手机

3

主题

14

回帖

1473

积分

金牌会员

积分
1473
发表于 前天 10:39 | 显示全部楼层
erci*** 发表于 2025-10-24 09:11
没开EAXFR?上传完整代码及电路图?

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

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

您有完整的示例吗?

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

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:474
  • 最近打卡:2025-10-25 00:09:12
已绑定手机

3

主题

14

回帖

1473

积分

金牌会员

积分
1473
发表于 前天 10:50 | 显示全部楼层
erci*** 发表于 2025-10-24 09:11
没开EAXFR?上传完整代码及电路图?

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

https://www.stcaimcu.com/forum.p ... mp;extra=#pid154960

哦哦,我看到了这个文件,你下面引用的。
晚上回去试一下,我确实没有看这个,我一直在看手册。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:474
  • 最近打卡:2025-10-25 00:09:12
已绑定手机

3

主题

14

回帖

1473

积分

金牌会员

积分
1473
发表于 昨天 22:01 | 显示全部楼层
复制代码
  1. #include "STC8H.h"
  2. void P0_Isr() interrupt 13
  3. {
  4.          char intf;
  5.     intf = P0INTF;
  6.     P0INTF = 0x00;  // 清除所有中断标志
  7.     if (intf & 0x01)  // 判断是否是 P0.0 触发
  8.     {
  9.         P20 = ~P20;  // 翻转 LED
  10.     }
  11. }
  12. void main()
  13. {
  14.         P_SW2|=0X80;//使能访问XFR,没有冲突不用关闭
  15.           P0IM0 &= ~0x01;   // 低电平有效
  16.     P0IM1 |= 0x01;    // 设置为中断
  17.     P0INTE |= 0x01;   // 使能 P0.0 中断
  18.             P0M0 &= ~0x01; P0M1 &= ~0x01;
  19.     P0PU |= 0x01;
  20.        
  21.         EA=1;//CPU中断使能
  22.         while(1){;}
  23. }
复制代码

代码如上, 计划为,P00接地LED反转,但是未成功,接线图
微信图片_20251025220014_69_44.jpg

麻烦有懂的,帮忙看下是哪里有问题。谢谢

回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-10-26 07:57 , Processed in 0.136915 second(s), 81 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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