|
|
楼主 |
发表于 2026-8-28 09:41:25
|
显示全部楼层
问Ai了
现在我已经获得了足够的信息来编写程序。让我整理一下STC15W4K32S4系列的外部中断信息:
外部中断引脚:
INT0 → P3.2,上升沿/下降沿均可触发(IT0=0),或仅下降沿(IT0=1)
INT1 → P3.3,上升沿/下降沿均可触发(IT1=0),或仅下降沿(IT1=1)
INT2 → P3.6,仅下降沿触发
INT3 → P3.7,仅下降沿触发
INT4 → P3.0,仅下降沿触发
中断向量/中断号:
INT0 → interrupt 0
INT1 → interrupt 2
INT2 → interrupt 10
INT3 → interrupt 11
INT4 → interrupt 16
中断寄存器:
INT0/INT1:IE寄存器中的EX0/EX1,TCON中的IT0/IT1
INT2/INT3/INT4:INT_CLKO(8FH)寄存器中的EX2/EX3/EX4位,加上EA总中断
现在需要确认用户所说的"STC15W413"具体对应哪个型号。根据STC15系列命名规则,STC15W4K32S4是STC15W系列中的大容量型号。用户可能指的是STC15W4K32S4系列。
我需要确认一下,根据您提到的"STC15W413",这可能是STC15W4K32S4系列中的一个具体型号,但我需要确认。让我查阅STC15系列的命名规则。
根据已有的信息,STC15W4K32S4系列包含了多种封装和存储大小。用户说的"STC15W413"很可能指的是STC15W4K32S4系列。不过为保险起见,我需要确认这个型号是否在手册中有特别说明。
现在我已经有充分的信息来编写完整的程序。让我确认一下用户需要的功能:所有外部中断(INT0/INT1/INT2/INT3/INT4),每个中断对应一个IO口取反。
我将编写完整的代码,每个中断服务程序中翻转一个不同的IO口。
由于需要确定输出引脚,让我设计合理的IO口分配。根据手册说明,INT0=P3.2、INT1=P3.3、INT2=P3.6、INT3=P3.7、INT4=P3.0。我们可以将对应的输出引脚分配到其他IO口,比如P1.0-P1.4等。
不过,在编写代码前,我需要确认一点:您说的"STC15W413"具体是指哪一个型号?是STC15W4K32S4系列吗?让我再确认一下命名规则。
根据STC15系列命名规则,STC15W4K32S4系列是STC15系列中功能最强大的型号,具有4K SRAM、32K Flash。用户说的"STC15W413"可能是简写或误写。
我直接按照STC15W4K32S4系列来编写这个程序,因为这个系列是STC15系列中外部中断功能最完整的。现在让我编写完整的代码。
根据手册信息,我已经为您整理好了完整的代码。关于您的型号,STC15W4K32S4系列(STC15W413可能指该系列)提供5个外部中断:INT0、INT1、INT2、INT3、INT4。下面为您编写完整的程序。
STC15W4K32S4 五个外部中断 - 每个中断对应一个IO口取反
外部中断引脚及中断号汇总
根据手册《STC15系列单片机的中断系统》章节:
中断 引脚 中断号 触发方式 中断允许位
INT0 P3.2 0 上升沿/下降沿或仅下降沿 EX0
INT1 P3.3 2 上升沿/下降沿或仅下降沿 EX1
INT2 P3.6 10 仅下降沿 EX2 (INT_CLKO.4)
INT3 P3.7 11 仅下降沿 EX3 (INT_CLKO.5)
INT4 P3.0 16 仅下降沿 EX4 (INT_CLKO.6)
完整代码
/*---------------------------------------------------------------------*/
/* STC15W4K32S4系列 五个外部中断程序 */
/* 每个外部中断对应一个IO口取反 */
/* */
/* 中断引脚分配: */
/* INT0 -> P3.2 (中断号0) -> 取反 P1.0 */
/* INT1 -> P3.3 (中断号2) -> 取反 P1.1 */
/* INT2 -> P3.6 (中断号10) -> 取反 P1.2 */
/* INT3 -> P3.7 (中断号11) -> 取反 P1.3 */
/* INT4 -> P3.0 (中断号16) -> 取反 P1.4 */
/* */
/* 编译环境: Keil C51,选择 Intel 8052 编译 */
/* 头文件: 包含 reg51.h 即可 */
/*---------------------------------------------------------------------*/
#include <reg51.h>
#include <intrins.h>
/* 特殊功能寄存器定义(需手动声明) */
sfr INT_CLKO = 0x8F; /* 外部中断2/3/4允许寄存器 */
sfr P1M1 = 0x91; /* P1口模式控制寄存器1 */
sfr P1M0 = 0x92; /* P1口模式控制寄存器0 */
sfr P3M1 = 0xB1; /* P3口模式控制寄存器1 */
sfr P3M0 = 0xB2; /* P3口模式控制寄存器0 */
/* 输出引脚定义 */
sbit LED_OUT0 = P1^0; /* INT0触发时取反 */
sbit LED_OUT1 = P1^1; /* INT1触发时取反 */
sbit LED_OUT2 = P1^2; /* INT2触发时取反 */
sbit LED_OUT3 = P1^3; /* INT3触发时取反 */
sbit LED_OUT4 = P1^4; /* INT4触发时取反 */
/*---------------------------------------------------------------------*/
/* 主函数 */
/*---------------------------------------------------------------------*/
void main(void)
{
/* 1. 配置输出引脚P1.0~P1.4为推挽输出(强上拉) */
/* P1M1和P1M0对应位: 0/1 = 推挽输出 */
P1M1 = 0x00; /* P1.0~P1.7 均为推挽输出 */
P1M0 = 0x1F; /* 仅P1.0~P1.4为推挽输出(低5位) */
/* 实际上推挽需要P1M1=0, P1M0=1 */
/* 2. 配置外部中断输入引脚P3.2/P3.3/P3.6/P3.7/P3.0 */
/* 作为输入使用,需设置为高阻输入 */
P3M1 = 0xCD; /* P3.0/P3.2/P3.3/P3.6/P3.7 高阻输入 */
P3M0 = 0x00;
/* 详细位: P3.0=1, P3.1=0, P3.2=1, P3.3=1, P3.4=0, P3.5=0, P3.6=1, P3.7=1 */
/* P3M1: 1 1 0 0 1 1 1 0 = 0xCE 不对,重新计算 */
/* 重新计算:P3.0、P3.2、P3.3、P3.6、P3.7 需要高阻输入 */
/* P3M1对应位为1, P3M0对应位为0 → 高阻输入 */
/* bit7=P3.7=1, bit6=P3.6=1, bit5=P3.5=0, bit4=P3.4=0 */
/* bit3=P3.3=1, bit2=P3.2=1, bit1=P3.1=0, bit0=P3.0=1 */
/* P3M1 = 1100 1111 = 0xCF */
P3M1 = 0xCF; /* P3.0/P3.2/P3.3/P3.6/P3.7 高阻输入 */
P3M0 = 0x00; /* 其余为准双向 */
/* 3. 配置外部中断触发方式 */
/* IT0=0: INT0上升沿/下降沿均可触发 */
/* IT1=0: INT1上升沿/下降沿均可触发 */
/* IT0=1: 仅下降沿。这里设为0, 双沿触发 */
TCON &= 0xFC; /* IT0=0, IT1=0, 上升沿/下降沿均可触发 */
/* 4. 开启中断 */
EX0 = 1; /* 允许INT0中断 */
EX1 = 1; /* 允许INT1中断 */
/* INT2/INT3/INT4 中断允许位在INT_CLKO寄存器中 */
INT_CLKO |= 0x70; /* EX4=1, EX3=1, EX2=1 (BIT6/5/4) */
/* 5. 打开总中断 */
EA = 1;
/* 6. 初始化输出引脚电平 */
LED_OUT0 = 0;
LED_OUT1 = 0;
LED_OUT2 = 0;
LED_OUT3 = 0;
LED_OUT4 = 0;
/* 主循环 */
while(1)
{
/* 主程序可以执行其他任务 */
}
}
/*---------------------------------------------------------------------*/
/* 外部中断0服务程序 (INT0 -> P3.2) */
/*---------------------------------------------------------------------*/
void INT0_Routine(void) interrupt 0
{
LED_OUT0 = ~LED_OUT0; /* P1.0取反 */
}
/*---------------------------------------------------------------------*/
/* 外部中断1服务程序 (INT1 -> P3.3) */
/*---------------------------------------------------------------------*/
void INT1_Routine(void) interrupt 2
{
LED_OUT1 = ~LED_OUT1; /* P1.1取反 */
}
/*---------------------------------------------------------------------*/
/* 外部中断2服务程序 (INT2 -> P3.6) */
/*---------------------------------------------------------------------*/
void INT2_Routine(void) interrupt 10
{
LED_OUT2 = ~LED_OUT2; /* P1.2取反 */
}
/*---------------------------------------------------------------------*/
/* 外部中断3服务程序 (INT3 -> P3.7) */
/*---------------------------------------------------------------------*/
void INT3_Routine(void) interrupt 11
{
LED_OUT3 = ~LED_OUT3; /* P1.3取反 */
}
/*---------------------------------------------------------------------*/
/* 外部中断4服务程序 (INT4 -> P3.0) */
/*---------------------------------------------------------------------*/
void INT4_Routine(void) interrupt 16
{
LED_OUT4 = ~LED_OUT4; /* P1.4取反 */
}
关键说明
根据手册《中断系统》章节:
INT0/INT1(P3.2/P3.3)的触发方式由 TCON 寄存器中的 IT0/IT1 控制:
ITx=0:上升沿或下降沿均可触发
ITx=1:仅下降沿触发
INT2/INT3/INT4(P3.6/P3.7/P3.0)只能下降沿触发,由 INT_CLKO(地址0x8F)寄存器控制:
EX2(bit4)、EX3(bit5)、EX4(bit6)来允许中断
P3M1/P3M0 用于配置P3口的输入/输出模式,外部中断引脚建议配置为高阻输入模式(P3M1对应位=1,P3M0对应位=0)。
P1M1/P1M0 用于配置P1口的输出模式,输出引脚(取反的IO口)配置为推挽输出模式(P3M1=0,P3M0=1)以增强驱动能力。
注意事项
外部中断2/3/4为固定最低优先级,若需要更高优先级请考虑使用INT0/INT1。
每个中断引脚输入信号至少需要维持2个时钟周期以确保被检测到。
若使用INT0/INT1作为按键输入,建议按键接到VCC(上拉),按键按下时产生下降沿触发;或按键接地,按键释放时产生上升沿触发(需设置IT0/IT1=0)。
如果您需要将某个中断改为仅下降沿触发,请将 TCON 中的相应位置1(IT0=1 或 IT1=1)。如需调整输出IO口或中断触发方式,请告诉我具体需求,我可以进一步修改。
🔍 搜索 "STC15W413 外部中断 程序 引脚取反"
📌 相关论坛讨论
STC15W413AS有几个外部中断
IAP15W4K61S4 LQFP64封装脚位是怎么排列的
所有普通I/O口都支持的外部中断演示程序,8H系列、32G系列, 中断号37~44
⏱️ 查找用时 19.3s | 总回答用时 46.2s |
|