【单片机笔记】51内核的中断及中断向量

本文详细介绍了51单片机的中断源,包括外部中断、定时器中断和串口中断,探讨了中断向量、优先级设置及using关键字的作用。通过实际案例,解析了如何正确配置中断以避免潜在的BUG。

51内核的最基础的中断源请求有外部中断、定时器中断和串口中断,这也是学习和开发者最长用的。当然还有其他的中断源,比如ADC、SPI、PWM等。以外部中断0为例,在编程中常使用的方式为: 
void INT0()interrupt 0 using 1 

…… 

在这里特别做上笔记:其中前面的void INT0() 只是代表一个普通没有形参的函数而已,函数名写成什么都是可以的,这个到不重要。那么后面的就一个一个词的扣把: 
其中 interrupt n 组成一组,n用来指明中断号,在函数后使用了interrupt关键字后,就会自动的生成中断向量,51内核中断号如下图,这是我今天查的正在使用的MCU: 


例如:
1
interrupt 1 指明是定时器中断0; 
interrupt 2 指明是外部中断1; 
interrupt 3 指明是定时器中断1 
。。。

对于51内核的MCU,不同厂家及不同型号的内部资源会有所不同,上图是我正在开发的一款中颖SH88F516单片机,由上图可见内部资源还算可以,能够满足一般的产品。后面的using n 指的是使用第n组寄存器。这个之前我在使用的过程中往往忽略了这个,也没有出现什么问题。但是今天注意到这个问题,查完资料后用上发现效果还不如不用,很有肯能是没有把这个知识用好的原因把。对比之后给我的感觉是在使用C语言写程序时,能不用就不用吧。查资料解释说假如在中断函数中使用了using n,中断不再保存R0-R7的值,这也就意味着假如一个高优先级的中断及一个低优先级的中断同时使用了using n,而这个n恰恰相等,那就等着哭把,因为这个BUG还真不是那么好找出来的(今天我就遇到了这个问题)。 
其次就是中断优先级的问题了,如图上面的中断表,在右侧第二栏标的很清楚,除了复位之外,就数外部中断0优先级最高了,依次往下排列,那么问题来了,今天刚好就碰到了需要串口0的优先级比定时器0的优先级高。没办法,只好接着啃数据手册,还好这寄存器不多,一会就查到了下表和相关的描述: 


所以按照描述修改下优先级就可以达到目的了。 
总结:用到回过头来用到51的中断,发现有些东西在之前学习的时候并没有太在意,导致现在在开发产品上使用的时候不清楚用途。因为工作跟学习性质是不一样的,作为开发者的角度来说,质量往往是第一要求。同时会接触到很多新鲜的事物和技术,但是话又说回来了,最基本的知识还是需要打牢。要学的东西太多了!记不住,怎么办?想个办法记住它,比如写该笔记。知识很基础,但是我想以后很难再忘记! 
--------------------- 
作者:沉默的小宇宙 
来源:优快云 
原文:https://blog.youkuaiyun.com/qq997758497/article/details/77389359 
版权声明:本文为博主原创文章,转载请附上博文链接!

### 中断向量表的定义、作用及实现方式 #### ### 1. 中断向量表的定义 中断向量表是一种特殊的内存结构,由一系列地址组成,每个地址对应一个特定的中断源或异常类型。当处理器检测到某一类型的中断或异常时,会根据其编号访问中断向量表中对应的条目,并跳转到该条目所指向的服务例程(Interrupt Service Routine, ISR 或 Exception Service Routine, ESR)[^3]。 对于现代嵌入式系统而言,中断向量表通常是一个 WORD 数组(32 位整数数组),其中每个元素存储着相应服务例程的入口地址。例如,在 Cortex-M 架构中,向量表的第一个元素总是堆栈指针初始值,而后续元素分别对应复位、未定义指令、硬故障等不同类型的异常和服务例程[^3]。 --- #### ### 2. 中断向量表的作用 中断向量表的主要作用在于建立中断/异常与其处理逻辑之间的映射关系,从而使得 CPU 可以快速定位并调用正确的服务例程。以下是它的几个核心功能: - **快速响应**:通过预先配置好的向量表,CPU 不需要额外的时间来解析复杂的分支条件,而是可以直接跳转到目标地址。 - **统一管理**:所有中断和异常都被集中在一个地方进行管理和分发,便于维护和扩展。 - **支持动态调整**:某些架构允许在运行期间修改向量表的位置或内容,这为实现高级特性提供了便利,例如多任务调度中的上下文切换或者热插拔设备的支持[^4]。 --- #### ### 3. 中断向量表的实现方式 根据不同平台的设计理念和技术特点,中断向量表的具体实现方法有所差异。下面列举了几种常见的方式及其应用场景: ##### ###### (1)固定位置的向量表 许多微控制器会在复位后默认将向量表放置在 ROM 的起始地址(如 `0x0000_0000`)。这种做法的优点是简单可靠,缺点是没有灵活性。如果需要更改向量表的内容,则必须重新烧录固件[^3]。 示例代码如下: ```c // 假设向量表位于 Flash 地址 0x08000000 开始的地方 __attribute__((section(".isr_vector"))) const void (*const g_pfnVectors[])(void) = { (void (*)(void))(&__StackTop), // 初始堆栈指针 Reset_Handler, // 复位处理函数 NMI_Handler, // 非屏蔽中断处理函数 HardFault_Handler // 硬错误处理函数 }; ``` ##### ###### (2)可重定位的向量表 为了提高系统的适应性和效率,一些高性能 MCU 提供了向量表重定位的功能。这意味着可以通过写入特定寄存器(如 NVIC 的 VECTTAB 寄存器)来改变向量表的实际存放位置。例如,可以将其迁移到 SRAM 中以便于实时更新。 以下是一段用于将向量表复制到 RAM 并启用的新位置的 C 代码片段: ```c #define YTD_APP1_BASE_ADDR 0x08000000UL volatile uint32_t *RAM_VECTOR_TABLE = (uint32_t *)0x20000000; for(uint32_t i = 0; i < VECTOR_TABLE_SIZE / sizeof(uint32_t); i++) { RAM_VECTOR_TABLE[i] = *(uint32_t *)(YTD_APP1_BASE_ADDR + i * sizeof(uint32_t)); } SCB->VTOR = (uint32_t)RAM_VECTOR_TABLE; ``` 此处的关键点在于 SCB->VTOR 的赋值操作,它告诉内核新的向量表基址在哪里[^2]。 ##### ###### (3)基于优先级的选择机制 部分高端芯片还引入了多层次的优先级判断策略,确保重要性更高的事件能够得到及时处置。例如 AURIX TRICORE 使用 PIPN(Pending Interrupt Priority Number)字段辅助定位恰当的服务路径[^1]。 --- #### ### 结论 综上所述,中断向量表不仅是连接硬件资源与软件算法的重要桥梁,也是保障系统稳定运转不可或缺的一部分。无论是静态还是动态布局方案都有各自的优劣之处,应视具体需求加以选用。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值