求教下,SDCC\IAR下32号以上中断跳转语法?|已测试,不需要
本帖最后由 ercircle 于 2024-12-3 20:43 编辑如题,Keil C51下isr.asm里中断跳转语法貌似不能直接用于sdcc\iar。
有木有坛友已经搞过了请指点下谢谢!
结论:不需要跳转,附Keil C251/Keil C51/SDCC/IAR RTC测试工程
昨天拜读了你的普中移植Ai8051U代码后,我对这个Keil C51下isr.asm里中断跳转语法也有疑问
这几句是怎么发挥作用的呢?
```
CSEG AT 01F3H
LJMP 00C3H
CSEG AT 018BH
LJMP 006BH
END
```
方便讲解一下吗
VCC 发表于 2024-12-3 15:35
昨天拜读了你的普中移植Ai8051U代码后,我对这个Keil C51下isr.asm里中断跳转语法也有疑问
这几句是怎 ...
我也不懂汇编语法,按我的理解,使能中断后,由MCU触发中断进入01F3H这个原始中断地址,然后这段汇编跳转地址到00C3H这里,就实现了自定义中断号映射。 论坛里关于这个讨论挺多的可以看看。但是sdcc和iar的就比较冷门了
有关使用超过31号中断问题的解决方法2的疑问 sdcc的搜到了,不需要汇编跳转。。。
ercircle 发表于 2024-12-3 15:49
论坛里关于这个讨论挺多的可以看看。但是sdcc和iar的就比较冷门了
有关使用超过31号中断问题的解决方法2的 ...
感觉那个大佬想问的是方法3的东西,,想跳转任意地址.. ercircle 发表于 2024-12-3 15:50
sdcc的搜到了,不需要汇编跳转。。。
同理IAR应该也没32的限制,待测试 VCC 发表于 2024-12-3 15:35
昨天拜读了你的普中移植Ai8051U代码后,我对这个Keil C51下isr.asm里中断跳转语法也有疑问
这几句是怎 ...
CSEG:Code Segment,插入代码段
AT:at,定位绝对地址,类似C语言的 _at_
LJMP :Long Jump,长跳转,长度3字节,机器码02H后面跟2字节操作数,是地址
END:结束
代码:
CSEG AT 01F3H
LJMP 00C3H
CSEG AT 018BH
LJMP 006BH
END
编译后可以看到机器码中指定位置正确插入了2个LJMP
根据数据手册,中断向量01F3H处是I2S中断
当触发I2S中断后,单片机中断系统硬件会让程序计数器PC为01F3H,跳转到中断向量处执行程序
因为I2S中断向量处是LJMP 00C3H(02 00 C3),此时软件会让程序计数器PC为00C3H,跳转到00C3H处
根据数据手册,00C3H是I2C的中断向量
但此时00C3H处没有中断函数入口地址
根据数据手册中的指令集部分,BINARY模式的FFH指令是MOV R7,A,SOURCE的FFH没有指令
所以单片机会执行错误的操作,导致程序跑飞、死机、复位等问题
这就是为什么打开了中断就必须要有中断函数的原因,初学者经常遇到这个问题!
中断函数注意查询次序(中断向量)填I2C中断的,这决定编译器在哪里插入I2S中断函数的入口地址,必须是之前跳转过来的地址
此时机器码中就可以看到这个地址处出现了一个LJMP指令,地址为0010H
到这个地址看看程序要干什么了
BINARY模式和SOURCE模式都是RETI,中断返回
因为中断函数是空的,空的中断函数,也会正确中断返回
这就是为什么打开了中断就必须要有中断函数的原因,初学者经常遇到这个问题!
这就实现了一个中断借用
018BH的DMA_SPI中断同理,就不赘述了
说完了中断借用再说下中断共用的问题
那I2C中断被占用了怎么办?
此时如果I2C中断也打开了,发生I2C中断时,硬件也会往这个地址跳转,只不过比I2S中断少跳转了一次,会进入相同的中断函数,那么在同一个中断函数中判断中断请求标志位就可以判断发生了哪个中断,类似UART1的RI和TI,但不建议这样做,还是使用保留中断或未使用的中断比较好
如果设置了不同的优先级,会形成中断嵌套,通过同一个RETI中断返回,CPU会在响应中断时暂存PC,中断返回时会从之前响应中断时暂存的PC处继续执行,不会出现跑飞问题,但存在函数重入问题,注意共用中断时不要在中断函数内执行不可重入的操作(一般是多个if判断中断请求标志位,也没什么不可重入的操作)
注意响应中断时自动清除中断请求标志位的中断不可以中断共用,因为进了中断后不知道是谁请求的
多个中断可以共用USER_VECTOR
DebugLab 发表于 2024-12-3 17:39
CSEG:Code Segment,插入代码段
AT:at,定位绝对地址,类似C语言的 _at_
感谢!非常详细和清晰的讲解!!!
我还有一个疑问。
为什么不在I2S的中断向量里,像正常Keil C51一样,LJMP到另外一个专门编写的I2S_ISR函数里,而是要跳转到I2C这里呢。是必须如此吗?为什么会这样呢 VCC 发表于 2024-12-3 17:54
感谢!非常详细和清晰的讲解!!!
我还有一个疑问。
I2C这个00C3H是可以修改的,一般借用中断13
Keil不支持中断31以上的中断
使用中断号扩展插件,可以直接使用中断31以上的中断,不需要借用
页:
[1]
2