limddfcl 发表于 2025-8-15 11:24:50

8H2K12U 设置IO中断后提示编译错误 帮忙分析以下

void Port3_Isr (void) interrupt 40
{
      
      
}

void PortInt_Init(void)
{
      P3INTE = 0x40;                        //使能P3口中断 p36
      P3IM0 = 0x40;                        //设置P3口中断模式 (00:下降沿, 01:上升沿)
      P3IM1 = 0x00;                        //设置P3口中断模式 (10:低电平, 11:高电平)
      P3WKUE = 0x00;                        //设置P3口中断唤醒省电模式
}

Rebuild started: Project: STC8H2K12U
Rebuild target 'Target 1'
compiling main.c...
compiling STC8G_H_GPIO.c...
compiling STC8G_H_Timer.c...
compiling STC8G_H_Timer_Isr.c...
compiling STC8G_H_UART.c...
compiling STC8G_H_UART_Isr.c...
compiling STC8G_H_NVIC.c...
compiling STC8G_H_Delay.c...
linking...
LX51 LINKER/LOCATER V4.66.97.0 - SN: K1SMC-KNTYSC
COPYRIGHT ARM Germany GmbH 1995 - 2019
@.\list\STC8H2K12U.lnp ".\list\main.obj",
".\list\STC8G_H_GPIO.obj",
".\list\STC8G_H_Timer.obj",
".\list\STC8G_H_Timer_Isr.obj",
".\list\STC8G_H_UART.obj",
".\list\STC8G_H_UART_Isr.obj",
".\list\STC8G_H_NVIC.obj",
".\list\STC8G_H_Delay.obj"
TO ".\list\STC8H2K12U"
PRINT(".\list\STC8H2K12U.map") REMOVEUNUSED
*** ERROR L214: INPUT PHASE ERROR
    MODULE:.\list\main.obj (MAIN)
Target not created.
Build Time Elapsed:00:00:02

国芯人工智能 发表于 2025-8-15 11:28:00

您在使用STC8H2K12U单片机时,设置IO中断后出现编译错误,可能是由于中断服务函数的定义与单片机的中断向量表不匹配所致。以下是对您代码的分析及建议:

一、问题分析

您的代码中定义了如下中断服务函数:

c
void Port3Isr (void) interrupt 40
{
}

在STC8H系列单片机中,中断号与中断向量地址是固定的。对于STC8H2K12U,其内部中断源对应的中断号和中断向量地址需要与用户程序中定义的interrupt参数一致。

1. 中断号对应关系

STC8H系列单片机的中断号定义如下(部分):

| 中断源 | 中断号 | 向量地址 |
|--------|--------|----------|
| P3口中断 | 40 | 0x007B |

因此,interrupt 40 是正确的,理论上应该可以正常编译。

但需要注意的是,STC8H系列支持多个中断源,且部分中断可能被系统占用或未启用。如果未正确配置中断使能寄存器,也可能导致编译警告或错误。

二、代码检查

您提供的PortIntInit()函数如下:

c
void PortIntInit(void)
{
    P3INTE = 0x40;          //使能P3口中断 p36
    P3IM0 = 0x40;         //设置P3口中断模式 (00:下降沿, 01:上升沿)
    P3IM1 = 0x00;         //设置P3口中断模式 (10:低电平, 11:高电平)
    P3WKUE = 0x00;          //设置P3口中断唤醒省电模式
}

1. P3INTE 寄存器
P3INTE 用于使能P3口的中断功能。
设置为 0x40 表示仅使能P3.6引脚的中断,这是正确的。

2. P3IM0 和 P3IM1 寄存器
P3IM0 和 P3IM1 共同决定P3口的中断触发方式。
该组合表示:P3IM1=00,P3IM0=01,即 上升沿触发。
但您设置的是 P3IM0=0x40,这显然不符合逻辑,因为 P3IM0 的位宽为4位,每一位代表一个引脚的中断模式。
❗ 此处存在明显错误:P3IM0 应为按位设置,例如 P3IM0 |= 0x01; 表示P3.0为上升沿触发,而不是直接赋值为 0x40。

3. P3WKUE 寄存器
用于设置P3口中断是否可用于唤醒掉电模式,此处设置为 0x00 是合理的。

三、建议修改

根据上述分析,以下是修正后的 PortIntInit() 函数:

c
void PortIntInit(void)
{
    // 使能P3.6中断
    P3INTE |= 0x40;

    // 设置P3.6中断为上升沿触发
    P3IM0 |= 0x01;   // P3.0~P3.3的中断模式
    P3IM1 |= 0x00;   // P3.4~P3.7的中断模式

    // 设置P3中断不用于唤醒省电模式
    P3WKUE &= ~0x40;
}
✅ 注意:P3IM0 和 P3IM1 应按位设置,不能直接赋值为 0x40。

四、中断服务函数定义

您当前的中断服务函数定义为:

c
void Port3Isr (void) interrupt 40
{
}

此定义在标准C51语法中是合法的,但需确保:
使用的编译器支持该语法;
中断向量地址正确;
在启动文件中已正确映射中断向量。

五、总结

您的代码中主要问题在于:

1. P3IM0 被错误地赋值为 0x40,应按位设置;
2. 建议使用位操作(如 |=, &=)来设置寄存器;
3. 确保中断服务函数与中断向量地址匹配;
4. 检查编译器版本及中断向量表配置。

如您提供完整的编译错误信息,我们可以进一步定位具体原因。希望以上分析对您有所帮助。

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

AI芯 发表于 2025-8-15 11:30:32

装一下Keil中断拓展插件
深圳国芯人工智能有限公司-工具软件


Keil C51, Keil C251 中断号的 拓展:0 ~ 254,BL51/LX51/L251链接器, 说明
https://www.stcaimcu.com/thread-6287-1-1.html
(出处: 国芯人工智能技术交流网站)


limddfcl 发表于 2025-8-15 11:38:10

现在发现问题就是出在 interrupt 40 上 如果单独注释 interrupt 40 就能编译通过

ercircle 发表于 2025-8-15 11:45:04

limddfcl 发表于 2025-8-15 11:38
现在发现问题就是出在 interrupt 40 上 如果单独注释 interrupt 40 就能编译通过


LX51不支持中断拓展

切换BL51+中断拓展插件,或,使用汇编跳转看下手册这个章节


Keil C51, Keil C251 中断号的 拓展:0 ~ 254,BL51/LX51/L251链接器, 说明 - 仿真/编译器/汇编器/头文件 国芯人工智能技术交流网站 - AI32位8051交流社区

limddfcl 发表于 2025-8-15 12:03:45

Use Extended Linker(LX51) instead of BL51 已经勾选, 中断向量安装时提示 c51.exe 已经修改, C251 未找到是否有问题?

limddfcl 发表于 2025-8-15 16:02:03

中断被触发一次,一直在触发,需要清中断吗?如何清除呢

limddfcl 发表于 2025-8-15 16:04:33

void Port3_Isr (void) interrupt 40
{
        printf("test \r\n");
       
}



void PortInt_Init(void)
{
        P3INTE |= 0x40;                        //使能P3口中断 p36
        P3IM0 |= 0x00;                        //设置P3口中断模式 (00:下降沿, 01:上升沿)
        P3IM1 |= 0x10;                        //设置P3口中断模式 (10:低电平, 11:高电平)
        P3WKUE |= 0x00;                        //设置P3口中断唤醒省电模式
}
触发后会一直打应信息

ercircle 发表于 2025-8-15 16:10:32

limddfcl 发表于 2025-8-15 16:04
void Port3_Isr (void) interrupt 40
{
        printf("test \r\n");


1.C251没装就不用管

2.要点回复对方才能收到消息
3.参考手册例程处理IO中断,要清理标识位直接赋0

页: [1]
查看完整版本: 8H2K12U 设置IO中断后提示编译错误 帮忙分析以下