请问一下 关于51单片机的中断
我希望运行完中断函数后,不跳回主函数正在执行的那段,而是从主函数另一个指定位置开始执行,怎么做?
比如:
- void main()
- {
- while(1) //主函数的大循环内,有很多行代码,这里先忽略
- {
- .... //不知程序运行到什么地方,这时外部中断被触发了
- ...... //假设这里是中断点---被压入堆栈
-
- }
- }
- void init() interrupt 0
- {
- .....
- ...... //我希望程序运行完成中断函数后,不返回主函数的大循环内,而是跳到while(1)的上一条语句
-
- }
这里顺便提一下,给需要的朋友。在我的代码基础上进行扩展,可以实现51单片机运行多任务。
简但来说,就是定义几个像代码中TargetAddress这样的变量,组成一个数组,成为任务列表,用来保存每个任务的运行地址。如果要创建新任务,就把新任务的地址赋给一个空白的TargetAddress成员。然后把实现跳转的代码放到定时器中断里,由定时器负责任务之间的切换。定时器的周期可以是1ms或者10ms等。进入定时器中断时保存当前任务的地址到它对应的TargetAddress变量中,还有现场环境,然后用算法选择下一个可运行的任务,恢复这个任务的环境,再在中断返回后跳转至这个任务的地址。周而复始,任务之间不断切换。
最后不要忘记任务退出后的清理工作。
我在这里只是抛砖引玉,有兴趣在51上完多任务的可以自己琢磨。
把你要跳的那条语句的地址替换掉堆栈里保存的PC值即可
好像只有汇编可以吧? C语言怎么写?
这个还没有听说过c语言可以,占楼学习,等待结果……
可以尝试使用break语句结束while循环,,,,,或者用continue语句结束本次循环,重新判断循环条件
回小编,C无法办到,但可以采用C和汇编混合编程的方式。
我已针对你的问题做了一个测试程序,开发环境为Keil4,如果打不开,请直接把src文件夹下的main.c和sub.asm添加到你能打开的空工程中。
只有这两个源文件,main.c相当于你目前在写的。对于C无法办到的事情,用汇编写在sub.asm中,里面有两个函数。有详细的注释。
附件暂时上传不了,我稍后再补上
补上附件。
算了,13k的zip包死活上传不了,放百度网盘了http://pan.baidu.com/s/1kTu6kcf示例工程,无密码
因为汇编太久没用,基本忘光了,我试了一次,能用,我最近再挑一些程序来试
请问下,如果在中断函数尾,直接用goto 指令,效果会不会一样?
如果 WHILE(1) 前没语句,可以在中断程序最后用软件复位的方法。
C语言的goto只能在一个函数内跳转,原因很简单,不同的函数的栈不一样,如果从一个函数跳到另一个函数,会导致堆栈不对称,而使程序跑飞。
举个简单的例子来演示一下,加入函数func1使用了5Bytes的栈空间,那么当退出func1时就要释放5bytes的栈空间,函数func2使用4bytes的栈空间。这时假设你调用了func2,消耗了4bytes的栈空间,原则上说你退出函数前要释放这4bytes,然而你用goto直接从func2跳到func1中,程序就不会从func2退出,而是从func1退出,释放了5bytes的栈,这样栈的对称性被破坏了不说,连调用者的现场也被破坏了(原本是保护a寄存器的值,最后却还给了b寄存器)。
所以c不允许这样的非法跳转。汇编编译器则不会限制你这么做,因为汇编里函数的概念没C这么强烈,但随意的在函数间跳转除了会有栈方面的问题,寄存器方面也有问题。
以前不知道这个这么强大的网站啊!好好学
学习学习中
解决问题没有,我也想要这样的代码
的确可以这么玩,中断嵌套的感觉,发挥了ASM灵活访问寄存器的有点
小编在用定时器时,进入中断函数需不需要判断TF0==1? 或者例如
void timer_0()interrupt 1
{
count ++;
//重装初值
TH0=(2^16-50000)/2^8;
TL0=(2^16-50000)%2^8;
}这样的 要怎么用呢这种中断函数的使用方法
学习了
TF0不需要检测
TH0和TL0也不需要重装初值