写中断服务子程序子程序应注意什么?

S7-200 PLC子程序和中断程序
添加时间:
来源: | 阅读量:51
提示: 西门子PLC的编程强调结构化编程,因此会经常使用到子程序和中断程序。 在S7-200 PLC中,有4种程序:OS(系统程序)、OB1(主程序)、SBR(子程序)和INT(中断程序)。CPU在运行时,当满足调用SBR程序状态时,会暂停现在执行的用户程序进入执行SBR子程序。执行完子程序后,再返回原来的地方继续执行原来的程序。执行中断程
&&& 西门子PLC的编程强调结构化编程,因此会经常使用到子程序和中断程序。
&&& 在S7-200 PLC中,有4种程序:OS(系统程序)、OB1(主程序)、SBR(子程序)和INT(中断程序)。CPU在运行时,当满足调用SBR程序状态时,会暂停现在执行的用户程序进入执行SBR子程序。执行完子程序后,再返回原来的地方继续执行原来的程序。执行中断程序,当声明允许开中断,有中断源产生,会暂停现在执行的用户程序(包括OB1、SBR和级别较低的INT),进入声明与该中断源有联系的INT中断程序,中断程序执行完毕,自动返回到原来的地方,继续执行原来的程序。子程序可以从主程序、另一个SBR或INT中调用,不能从子程序本身调用。S7-200 CPU总共有64个子程序(CPU226 XM有128个子程序),可以在子程序中调用另一个子程序,最大嵌套深度为8级,但在INT程序中不能嵌套子程序。使用子程序能加快CPU的扫描速度。中断程序主要是为特殊内部或外部事物提供快速反应而设置的,中断程序中不可以使用DISI、ENI、HDEF、SCR、END指令。一个程序中总共可以有128个子程序,在任何时刻只能执行一个用户中断程序。
(责任编辑: 佚名 )
本文关键字:
免责声明:本文章仅代表作者个人观点,与艾特贸易网无关。本站大部分技术资料均为原创文章,文章仅作为读者参考使用,请自行核实相关内容,如若转载请注明来源:
(1)墙挂式***。由于变频器本...
如图6-21所示,按钮SB1和SB2...
KY - 250型牙轮钻机(图3-6)...
晚上九时许,劳动一天的村民...
新闻热点排行> 问题详情
中断处理和子程序调用都需要压栈以保护现场,中断处理一定会保存而子程序调用不需要保存其内容的
悬赏:0&***豆
提问人:匿名网友
发布时间:
中断处理和子程序调用都需要压栈以保护现场,中断处理一定会保存而子程序调用不需要保存其内容的是A.程序计数器B.程序状态字寄存器C.通用数据寄存器D.通用地址寄存器请帮忙给出正确***和分析,谢谢!
您可能感兴趣的试题
1下列关于虚拟存储器的叙述中,正确的是A.虚拟存储只能基于连续分配技术B.虚拟存储容量只受外存容量的限制C.虚拟存储只能基于非连续分配技术D.虚拟存储容量只受内存容量的限制2操作系的 I/O 子系统通常由四个层次组成,每一层明确定义了与邻近层次的接口,其合理的层次组织排列顺序 是A.用户级 I/O 软件、设备无关软件、设备驱动程序、中断处理程序B.用户级 I/O 软件、设备无关软件、中断处理程序、设备驱动程序C.用户级 I/O 软件、设备驱动程序、设备无关软件、中断处理程序D.用户级 I/O 软件、中断处理程序、设备无关软件、设备驱动程序
我有更好的***
论文写作技巧
相关考试课程
请先输入下方的验证码查看最佳***
图形验证:
验证码提交中……问题已关闭
代为完成的个人任务
提问需要满足:其他人可能遇到相似问题,或问题的解决方法对其他人有所助益。如果通过其他方式解决遇到困难,欢迎提问并说明你的求知过程。
1、写一个中断服务程序,替换相应的中断调用;
2、写int21的1,2,9,A号功能子程序?
汇编语言题目 最好给出完成代码
你再这样我告诉冯阿姨了
少侠不要病急乱投医,估计是邀请了一堆人碰运气
在知乎潜水了这么长时间怎么可能有人认识我。。。。
恰好我也在学汇编语言@( ̄- ̄)@
题主问的作业题好像是汇编语言书上的原题
具体细节我也忘了,有时间再补充
已有帐号?
无法登录?
社交帐号登录单片机调用中断服务子程序和调用子程序的区别是什么?
单片机调用中断服务子程序和调用子程序的区别是什么?
09-11-01 &
基于51单片机中断跳出指令“RETI”浅议&   最近在基于51单片机编程的过程中出现了个很奇怪的问题“程序执行中在寄存器EA=1,ET0=1,TR0=1条件下,单TF0=1时并没有执行中断”。在有过单片机中断编程经历者都知道当EA=1,ET0=1的条件下,满足TF0=1时,如果在此期间没有更高优先级的中断执行的情况下定时器中断0必定会产生中断响应。而在我所编写的程序中仅使用了定时器中断0,一个中断也就谈不上存在优先级问题。经过我对自己程序的检查并对各教材中断程序对比发现我的程序中的一个问题:由于中断的不可控性决定其跳出中断返回主程序的不确定,而由于程序需要中断跳出后能跳到指定的地址。为了解决这个问题我在中断结束的地方直接用了无条件跳转指令“LJMPADR16”其中ADR16是我想在中断结束后程序所运行的地址,而没有经过指令“RETI”。问题找到了这就意味着我的程序和其他程序不同的地方就是没有执行“RETI”而直接跳出。/p&   为了解决问题所在我查阅了很多单片机方面的资料,教材。几乎所有的教材对指令“RETI”的作用千篇一律都是:“中断程序完成后,一定要执行一条RETI指令,执行这条指令后,CPU将会把堆栈中保存着的地址取出,送回PC,那么程序就会从主程序的中断处继续往下执行了。”如果“RETI”的作用仅仅在于“把堆栈中保存着的地址取出送回PC”;那么我用指令“POPDPH”和“POPDPL”两条指令取代其做用不就可以达到同样的推出地址的效果么?这样可以解决由于只有进堆栈指令(硬件自动生成)没有出堆栈所导致的堆栈溢出错误,但是并不能解决文章开始所提到的“进不了中断”问题。这让我更加相信书上所介绍的关于指令“RETI”作用并不完全。经过查阅各种资料文献,我发现了个以往在介绍单片机硬件,以及寄存器上教材,老师,没有提及的“‘优先级生效’触发器“的概念。资料指出“根据8051的结构特点,其中断系统中含有两个不可寻址的“优先级生效”触发器。一个用于指出CPU是否正在执行高优先级的中断服务程序,这个触发器为1时,系统将屏蔽所有的中断请求;另一个则指出CPU是否正在执行低优先级中断服务程序,该触发器为1时,将阻止除高优先级以外的一切中断请求。由此可见,若要响应同级甚至是低级中断请求,必须使得该“优先级生效”触发器清零。但该触发器又是不可寻址的,所以无法用软件直接清零。”问题是不是在这里呢?而“优先级生效”触发器清零过程是怎样执行的呢?是在硬件自动执行的那么是在什么时候执行的呢?带着问题我去解决问题。假设我可以将程序满足跳出中断后跳到自己原来指定地址“ADR16”又满足执行指令“RETI”。经过反复思考我用“DEC SP”;“DEC SP”;“MOVDPTR,#ADR16”;“PUSHDPL”;“PUSHDPL”“PUSHDPH”四条指令代替,问题得到了解决。/p&   总结:中断指令“RETI”做为中断跳出指令除了将堆栈中保存着的地址取出,送回PC;使程序从主程序的中断处继续往下执行。的作用外还有将“优先级生效”触发器清零。自己做的程序也是出现了这个错误,由于对“优先级生效”触发器清零,导致第二次进不了中断(相当于同优先级申请)。/p&  后记:在解决这个问题时候我所用的知识是课本上的,而又不完全是课本上的。在这个过程中我用已学的知识解决了自己的问题,并进一步推出中断过程的一些新的知识,我认为新知识的学习有很大程度的要靠自己在已学过知识的基础上通过运用,总结,推导等过程获得新知识。着也是当代大学生运用知识,获取新知识的一种能力。/p
请登录后再发表评论!
在Linux操作系统下有3类主要的设备文件类型:块设备、字符设备和网络设备。这种分类方法可以将控制输入/输出设备的驱动程序与其他操作系统软件分离开来。 字符设备与块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般紧接着发生。块设备则不然,它利用一块系统内存作为缓冲区,若用户进程对设备的请求能满足用户的要求,就返回请求的数据;否则,就调用请求函数来进行实际的I/O操作。块设备主要是针对磁盘等慢速设备设计的,以免耗费过多的CPU时间用来等待。网络设备可以通过BSD套接口访问数据。 每个设备文件都有其文件属性(c/b),表示是字符设备还是块设备。另外每个文件都有2个设备号,第一个是主设备号,标识驱动程序;第二个是从设备号,标识使用同一个设备驱动程序的、不同的硬件设备。设备文件的主设备号必须与设备驱动程序在登记时申请的主设备号一致,否则用户进程将无法访问驱动程序。 系统调用时操作系统内核与应用程序之间的接口,设备驱动程序是操作系统内核与机器硬件之间的接口。设备驱动程序是内核的一部分,它完成以下功能: *对设备初始化和释放 *把数据从内核传送到硬件和从硬件读取数据 *读取应用程序传送给设备文件的数据和回送应用程序请求的数据 *检测和处理设备出现的错误 MTD(Memory Technology Device)设备是闪存芯片、小型闪存卡、记忆棒之类的设备,它们在嵌入式设备中的使用正在不断增加。MTD驱动程序是在Linux下专门为嵌入式环境开发的新的一类驱动程序。相对于常规块设备驱动程序,使用MTD驱动程序的优点在于他们能更好的支持、管理给予闪存设备,有基于扇区的擦除和读/写操作的更好的接口。 驱动程序结构 Linux的设备驱动程序可以分为3个主要组成部分: 1. 自动配置和初始化子程序,负责监测所要驱动的硬件设备是否存在和能否正常工作。如果该设备正常,则对这个设备及其相关的设备驱动程序需要的软件状态进行初始化。这部分驱动程序仅在初始化时被调用一次。 2. 服务于I/O请求的子程序,又称为驱动程序的上半部分。调用这部分程序是由于系统调用的结果。这部分程序在执行时,系统仍认为是与进行调用的进程属于同一个进程,只是由用户态变成了核心态,具有进行此系统调用的用户程序的运行环境,因而可以在其中调用sleep()等与进行运行环境有关的函数。 3. 中断服务子程序,又称为驱动程序的下半部分。在Linux系统中,并不是直接从中断向量表中调用设备驱动程序的中断服务子程序,而是由Linux系统来接收硬件中断,再由系统调用中断服务子程序。中断可以在任何一个进程运行时产生,因而在中断服务程序被调用时,不能依赖于任何进程的状态,也就不能调用任何与进程运行环境有关的函数。因为设备驱动程序一般支持同一类型的若干设备,所以一般在系统调用中断服务子程序时,都带有一个或多个参数,以唯一标识请求服务的设备。 在系统内部,I/O设备的存/取通过一组固定的入口点来进行,这组入口点是由每个设备的驱动程序提供的。具体到Linux系统,设备驱动程序所提供的这组入口点由一个文件操作结构来向系统进行说明。file_operation结构定义于linux/fs.***件中。 struct file_operation{int (*lseek)(struct inode *inode, struct file *filp, off_t off, int pos);int (*read)(struct inode *inode, struct file *filp, char *buf, int count);int (*write)(struct inode *inode, struct file *filp, const char *buf, int count);int (*readdir)(struct inode *inode, struct file *filp, struct dirent *dirent, int count);int (*select)(struct inode *inode, struct file *filp, int sel_type, select_table *wait);int (*ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned int arg);int (*mmap)(void);int (*open)(struct inode *inode, struct file *filp);int (*release)(struct inode *inode, struct file *filp);int (*fasync)(struct inode *inode, struct file *filp);}; file_operation结构中的成员几乎全部是函数指针,所以实质上就是函数跳转表。每个进程对设备的操作都会根据major、minor设备号,转换成对file_operation结构的访问。 常用的操作包括以下几种: *lseek, 移动文件指针的位置,只能用于可以随机存取的设备。 *read, 进行读操作,参数buf为存放读取结果的缓冲区,count为所要读取的数据长度。返回值为负表示读取操作发生错误;否则,返回实际读取的字节数。对于字符型,要求读取的字节数和返回的实际读取字节数都必须是inode-i_blksize的倍数。 *write, 进行写操作,与read类似 *readdir, 取得下一个目录入口点,只有与文件系统相关的设备程序才使用。 *select, 进行选择操作。如果驱动程序没有提供select入口,select操作会认为设备已经准备好进行任何I/O操作。 *ioctl, 进行读、写以外的其他操作,参数cmd为自定义的命令 *mmap, 用于把设备的内容映射到地址空间,一般只有块设备驱动程序使用 *open, 打开设备准备进行I/O操作。返回0表示打开成功,返回负数表示失败。如果驱动程序没有提供open入口,则只要/dev/driver文件存在就认为打开成功。 *release, 即close操作。 在用户自己的驱动程序中,首先要根据驱动程序的功能,完成file_operation结构中函数实现。不需要的函数接口可以直接在file_operation结构中初始化为NULL。file_operation变量会在驱动程序初始化时注册到系统内部。当操作系统对设备操作时,会调用驱动程序注册的file_operation结构中的函数指针。 Linux对中断的处理 在Linux系统里,对中断的处理是属于系统核心部分,因而如果设别与系统之间以中断方式进行数据交换,就必须把该设备的驱动程序作为系统核心的一部分。设备驱动程序通过调用request_irq函数来申请中断,通过free_irq来释放中断。它们被定义为: #include int request_irq(unsigned int irq, void (*handler)(int irq, void dev_id, struct pt_regs *regs),unsigned long flags,const char *device,void *dev_id);void free_irq(unsigned int irq, void *dev_id); 参数irq表示所要申请的硬件中断号;handler为向系统登记的中断处理子程序,中断产生时由系统来调用,调用时所带参数irq为中断号;dev_id为申请时告诉系统的设备标识;regs为中断发生时的寄存器内容;device为设备名,将会出现在/proc/interrupts文件里;flag是申请时的选项,它决定中断处理程序的一些特性,其中最重要的是中断处理程序是快速处理程序还是慢速处理程序。快速处理程序运行时,所有中断都被屏蔽,而慢速处理程序运行时,除了正在处理的中断外,其他中断都没有被屏蔽。在Linux系统中,中断可以被不同的中断处理程序共享。 作为系统核心的一部分,设备驱动程序在申请和释放内存时不是调用malloc和free,而代之以调用kmalloc和kfree,它们被定义为: #include void *kmalloc(unsigned int len, int priority);void kfree(void *obj); 参数len为希望申请的字节数;obj为要释放的内存指针;priority为分配内存操作的优先级,即在没有足够空闲内存时如何操作,一般用GFP_KERNEL。
请登录后再发表评论!
简单点讲就是子程序可以在程序中通过程序人为调用,什么时候调用都可以;而中断服务程序必须由相应的中断机构来执行,不能人为调用。
请登录后再发表评论!
中断服务子程序入口地址相对某一中断是固定的,调用子程序的偏移地址是随机的,基本过程差不多,返回时,中断服务子程序用的是RETI 调用子程序是RET调用中断服务子程序和调用子程序都会把当前偏移地址的下一地址压栈,但调用子程序的返回指令RET不影响标志位,RETI从中断程序返回,并会清除内部相应的中断状态寄存器。我说的是80C51的
请登录后再发表评论!
基于51单片机中断跳出指令“RETI”浅议&   最近在基于51单片机编程的过程中出现了个很奇怪的问题“程序执行中在寄存器EA=1,ET0=1,TR0=1条件下,单TF0=1时并没有执行中断”。在有过单片机中断编程经历者都知道当EA=1,ET0=1的条件下,满足TF0=1时,如果在此期间没有更高优先级的中断执行的情况下定时器中断0必定会产生中断响应。而在我所编写的程序中仅使用了定时器中断0,一个中断也就谈不上存在优先级问题。经过我对自己程序的检查并对各教材中断程序对比发现我的程序中的一个问题:由于中断的不可控性决定其跳出中断返回主程序的不确定,而由于程序需要中断跳出后能跳到指定的地址。为了解决这个问题我在中断结束的地方直接用了无条件跳转指令“LJMPADR16”其中ADR16是我想在中断结束后程序所运行的地址,而没有经过指令“RETI”。问题找到了这就意味着我的程序和其他程序不同的地方就是没有执行“RETI”而直接跳出。/p&   为了解决问题所在我查阅了很多单片机方面的资料,教材。几乎所有的教材对指令“RETI”的作用千篇一律都是:“中断程序完成后,一定要执行一条RETI指令,执行这条指令后,CPU将会把堆栈中保存着的地址取出,送回PC,那么程序就会从主程序的中断处继续往下执行了。”如果“RETI”的作用仅仅在于“把堆栈中保存着的地址取出送回PC”;那么我用指令“POPDPH”和“POPDPL”两条指令取代其做用不就可以达到同样的推出地址的效果么?这样可以解决由于只有进堆栈指令(硬件自动生成)没有出堆栈所导致的堆栈溢出错误,但是并不能解决文章开始所提到的“进不了中断”问题。这让我更加相信书上所介绍的关于指令“RETI”作用并不完全。经过查阅各种资料文献,我发现了个以往在介绍单片机硬件,以及寄存器上教材,老师,没有提及的“‘优先级生效’触发器“的概念。资料指出“根据8051的结构特点,其中断系统中含有两个不可寻址的“优先级生效”触发器。一个用于指出CPU是否正在执行高优先级的中断服务程序,这个触发器为1时,系统将屏蔽所有的中断请求;另一个则指出CPU是否正在执行低优先级中断服务程序,该触发器为1时,将阻止除高优先级以外的一切中断请求。由此可见,若要响应同级甚至是低级中断请求,必须使得该“优先级生效”触发器清零。但该触发器又是不可寻址的,所以无法用软件直接清零。”问题是不是在这里呢?而“优先级生效”触发器清零过程是怎样执行的呢?是在硬件自动执行的那么是在什么时候执行的呢?带着问题我去解决问题。假设我可以将程序满足跳出中断后跳到自己原来指定地址“ADR16”又满足执行指令“RETI”。经过反复思考我用“DEC SP”;“DEC SP”;“MOVDPTR,#ADR16”;“PUSHDPL”;“PUSHDPL”“PUSHDPH”四条指令代替,问题得到了解决。/p&   总结:中断指令“RETI”做为中断跳出指令除了将堆栈中保存着的地址取出,送回PC;使程序从主程序的中断处继续往下执行。的作用外还有将“优先级生效”触发器清零。自己做的程序也是出现了这个错误,由于对“优先级生效”触发器清零,导致第二次进不了中断(相当于同优先级申请)。/p&  后记:在解决这个问题时候我所用的知识是课本上的,而又不完全是课本上的。在这个过程中我用已学的知识解决了自己的问题,并进一步推出中断过程的一些新的知识,我认为新知识的学习有很大程度的要靠自己在已学过知识的基础上通过运用,总结,推导等过程获得新知识。着也是当代大学生运用知识,获取新知识的一种能力。/p
请登录后再发表评论!子程序应放在程序中的什么位置?中断子程序是如何调用的?_百度知道

参考资料

 

随机推荐