科威PLC芯片组开发实例(六)
[font=宋体]上讲驱动语句解释:[/font][font=Times New Roman] [/font]
[font=宋体]在上面一讲,笔者给出了一段基本用户驱动语句段的代码,下面是详细解释它们的时候了。[/font]
[font=Times New Roman] [/font]
[font=Times New Roman]1.
[/font][font=宋体]第[/font][font=Times New Roman]1~4[/font][font=宋体]句:是将[/font][font=Times New Roman]3[/font][font=宋体]个头文件和[/font][font=Times New Roman]1[/font][font=宋体]个库文件添加到你的驱动工程项目中,这个就不在解释了。[/font]
[font=Times New Roman] [/font]
[font=Times New Roman]2.
[/font][font=宋体]第[/font][font=Times New Roman]5~24[/font][font=宋体]句:是将[/font][font=Times New Roman]F040[/font][font=宋体]的中断跳转重定义,查阅[/font][font=Times New Roman]F040[/font][font=宋体]的说明书我们可以看到,[/font][font=Times New Roman]0X0003H[/font][font=宋体]是外部中断[/font][font=Times New Roman]0[/font][font=宋体]的代码起始地址,在内核中,将外部中断[/font][font=Times New Roman]0[/font][font=宋体]的起始代码重新定义到[/font][font=Times New Roman]0E003H[/font][font=宋体]开始了。这里就产生了[/font][font=Times New Roman]3[/font][font=宋体]个问题:[/font]
[font=宋体]①
[/font][font=宋体]为什么要将中断的起始代码地址重定义?[/font]
[font=宋体]答:这个是为了方便代码管理,前面笔者曾经提到过,驱动下载到内核里,是存放在一[/font]
[font=宋体]块相应的地址空间由内核调用的。这个地址你现在可以看到,是从[/font][font=Times New Roman]0XE000H[/font][font=宋体]开始的,由于用户中断也属用户驱动的一部分,所以,它的这部分代码也必须保存到[/font][font=Times New Roman]0XE000H[/font][font=宋体]以后的一个地址段内,而默认的中断起始代码从哪里开始呢?以外部中断[/font][font=Times New Roman]0[/font][font=宋体]为例,你可以从说明书上看到,它的起始地址是[/font][font=Times New Roman]0X0003H[/font][font=宋体],这样用户驱动流程代码和用户驱动中断代码就被分成了[/font][font=Times New Roman]2[/font][font=宋体]个地址段,给内核的管理造成了麻烦。所以我们必须要进行中断代码地址重定义的工作。[/font]
[font=宋体]②
[/font][font=宋体]如何实现中断的起始代码地址重定义?[/font]
[font=宋体]答:还是以外部中断[/font][font=Times New Roman]0[/font][font=宋体]为例,内核在这里直接用了一个“[/font][font=Times New Roman]LJMP
0XE003H[/font][font=宋体]”即完成了地址重定义的工作,是不是很简单?[/font]
[font=宋体]③
[/font][font=宋体]科威[/font][font=Times New Roman]PLC[/font][font=宋体]芯片组还有其他的中断重定义了吗?我可以用它们吗?[/font]
[font=宋体]答:我们只能够用到上面代码给出的这些中断,还有的中断比如[/font][font=Times New Roman]T0[/font][font=宋体],[/font][font=Times New Roman]T1[/font][font=宋体]等中断已被内核占用,我们编写用户驱动就无缘使用它们啦![/font]
[font=Times New Roman] [/font]
[font=Times New Roman]3.
[/font][font=宋体]第[/font][font=Times New Roman]18[/font][font=宋体]句:[b]用户[/b][/font][b][font=Times New Roman]I/O[/font][/b][b][font=宋体]口配置程序[/font][/b][font=宋体]:根据设计的输入输出功能配置相应的端口[/font][font=Times New Roman]([/font][font=宋体]推挽或者漏级[/font][font=Times New Roman])[/font][font=宋体],用户不可配置的[/font][font=Times New Roman]I/O[/font][font=宋体]口资源为[/font][font=Times New Roman]P4.4[/font][font=宋体]、[/font][font=Times New Roman]P4.5[/font][font=宋体]、[/font][font=Times New Roman]P4.6[/font][font=宋体]、[/font][font=Times New Roman]P4.7[/font][font=宋体]、[/font][font=Times New Roman]P5[/font][font=宋体]、[/font][font=Times New Roman]P6[/font][font=宋体]、[/font][font=Times New Roman]P7[/font][font=宋体]及[/font][font=Times New Roman]UART0[/font][font=宋体]。理由还是那句话:内核已占用[/font][font=Times New Roman]…[/font][font=宋体]此段程序会在内核重新上电后调用一次。[/font]
[font=Times New Roman] [/font]
[font=Times New Roman]4.
[/font][font=宋体]第[/font][font=Times New Roman]19[/font][font=宋体]句:[b]用户上电初始化程序[/b]:用户嵌入程序中用到的输入输出变量,中间变量,指针变量,位变量等在重新上电后必需进行初始化处理,此段程序在内核重新上电后调用一次。[/font]
[font=Times New Roman] [/font]
[font=Times New Roman]5.
[/font][font=宋体]第[/font][font=Times New Roman]20[/font][font=宋体]句:[b]用户设置初始化程序:[/b]内核重新上电后进入梯型图下载状态或内核从梯型图运型状态进入梯型图下载状态时调用此程序一次。[/font]
[font=Times New Roman] [/font]
[font=Times New Roman]6.
[/font][font=宋体]第[/font][font=Times New Roman]21[/font][font=宋体]句:[b]用户运行初始化程序:[/b]内核重新上电后第一次运行梯型图或内核从下载梯型图状态进入梯型图运行状态时调用此程序一次。这个子程序大家可以看到,与上面一个的流程是相反的。[/font]
[font=Times New Roman] [/font]
[font=Times New Roman]7.
[/font][font=宋体]第[/font][font=Times New Roman]22[/font][font=宋体]句:[b]用户演算周期扫描程序:[/b]所有梯形图执行完后,即调用该程序,调用周期为梯型图演算周期,一般的数据处理、开关量输入[/font][font=Times New Roman]/[/font][font=宋体]输出的刷新及代码执行时间较长的程序均放在此程序中执行。[/font]
[font=Times New Roman] [/font]
[font=Times New Roman]8.
[/font][font=宋体]第[/font][font=Times New Roman]23[/font][font=宋体]句:[b]用户每步执行程序:[/b]梯形图每执行一步,即调用此程序一次。需要快速执行的事件可在此程序或用户中断程序中完成,内核周期性地调用此程序,周期小于[/font][font=Times New Roman]50US[/font][font=宋体]。[/font]
[font=Times New Roman]50US[/font][font=宋体]有多少个指令周期呢?我们可以算算:设[/font][font=Times New Roman]1[/font][font=宋体]个指令周期的执行时间为[/font][font=Times New Roman]t[/font][font=宋体],系统时钟频率为[/font][font=Times New Roman]f[/font][font=宋体],那么[/font][font=Times New Roman]1S=1000000US[/font][font=宋体],[/font][font=Times New Roman] f = 24.5MHZ[/font][font=宋体],那么[/font][font=Times New Roman]t = 1000000/24500000 = 0.04US[/font][font=宋体],也就是说[/font][font=Times New Roman]50US[/font][font=宋体]可以执行的指令周期数为[/font][font=Times New Roman]50/0.04 = 1250[/font][font=宋体]个。这里有两点需要说明一下,一条语句所占的指令周期并不一定只有一个,比如[/font][font=Times New Roman]NOP[/font][font=宋体]指令所占的指令周期为[/font][font=Times New Roman]1[/font][font=宋体],但是[/font][font=Times New Roman]CJNE[/font][font=宋体]指令就不止[/font][font=Times New Roman]1[/font][font=宋体]个了,具体占了几个笔者不记得了[/font][font=Times New Roman]~[/font][font=宋体],这个可以在说明书里面查到。另外一点是假设你编写的总代码折合成指令周期数是[/font][font=Times New Roman]2000[/font][font=宋体]个,那是不是就不能满足要求了呢?答案是不一定,只要你最长的一次执行过程所花费的指令周期数不超过[/font][font=Times New Roman]1250[/font][font=宋体]个就行了,因为往往在程序里会有条件跳转的代码。举个例子吧,假设你的[/font][font=Times New Roman]STEP[/font][font=宋体]里面有[/font][font=Times New Roman]2[/font][font=宋体]个条件执行过程[/font][font=Times New Roman]A[/font][font=宋体]和[/font][font=Times New Roman]B[/font][font=宋体],[/font][font=Times New Roman]A[/font][font=宋体]条件的执行过程一共有[/font][font=Times New Roman]1100[/font][font=宋体]个指令周期,[/font][font=Times New Roman]B[/font][font=宋体]条件有[/font][font=Times New Roman]900[/font][font=宋体]个。虽然[/font][font=Times New Roman]A+B[/font][font=宋体]一共有[/font][font=Times New Roman]2000[/font][font=宋体]个超过了[/font][font=Times New Roman]1250[/font][font=宋体]个,但是因为是条件跳转,程序是不可能同时执行[/font][font=Times New Roman]A[/font][font=宋体]和[/font][font=Times New Roman]B[/font][font=宋体]的。所以算起来你的程序最长的指令周期数是[/font][font=Times New Roman]1100[/font][font=宋体]个而不是[/font][font=Times New Roman]2000[/font][font=宋体]个!哎呀,估计越讲越难让人理解了[/font][font=Times New Roman]…[/font][font=宋体]打住,往下走吧,毕竟,计算每条语句所占用的系统时间并将其代码优化都是些达人们,我们还是先看简单的。[/font]
[font=Times New Roman] [/font]
[font=Times New Roman]9.
[/font][font=宋体]第[/font][font=Times New Roman]24[/font][font=宋体]句:[b]用户[/b][/font][b][font=Times New Roman]2.5mS[/font][/b][b][font=宋体]定时运行程序:[/font][/b][font=宋体]需要定时采样的流程可放在此程序中完成,但该段程序代码执行时间必须小于[/font][font=Times New Roman]50 US[/font][font=宋体]。数据处理程序不宜放在此段程序中执行。注意这里是内核给提供的软中断,如果你的驱动里面没有什么高级的中断并频繁发生,那么它就是[/font][font=Times New Roman]2.5ms[/font][font=宋体]调用一次,很准!同时你得注意,它的返回语句不是“[/font][font=Times New Roman]RETI[/font][font=宋体]”而是“[/font][font=Times New Roman]RET[/font][font=宋体]”,为什么?因为它是“软”的嘛,是内核给定义的,又不是[/font][font=Times New Roman]F040[/font][font=宋体]的规范中断,呵呵![/font]
[font=Times New Roman] [/font]
[font=Times New Roman]10.
[/font][font=宋体]第[/font][font=Times New Roman]25[/font][font=宋体]句:用户驱动程序编程起始位置,从这里往下就是你自由发挥的空间了哦[/font][font=Times New Roman]~[/font]
[font=Times New Roman] [/font]
[font=Times New Roman]11.
[/font][font=宋体]第[/font][font=Times New Roman]26[/font][font=宋体]句:别忘了给你的驱动程序加个完美的“句号”。[/font]
[font=Times New Roman] [/font]
[font=宋体]看到这里,你应该对科威[/font][font=Times New Roman]PLC[/font][font=宋体]芯片组的开发有了一定的了解了吧。?完全没了解??看来笔者的水平差了点,就请将就多看几遍吧[/font][font=Times New Roman]…-_-![/font][font=宋体]不是有一句话就作“书读百遍,其意自现”的么。有问题或不懂的给回下贴嘛,笔者看到了一定给你解答[/font][font=Times New Roman]^-^~![/font]
[font=Times New Roman] [/font]
[font=宋体]在下一讲里面,就要开始实战了,笔者将基于科威公司出产的[/font][font=Times New Roman]EASY-M0806R[/font][font=宋体]这款[/font][font=Times New Roman]PLC[/font][font=宋体]重新编写[/font][font=Times New Roman]IO[/font][font=宋体]驱动程序,手头上有这款[/font][font=Times New Roman]PLC[/font][font=宋体]的朋友也可以跟着做哦[/font][font=Times New Roman]~[/font][font=宋体]![/font]
[font=Times New Roman] [/font]
[font=宋体]本帖首发中国工控网科威[/font][font=Times New Roman]PLC[/font][font=宋体]论坛,转载请声明![/font]
[font=Times New Roman] [font=宋体][size=10.5pt]科威[/size][/font][size=10.5pt]PLC[/size][font=宋体][size=10.5pt]芯片组开发实例[/size][/font][size=10.5pt]([/size][font=宋体][size=10.5pt]六[/size][/font][size=10.5pt])[/size][/font]
页:
[1]