lyq_4652
級(jí)別: *
精華主題: * 篇
發(fā)帖數(shù)量: * 個(gè)
工控威望: * 點(diǎn)
下載積分: * 分
在線時(shí)間: (小時(shí))
注冊(cè)時(shí)間: *
最后登錄: *
查看lyq_4652的 主題 / 回貼
樓主  發(fā)表于: 2008-07-25 15:12
工欲善其事,必先磨其器。

做科威PLC芯片組開發(fā),需要準(zhǔn)備什么工具呢?

不必著急,給你一一道來(lái):
1.    KEIL2或者KEIL3,這個(gè)是必須的。下載地址筆者就不貼了,網(wǎng)上都有自己找。此款工具是你編寫驅(qū)動(dòng)所必須的。當(dāng)然你也可以用新華龍公司提供的編程工具Cynal來(lái)做,殊途同歸。
2.    DOWNHEX,此軟件屬科威公司開發(fā),專用于驅(qū)動(dòng)下載。所以你不要用KEIL自帶的下載功能進(jìn)行驅(qū)動(dòng)下載,沒有用,非用此工具下載不可。要搞清楚的是,現(xiàn)在你需要編寫的只是驅(qū)動(dòng),科威PLC芯片組的實(shí)時(shí)操作系統(tǒng)會(huì)將你的驅(qū)動(dòng)嵌入到系統(tǒng)內(nèi),驅(qū)動(dòng)并不是要覆蓋這個(gè)系統(tǒng),而只是補(bǔ)充此系統(tǒng)。驅(qū)動(dòng)中你所編寫的功能會(huì)被操作系統(tǒng)調(diào)用并執(zhí)行。DOWNHEX的作用,就是將你編寫的驅(qū)動(dòng)形成的HEX代碼保存在芯片組中的一個(gè)固定區(qū)域,系統(tǒng)運(yùn)行過程中會(huì)調(diào)用你寫的程序。
3.    CANSET,此軟件也屬科威公司開發(fā),專用于編寫CAN網(wǎng)絡(luò)設(shè)置參數(shù),也就是說(shuō),你想要激活科威PLC芯片組的CAN網(wǎng)絡(luò)通訊功能,就必須使用這款工具。如果你不用到此功能,那你當(dāng)然也可以不必使用此工具,但是做科威PLC芯片組開發(fā)不用到CAN功能,那可是暴殄天物,因?yàn)榇斯δ芸墒强仆⺁LC芯片組最大的亮點(diǎn)特色之一喲!
4.    FX2N編程軟件,嚴(yán)格說(shuō)起來(lái),這個(gè)和編寫驅(qū)動(dòng)沒有太大關(guān)系,但是,此軟件和科威PLC芯片組可是大大的有關(guān)系!這個(gè)軟件是編寫梯形圖的軟件,想要讓你的PLC運(yùn)行梯形圖,當(dāng)然還得靠它。

以上的前3種工具,筆者會(huì)在開發(fā)過程中告訴你應(yīng)該怎樣使用,所以你只要先有個(gè)大概的概念即可。

除此之外,你還得有一本C8051F040的說(shuō)明書,有許多寄存器的功能定義在使用過程中你非得查閱此書不可。網(wǎng)上有中文的和英文的版本,筆者用的是中文的,呵呵,如果喜好用英文的,那你是高手!什么?你已經(jīng)把說(shuō)明書的內(nèi)容都爛熟于心了?那你是高手中的高手,這段話當(dāng)我沒說(shuō)…ORZ

在網(wǎng)上找到c8051F040.inc的頭文件,此頭文件包含了所有F040的寄存器地址定義,開發(fā)過程中需要把此文件加到你的工程之中。如果不加,那么你所用的所有F040的寄存器,編譯器都會(huì)提示你undefined。

還得找到easycore.inc以及easycore.lib兩個(gè)文件。具體這兩個(gè)文件的作用,我們以后再談。

在從事開發(fā)之前,如果你對(duì)F040完全不了解,建議你還是花個(gè)幾天時(shí)間閱讀一下它的說(shuō)明書。當(dāng)然,想要把它完全都看懂,沒有一定編程實(shí)際經(jīng)驗(yàn)的話,絕對(duì)是個(gè)不可能完成的任務(wù)。只需要在看了以后,能夠?qū)Υ薈PU的性能和各功能模塊有一定了解即可。說(shuō)白了,筆者認(rèn)為,此說(shuō)明書存在的目的,就是為了能在開發(fā)過程中遇到的問題有個(gè)權(quán)威的查閱之處,而并不是去把它死記硬背,那是完全沒有必要的事情。

下一講,我們會(huì)正式進(jìn)入正題,講解如何編寫一個(gè)簡(jiǎn)單的驅(qū)動(dòng)。

PS:在本文提到的各種工具和資料,如果各位懶得去搜索,直接把郵箱貼在下面,筆者看到了會(huì)給你發(fā)過去^-^。

本帖首發(fā)中國(guó)工控網(wǎng)科威PLC論壇,轉(zhuǎn)載請(qǐng)聲明!    
lyq_4652
級(jí)別: *
精華主題: * 篇
發(fā)帖數(shù)量: * 個(gè)
工控威望: * 點(diǎn)
下載積分: * 分
在線時(shí)間: (小時(shí))
注冊(cè)時(shí)間: *
最后登錄: *
查看lyq_4652的 主題 / 回貼
1樓  發(fā)表于: 2008-07-28 14:49
如何搭建用戶驅(qū)動(dòng)環(huán)境?

首先,教大家如何使用KEIL3創(chuàng)建一個(gè)用戶驅(qū)動(dòng)工程(筆者目前用的是KEIL3,只能就此講解,所以你用的如果是KEIL2或者Cynal,那么就自行摸索,總的來(lái)說(shuō),功能上都相差不大。)

首先要注冊(cè)KEIL3,使之可以編譯超過2K范圍的代碼。至于怎么注冊(cè),請(qǐng)?jiān)诰W(wǎng)上找,筆者不在此贅述。

新建一個(gè)文件夾,此文件夾為你將要做的項(xiàng)目文件夾(比如D:\PLC_DRIVE,以下的教程皆假定你的項(xiàng)目在此文件夾內(nèi)來(lái)闡述)。
然后打開KEIL3,在菜單欄選擇Project→New Project…,將會(huì)彈出一個(gè)名為“Create New Project”的對(duì)話框,在對(duì)話框中選擇D:\PLC_DRIVE并雙擊進(jìn)入,創(chuàng)建一個(gè)名為“PLCDR”的uv2文件。

接下來(lái)會(huì)彈出一個(gè)選擇芯片類型的對(duì)話框,下拉豎直條選擇“Silicon Laboratories, Inc.”展開選擇“C8051F040”,點(diǎn)擊確定。

隨后系統(tǒng)問你是否需要“Copy Standard 8051 Startup Code to Project Folder and Add File to Project?”,這句話的意思是問你是否需要為你的項(xiàng)目添加標(biāo)準(zhǔn)的8051規(guī)范。這個(gè)東西對(duì)我們這個(gè)項(xiàng)目的開發(fā)沒多大用,推薦你選擇否,反正筆者就是這么干的。
這個(gè)時(shí)候基本的項(xiàng)目框架就搭建起來(lái)了,現(xiàn)在是時(shí)候?yàn)槟愕尿?qū)動(dòng)項(xiàng)目添加“血肉”了。

選擇菜單中的File→New…,點(diǎn)擊“保存”,將此Text1空白文檔保存在D:\PLC_DRIVE中,并更改此文件名為“PLCDR.ASM”,注意后綴名是“.ASM”而不是“.TXT”了。

這個(gè)時(shí)候,細(xì)心的你可能已經(jīng)發(fā)現(xiàn)了,我們將會(huì)用51匯編來(lái)實(shí)現(xiàn)驅(qū)動(dòng)程序的編寫。在這個(gè)匯編已經(jīng)沒落,甚至連C也慢慢的被人拋棄的時(shí)代, C#,.NET,.COM,JAVA,J2EE等流行語(yǔ)言及技術(shù)大行其道的今天,我們?yōu)槭裁催要用匯編來(lái)編寫程序呢?而且是在KEIL也是支持C語(yǔ)言的情況下我們做出的選擇,看似更加的沒有道理。其實(shí)這是仁者見仁,智者見智的。在筆者看來(lái),匯編雖然比C更加的晦澀難懂,但它最貼近硬件的特性卻能夠使我們的驅(qū)動(dòng)程序更加的高效,在F040這個(gè)8位小型CPU上,使用匯編語(yǔ)言能更加讓我們“精打細(xì)算”,使我們的每條語(yǔ)句都精確到0.0X個(gè)US(科威PLC芯片組的系統(tǒng)時(shí)鐘頻率為24.5MHZ,也是F040所能達(dá)到的最高系統(tǒng)時(shí)鐘頻率),PLC是做什么的?當(dāng)然是做控制的,所以實(shí)時(shí)性,高效性以及安全性是PLC永恒的話題。我們選擇匯編語(yǔ)言作為驅(qū)動(dòng)程序的開發(fā)的理由也正因如此。當(dāng)然,如果你對(duì)匯編一竅不通的話,筆者也建議你耐心把下面的教程看完,雖然匯編與C的差異性還是蠻大的,但是多多少少會(huì)對(duì)你對(duì)芯片組開發(fā)有一定的幫助。

呵呵,話題扯遠(yuǎn)了,言歸正轉(zhuǎn),你注意到左邊那個(gè)“Project Workspace”浮動(dòng)工具欄沒?雙擊里面的Source Group 1,路徑選擇到“D:\PLC_DRIVE”,選擇“PLCDR.ASM”并點(diǎn)擊確定。什么?沒有這個(gè)“PLCDR.ASM”?那你得把文件類型改為“all files”才能看的到。個(gè)人BS了KEIL公司一下,居然連.ASM的文件類型都沒有…看來(lái)也是個(gè)喜新厭舊的主~
這個(gè)時(shí)候,你會(huì)發(fā)現(xiàn)Source Group 1左邊有個(gè)小+號(hào),點(diǎn)擊下拉,PLCDR.ASM躍然紙上了,哦不,是躍然于顯示屏上了。

至此,準(zhǔn)備工作已經(jīng)完成,下一講我們就要介紹此項(xiàng)目工程在KEIL中的一些參數(shù)設(shè)置,以及科威PLC芯片組用戶驅(qū)動(dòng)開發(fā)所需要準(zhǔn)備的幾個(gè)頭文件和函數(shù)庫(kù)。

本帖首發(fā)中國(guó)工控網(wǎng)科威PLC論壇,轉(zhuǎn)載請(qǐng)聲明!

lyq_4652
級(jí)別: *
精華主題: * 篇
發(fā)帖數(shù)量: * 個(gè)
工控威望: * 點(diǎn)
下載積分: * 分
在線時(shí)間: (小時(shí))
注冊(cè)時(shí)間: *
最后登錄: *
查看lyq_4652的 主題 / 回貼
2樓  發(fā)表于: 2008-07-31 11:28
到底我該怎么編寫一個(gè)用戶驅(qū)動(dòng)呢?

上一講我們配置了用戶驅(qū)動(dòng)在KEIL3中的工程環(huán)境,下面我們來(lái)談?wù)凱LCDR項(xiàng)目在KEIL中應(yīng)該設(shè)置哪些參數(shù)。

首先,你得找到一個(gè)名為“Options For Target”的圖標(biāo),就是那個(gè)“LAOD”圖標(biāo)旁邊那個(gè)象個(gè)魔法棒的圖案,點(diǎn)擊彈出“Options For Target Target1”對(duì)話框。當(dāng)然你也可以選擇菜單的Project→Options For Target Target1來(lái)把此對(duì)話框調(diào)出。

找到OutPut選項(xiàng),勾上下面的“Create HEX File ”的單選框,前面我們?cè)?jīng)說(shuō)過,驅(qū)動(dòng)加載到科威PLC芯片組中是要以HEX形式的文件通過DOWNHEX軟件下載來(lái)實(shí)現(xiàn)的。所以得讓KEIL給你生成一個(gè)HEX才行。

然后找到A51選項(xiàng),將“Define 8051 SFR Names”前面的勾去掉。如果啟用這個(gè)功能,KEIL就會(huì)在編譯你的項(xiàng)目的時(shí)候,自動(dòng)調(diào)用51默認(rèn)的寄存器定義,那么就會(huì)和前面我們所提到的c8051F040.inc這個(gè)頭文件所定義的寄存器相沖突。結(jié)果會(huì)在你編譯項(xiàng)目的過程中,會(huì)出現(xiàn)一大堆的“redefined”錯(cuò)誤。

除此之外,都默認(rèn)就好,點(diǎn)擊確認(rèn)完成參數(shù)配置。

接下來(lái),將你找到的c8051F040.inc,easycore.inc以及easycore.lib這3個(gè)文件都復(fù)制到D:\PLC_DRIVE路徑下,并在此路徑下新建一個(gè)“USER_DATA.inc”的文件。

下面我們說(shuō)說(shuō),這幾個(gè)文件的含義:
1.    c8051F040.inc,這個(gè)筆者前面講過,不再重復(fù);
2.    easycore.inc,你可以打開它來(lái)看看,會(huì)發(fā)現(xiàn)這里面定義了用戶所可以用到的寄存器組還有相關(guān)的變量地址。F040中共定義了4個(gè)R0~R7寄存器組,用戶只能使用0區(qū),其他的對(duì)不起,內(nèi)核(我們習(xí)慣把芯片組內(nèi)的實(shí)時(shí)操作系統(tǒng)稱之為內(nèi)核,很形象,不是嗎?)都給占用了~然后是BRAM_USER,這個(gè)是用戶可用的位變量尋址,采用的是直接位尋址方式,一共可以定義32個(gè)位,也就是4個(gè)字節(jié)。少了點(diǎn),可是沒辦法,內(nèi)核占了大頭…DRAM_USER,這個(gè)是用戶可用的字節(jié)變量尋址,采用的是直接尋址方式,可以定義16個(gè),還是少了點(diǎn),但是還是沒辦法…-_-!最后是XRAM_USER,這個(gè)用戶能用的倒是多啊,有幾千個(gè),但是可惜的是它是間接字節(jié)尋址。系統(tǒng)讀取這個(gè)區(qū)域的數(shù)據(jù),那效率是刷刷往下降。〉沁是得用,要不然變量不夠啊,呵呵。F040要是直接尋址的存儲(chǔ)空間再大些就好了,可是這是筆者的一相情愿,殘念……最后面就是有關(guān)梯形圖的變量地址空間了,你可以看到D,M,S等梯形圖內(nèi)所用的這些寄存器在內(nèi)核里面所占的地址。中間的那一塊暫時(shí)跳過不講,以后找機(jī)會(huì)給大家說(shuō)明,不過可能有的讀者已經(jīng)了解那些定義大概是什么意思了,不管了解不了解,讓我們繼續(xù)GO ON!
3.    easycore.lib,這個(gè)庫(kù)直接從KEIL里面是看不了的,你想要看它,就從記事本里面看吧。里面是為了方便用戶所定義的一些系統(tǒng)函數(shù),比如雙字節(jié)乘除,浮點(diǎn)數(shù)運(yùn)算等等,如果你要調(diào)用這些函數(shù),注意出口入口要設(shè)置對(duì)哦。
4.    USER_DATA.inc,這個(gè)文件暫時(shí)是空白的,留給你自己發(fā)揮創(chuàng)造的,你可以在里面定義自己的位變量啦,字節(jié)變量啦,還有變量重定義等。比如你在里面寫一句“MODE_DATA      EQU  DRAM_USER  ;模式選擇”,意思就是你將直接字節(jié)尋址的第一個(gè)單元賦予了MODE_ONOFF這個(gè)名字,那么你在驅(qū)動(dòng)中就可以直接調(diào)用MODE_DATA這個(gè)變量啦。
后面那個(gè)分號(hào)以及分號(hào)以后的文字,是這條語(yǔ)句的注釋。在KEIL給51匯編加注釋有2中方法,一個(gè)是“;”,相當(dāng)于C里面的“//”,另外一個(gè)和C相同,是“/* */”。


下一講,筆者將講述科威PLC芯片組開發(fā)用戶驅(qū)動(dòng)的具體格式。

本帖首發(fā)中國(guó)工控網(wǎng)科威PLC論壇,轉(zhuǎn)載請(qǐng)聲明!

lyq_4652
級(jí)別: *
精華主題: * 篇
發(fā)帖數(shù)量: * 個(gè)
工控威望: * 點(diǎn)
下載積分: * 分
在線時(shí)間: (小時(shí))
注冊(cè)時(shí)間: *
最后登錄: *
查看lyq_4652的 主題 / 回貼
3樓  發(fā)表于: 2008-08-02 10:16
這一講里面將會(huì)講解科威PLC芯片組開發(fā)用戶驅(qū)動(dòng)的具體格式。筆者始終認(rèn)為,學(xué)編程,從看代碼開始是捷徑!所以,我們?cè)赑CLDR.ASM內(nèi)添加以下一段代碼。

$INCLUDE(C8051F040.INC)    ; Register definition file.    -------------------1    
$INCLUDE(easycore.INC)        ; easycore 符號(hào)定義------------------------2            
$INCLUDE(EASYCORE.LIB)    ; easycore 子程序---------------------------3            
$INCLUDE(user_data.INC)        ; 用戶程序變量定義------------------------4            
;================中斷向量重定向地址=======================
                ORG        0E000H                    
                ORG        0E003H            ;external interrupt0 vecter (INT0)------5
                ORG        0E013H            ;external interrupt1(INT1)---------------6
                ORG        0E033H            ;Serial Peripheral Interface(SPI)--------7
                ORG        0E03BH            ;SMBus interface-------------------------8
                ORG        0E043H            ;ADC0 Window Comparator;----------9
                ORG        0E04BH            ;Programmable Counter Array--------10
                ORG        0E053H            ;Comparator 0---------------------------11
                ORG        0E05BH            ;Comparator 1---------------------------12
                ORG        0E063H            ;Comparator 2    --------------------------13
                ORG        0E07BH            ;ADC0 end of Conversion-------------14
                ORG        0E083H            ;Timer    4-------------------------------15
                ORG        0E08BH            ;ADC2 end of Conversion-------------16
                ORG        0E093H            ;ADC2 Window Comparator-----------17
;===============用戶應(yīng)用程序調(diào)用入口====================
                ORG        0E0A0H            ;用戶端口初始化
                LJMP        INIT_CONFIG     ;----------------------- --------------------18    
                ORG        0E0A3H            ;用戶上電初始化
                LJMP        INIT_START        ;----------------------- --------------------19    
                ORG        0E0A6H            ;用戶設(shè)置初始化
                LJMP        INIT_SET        ;----------------------- --------------------20    
                ORG        0E0A9H            ;用戶運(yùn)行初始化
                LJMP        INIT_RUN        ;----------------------- --------------------21
                ORG        0E0ACH            ;演算周期掃描
                LJMP        SCAN            ;----------------------- --------------------22
                ORG        0E0B0H            ;指令周期掃描
                LJMP        STEP            ;----------------------- --------------------23
                ORG        0E0B3H            ;2.5MS周期掃描            
                LJMP        TMS            ;----------------------- --------------------24
                        
                ORG         0E100H            ;----------------------- --------------------25


INIT_CONFIG:
                RET

INIT_START:
                RET

INIT_SET:
                RET

INIT_RUN:
                RET

STEP:
                RET

TMS:
                RET

SCAN:
                RET

END        ;-------------------------------------------------------------26

然后點(diǎn)擊編譯,如無(wú)意外,KEIL將會(huì)編譯成功并生成“PLCDR.HEX”文件,該文件可以在項(xiàng)目路徑下找到。

至此,你的第一個(gè)驅(qū)動(dòng)程序已經(jīng)編寫完成。只不過這是一個(gè)簡(jiǎn)單的驅(qū)動(dòng)程序,簡(jiǎn)單到什么也沒有的驅(qū)動(dòng)程序。嘿嘿,如果把這段HEX代碼下到你的PLC內(nèi),PLC的IO口可能會(huì)亂跳的哦~不過,梯形圖的解釋倒是獨(dú)立于驅(qū)動(dòng)之外的,加載了一個(gè)什么也沒有的驅(qū)動(dòng),PLC芯片組也是可以正常運(yùn)行梯形圖的。

在下一講里,筆者將會(huì)逐句給你分析以上程序的每一條語(yǔ)句哦~其實(shí)從那些簡(jiǎn)短的注釋里,相信不少讀者已經(jīng)看出了些許端倪了。

本帖首發(fā)中國(guó)工控網(wǎng)科威PLC論壇,轉(zhuǎn)載請(qǐng)聲明!

lyq_4652
級(jí)別: *
精華主題: * 篇
發(fā)帖數(shù)量: * 個(gè)
工控威望: * 點(diǎn)
下載積分: * 分
在線時(shí)間: (小時(shí))
注冊(cè)時(shí)間: *
最后登錄: *
查看lyq_4652的 主題 / 回貼
4樓  發(fā)表于: 2008-08-04 09:48
上講驅(qū)動(dòng)語(yǔ)句解釋:

在上面一講,筆者給出了一段基本用戶驅(qū)動(dòng)語(yǔ)句段的代碼,下面是詳細(xì)解釋它們的時(shí)候了。

1.    第1~4句:是將3個(gè)頭文件和1個(gè)庫(kù)文件添加到你的驅(qū)動(dòng)工程項(xiàng)目中,這個(gè)就不在解釋了。

2.    第5~24句:是將F040的中斷跳轉(zhuǎn)重定義,查閱F040的說(shuō)明書我們可以看到,0X0003H是外部中斷0的代碼起始地址,在內(nèi)核中,將外部中斷0的起始代碼重新定義到0E003H開始了。這里就產(chǎn)生了3個(gè)問題:
①    為什么要將中斷的起始代碼地址重定義?
答:這個(gè)是為了方便代碼管理,前面筆者曾經(jīng)提到過,驅(qū)動(dòng)下載到內(nèi)核里,是存放在一
塊相應(yīng)的地址空間由內(nèi)核調(diào)用的。這個(gè)地址你現(xiàn)在可以看到,是從0XE000H開始的,由于用戶中斷也屬用戶驅(qū)動(dòng)的一部分,所以,它的這部分代碼也必須保存到0XE000H以后的一個(gè)地址段內(nèi),而默認(rèn)的中斷起始代碼從哪里開始呢?以外部中斷0為例,你可以從說(shuō)明書上看到,它的起始地址是0X0003H,這樣用戶驅(qū)動(dòng)流程代碼和用戶驅(qū)動(dòng)中斷代碼就被分成了2個(gè)地址段,給內(nèi)核的管理造成了麻煩。所以我們必須要進(jìn)行中斷代碼地址重定義的工作。
②    如何實(shí)現(xiàn)中斷的起始代碼地址重定義?
答:還是以外部中斷0為例,內(nèi)核在這里直接用了一個(gè)“LJMP    0XE003H”即完成了地址重定義的工作,是不是很簡(jiǎn)單?
③    科威PLC芯片組還有其他的中斷重定義了嗎?我可以用它們嗎?
答:我們只能夠用到上面代碼給出的這些中斷,還有的中斷比如T0,T1等中斷已被內(nèi)核占用,我們編寫用戶驅(qū)動(dòng)就無(wú)緣使用它們啦!

3.    第18句:用戶I/O口配置程序:根據(jù)設(shè)計(jì)的輸入輸出功能配置相應(yīng)的端口(推挽或者漏級(jí)),用戶不可配置的I/O口資源為P4.4、P4.5、P4.6、P4.7、P5、P6、P7及UART0。理由還是那句話:內(nèi)核已占用…此段程序會(huì)在內(nèi)核重新上電后調(diào)用一次。

4.    第19句:用戶上電初始化程序:用戶嵌入程序中用到的輸入輸出變量,中間變量,指針變量,位變量等在重新上電后必需進(jìn)行初始化處理,此段程序在內(nèi)核重新上電后調(diào)用一次。

5.    第20句:用戶設(shè)置初始化程序:內(nèi)核重新上電后進(jìn)入梯型圖下載狀態(tài)或內(nèi)核從梯型圖運(yùn)型狀態(tài)進(jìn)入梯型圖下載狀態(tài)時(shí)調(diào)用此程序一次。

6.    第21句:用戶運(yùn)行初始化程序:內(nèi)核重新上電后第一次運(yùn)行梯型圖或內(nèi)核從下載梯型圖狀態(tài)進(jìn)入梯型圖運(yùn)行狀態(tài)時(shí)調(diào)用此程序一次。這個(gè)子程序大家可以看到,與上面一個(gè)的流程是相反的。

7.    第22句:用戶演算周期掃描程序:所有梯形圖執(zhí)行完后,即調(diào)用該程序,調(diào)用周期為梯型圖演算周期,一般的數(shù)據(jù)處理、開關(guān)量輸入/輸出的刷新及代碼執(zhí)行時(shí)間較長(zhǎng)的程序均放在此程序中執(zhí)行。

8.    第23句:用戶每步執(zhí)行程序:梯形圖每執(zhí)行一步,即調(diào)用此程序一次。需要快速執(zhí)行的事件可在此程序或用戶中斷程序中完成,內(nèi)核周期性地調(diào)用此程序,周期小于50US。
50US有多少個(gè)指令周期呢?我們可以算算:設(shè)1個(gè)指令周期的執(zhí)行時(shí)間為t,系統(tǒng)時(shí)鐘頻率為f,那么1S=1000000US, f = 24.5MHZ,那么t = 1000000/24500000 = 0.04US,也就是說(shuō)50US可以執(zhí)行的指令周期數(shù)為50/0.04 = 1250個(gè)。這里有兩點(diǎn)需要說(shuō)明一下,一條語(yǔ)句所占的指令周期并不一定只有一個(gè),比如NOP指令所占的指令周期為1,但是CJNE指令就不止1個(gè)了,具體占了幾個(gè)筆者不記得了~,這個(gè)可以在說(shuō)明書里面查到。另外一點(diǎn)是假設(shè)你編寫的總代碼折合成指令周期數(shù)是2000個(gè),那是不是就不能滿足要求了呢?答案是不一定,只要你最長(zhǎng)的一次執(zhí)行過程所花費(fèi)的指令周期數(shù)不超過1250個(gè)就行了,因?yàn)橥诔绦蚶飼?huì)有條件跳轉(zhuǎn)的代碼。舉個(gè)例子吧,假設(shè)你的STEP里面有2個(gè)條件執(zhí)行過程A和B,A條件的執(zhí)行過程一共有1100個(gè)指令周期,B條件有900個(gè)。雖然A+B一共有2000個(gè)超過了1250個(gè),但是因?yàn)槭菞l件跳轉(zhuǎn),程序是不可能同時(shí)執(zhí)行A和B的。所以算起來(lái)你的程序最長(zhǎng)的指令周期數(shù)是1100個(gè)而不是2000個(gè)!哎呀,估計(jì)越講越難讓人理解了…打住,往下走吧,畢竟,計(jì)算每條語(yǔ)句所占用的系統(tǒng)時(shí)間并將其代碼優(yōu)化都是些達(dá)人們,我們還是先看簡(jiǎn)單的。

9.    第24句:用戶2.5mS定時(shí)運(yùn)行程序:需要定時(shí)采樣的流程可放在此程序中完成,但該段程序代碼執(zhí)行時(shí)間必須小于50 US。數(shù)據(jù)處理程序不宜放在此段程序中執(zhí)行。注意這里是內(nèi)核給提供的軟中斷,如果你的驅(qū)動(dòng)里面沒有什么高級(jí)的中斷并頻繁發(fā)生,那么它就是2.5ms調(diào)用一次,很準(zhǔn)!同時(shí)你得注意,它的返回語(yǔ)句不是“RETI”而是“RET”,為什么?因?yàn)樗恰败洝钡穆,是?nèi)核給定義的,又不是F040的規(guī)范中斷,呵呵!

10.    第25句:用戶驅(qū)動(dòng)程序編程起始位置,從這里往下就是你自由發(fā)揮的空間了哦~

11.    第26句:別忘了給你的驅(qū)動(dòng)程序加個(gè)完美的“句號(hào)”。

看到這里,你應(yīng)該對(duì)科威PLC芯片組的開發(fā)有了一定的了解了吧。?完全沒了解??看來(lái)筆者的水平差了點(diǎn),就請(qǐng)將就多看幾遍吧…-_-!不是有一句話就作“書讀百遍,其意自現(xiàn)”的么。有問題或不懂的給回下貼嘛,筆者看到了一定給你解答^-^~!

在下一講里面,就要開始實(shí)戰(zhàn)了,筆者將基于科威公司出產(chǎn)的EASY-M0806R這款PLC重新編寫IO驅(qū)動(dòng)程序,手頭上有這款PLC的朋友也可以跟著做哦~!

本帖首發(fā)中國(guó)工控網(wǎng)科威PLC論壇,轉(zhuǎn)載請(qǐng)聲明!

lyq_4652
級(jí)別: *
精華主題: * 篇
發(fā)帖數(shù)量: * 個(gè)
工控威望: * 點(diǎn)
下載積分: * 分
在線時(shí)間: (小時(shí))
注冊(cè)時(shí)間: *
最后登錄: *
查看lyq_4652的 主題 / 回貼
5樓  發(fā)表于: 2008-08-05 09:59
實(shí)戰(zhàn)開始,苦手對(duì)象:EASY-M0806R

首先,我們得搞清楚,EASY-M0806R的IO引腳的分配情況,這款PLC有8個(gè)輸入點(diǎn),6個(gè)輸出點(diǎn),那么就相應(yīng)的有8+6 = 14個(gè)IO引腳對(duì)應(yīng)它們的輸入和輸出,對(duì)應(yīng)原理圖我們得知:
8個(gè)輸入點(diǎn)對(duì)應(yīng)的引腳是:
I0→P3.7     I1→P3.6  I2→P3.5  I3→P3.4  I4→P3.3  I5→P3.2  I6→P3.1  I7→P3.0

6個(gè)輸出點(diǎn)對(duì)應(yīng)的引腳是:
OUT0→P1.0  OUT1→P1.1  OUT2→P1.2  OUT3→P1.3  OUT4→P1.4  OUT5→P1.5

其次,每個(gè)輸入輸出點(diǎn)都對(duì)應(yīng)一個(gè)LED,當(dāng)輸入輸出點(diǎn)吸合的時(shí)候,對(duì)應(yīng)的LED將被點(diǎn)亮,那么對(duì)應(yīng)原理圖我們得知14個(gè)LED對(duì)應(yīng)的引腳是:
ILED0→P2.0  ILED1→P2.1  ILED2→P2.2  ILED3→P2.3  ILED4→P2.4  ILED5→P2.5
ILED6→P2.6  ILED7→P2.7
OLED0→P0.4  OLED1→P0.5  OLED2→P0.6  OLED3→P0.7  OLED4→P4.1  OLED5→P4.0

與此同時(shí),PLC還有一個(gè)RUN/SET的輸入,該輸入負(fù)責(zé)管理PLC的運(yùn)行狀態(tài)和下載狀態(tài),對(duì)應(yīng)著不同的狀態(tài),有一個(gè)專門LED點(diǎn)亮/熄滅來(lái)判斷此輸入的狀態(tài),一般來(lái)說(shuō),運(yùn)行狀態(tài)時(shí),該LED被點(diǎn)亮,下載狀態(tài)則反之。根據(jù)原理圖我們得知:
RUN/SET-LED→P4.3

PLC如果錯(cuò)誤的被執(zhí)行,應(yīng)該還有一個(gè)錯(cuò)誤的LED將被點(diǎn)亮,這個(gè)LED對(duì)應(yīng)的引腳為:
ERR-LED→P4.2
那么我們?cè)趺吹弥狿LC運(yùn)行/下載的狀態(tài),還有出錯(cuò)的狀態(tài)呢?請(qǐng)看easycore.inc文件,有3個(gè)變量定義:
KEY_SET            EQU        3FH        ;1有效(下載梯形圖)
KEY_PRO            EQU        3EH        ;0有效(下載用戶程序)
PLC_PRO_ERR        EQU        3DH        ;梯形圖錯(cuò)誤標(biāo)志,1有效
這個(gè)是我們前幾節(jié)所沒有講到的,通過檢測(cè)這些位變量,我們就可以對(duì)RUN/SET-LED和ERR-LED進(jìn)行控制了。

知道了這些以后,我們就對(duì)EASY-M0806R的IO引腳分配有了大致的了解,趁此機(jī)會(huì),我們把easycore.inc最后剩下沒講完的變量也拉出來(lái)遛一下吧~
M0~M15:這16個(gè)字節(jié)變量可是直接尋址方式的喲,但是應(yīng)用它們有個(gè)局限性,那就是必須得在SCAN里面應(yīng)用,其他地方是不允許調(diào)用這16個(gè)字節(jié)變量的,如果你非要在其他地方使用,那么就必須得把它們壓棧,不過還是不推薦此方法,真的要壓棧的話,還不如壓公共直接尋址變量區(qū)DRAM_USER區(qū)域呢。

FLOAT_M1~ FLOAT_M4,W_R0~ W_R7,W_DATA:這幾個(gè)變量是專門調(diào)用easycore.lib函數(shù)庫(kù)里面的函數(shù)所要用到的出口入口的變量。大致了解一下它們的含義便行,如果你到了需要調(diào)用easycore.lib函數(shù)庫(kù)里面的函數(shù)這個(gè)階段,那么本文對(duì)你來(lái)說(shuō),相信應(yīng)該已經(jīng)沒有多大意義了^-^~!

下一講我們將分模塊來(lái)詳細(xì)敘述如何根據(jù)我們所掌握的IO口引腳信息,來(lái)填充我們的驅(qū)動(dòng)項(xiàng)目工程。

PS:本節(jié)所講的IO口配置可能會(huì)與實(shí)際IO口配置略有出入,大家當(dāng)以實(shí)際的原理圖為準(zhǔn)!

本帖首發(fā)中國(guó)工控網(wǎng)科威PLC論壇,轉(zhuǎn)載請(qǐng)聲明!
lyq_4652
級(jí)別: *
精華主題: * 篇
發(fā)帖數(shù)量: * 個(gè)
工控威望: * 點(diǎn)
下載積分: * 分
在線時(shí)間: (小時(shí))
注冊(cè)時(shí)間: *
最后登錄: *
查看lyq_4652的 主題 / 回貼
6樓  發(fā)表于: 2008-08-06 09:34
實(shí)戰(zhàn)攻堅(jiān)!

上一講我們了解了EASY-M0806R的IO口分配情況以及各種LED的引腳情況,那么下面我們就要開始一步一步的編寫我們的驅(qū)動(dòng)代碼了~

首先是INIT_CONFIG用戶驅(qū)動(dòng)子程序,該程序里面,要添加的內(nèi)容在前文中已有說(shuō)明。那我們?cè)撊绾闻渲眠@些IO口方式呢?

INIT_CONFIG
首先我們的第一句話便是:
MOV    SFRPAGE,#0FH
那么SFRPAGE是什么意思呢?呵呵,這就要看你對(duì)以前看的F040說(shuō)明書熟悉程度了,什么?你完全不知道??-_-!那就現(xiàn)翻吧~筆者當(dāng)年也好不到哪去,嘿嘿。
從說(shuō)明書中可得知,這是一個(gè)選擇SFR頁(yè)數(shù)的功能寄存器,我們要調(diào)配IO端口的參數(shù)寄存器PnMDOUT,就首先得把SFR頁(yè)數(shù)置為15,這個(gè)是F040規(guī)劃的,就不再剝根問底了。值得提出的是,初學(xué)者常犯的一個(gè)錯(cuò)誤就是在配置功能寄存器的時(shí)候,沒有及時(shí)更改它所屬的SFR頁(yè)數(shù),導(dǎo)致程序運(yùn)行錯(cuò)誤。比如,配置了P0MDOUT功能寄存器,這個(gè)時(shí)候你是把SFRPAGE置成15了。但是在調(diào)配TMR4CN功能寄存器的時(shí)候,卻忘了把SFRPAGE改為2。這個(gè)時(shí)候錯(cuò)誤便不可避免的出現(xiàn)了。
其次,我們開始配置上面所涉及到的EASY-M0806R的IO口的配置寄存器了,也許有的朋友會(huì)問到了,怎么初始化沒有延遲啊,選擇系統(tǒng)時(shí)鐘頻率啊,調(diào)配交叉開關(guān)啊?這些步驟確實(shí)是一個(gè)操作系統(tǒng)運(yùn)行初始化所必須要配置的部分,但是在我們的驅(qū)動(dòng)里面就不用重新配置了,因?yàn)閮?nèi)核里面已經(jīng)定義過了一次。當(dāng)然,也許你做的PLC有特殊的用途需要重新配置這些,那么也可以,不過還是那句話,時(shí)刻記住以內(nèi)核為主,所以在重新配置這些之前你要考慮清楚怎么配置才不會(huì)和內(nèi)核的配置起沖突。
科威PLC一般來(lái)說(shuō),輸入端口要配置成漏極方式,輸入端口要配置成推挽方式,LED也都是推挽方式。當(dāng)然具體的要視其原理圖決定。根據(jù)這個(gè)原則,我們配置了下面4條語(yǔ)句:
ORL    P0MDOUT,#0F0H        ;1
ORL    P1MDOUT,#3FH        ;2
ORL    P2MDOUT,#0FFH        ;3
ANL    P3MDOUT,#00H        ;4
ORL    P4MDOUT,#03H        ;5
也許細(xì)心的你會(huì)問:為什么都要用ORL和ANL指令而不是用MOV呢?這個(gè)就是筆者的習(xí)慣了,ORL和ANL指令的好處是只用改變你所需要的位,而其他的可以保持不變,以免引起不必要的錯(cuò)誤。
我們來(lái)分析這4句話的含義:
1.    這句是配置P0端口的輸出方式的,由上一講我們得知,整個(gè)驅(qū)動(dòng)用到P0口的有:
OLED0→P0.4  OLED1→P0.5  OLED2→P0.6  OLED3→P0.7,由于LED需要配置成推挽輸出方式,那么我們就將P0MDOUT的高4位都配置成1即可。
2.    這句是配置P1端口的輸出方式的,整個(gè)驅(qū)動(dòng)用到P1口的有:
OUT0→P1.0  OUT1→P1.1  OUT2→P1.2  OUT3→P1.3  OUT4→P1.4  OUT5→P1.5,由于輸出端口需要配置成推挽輸出方式,那么我們把P1MDOUT的低6位都配置成1即可。
3.    這句是配置P2端口的輸出方式的,整個(gè)驅(qū)動(dòng)用到P2口的有:
ILED0→P2.0  ILED1→P2.1  ILED2→P2.2  ILED3→P2.3  ILED4→P2.4  ILED5→P2.5  ILED6→P2.6  ILED7→P2.7,由于LED需要配置成推挽輸出方式,那么我們就將P2MDOUT的所有8位都配置成1即可。
4.    這句是配置P3端口的輸出方式的,整個(gè)驅(qū)動(dòng)用到P3口的有:
I0→P3.7     I1→P3.6  I2→P3.5  I3→P3.4  I4→P3.3  I5→P3.2  I6→P3.1  I7→P3.0,由于輸入端口需要配置成漏極輸出方式,故我們把整個(gè)P3口輸出都配置成0。
5.    這句是配置P4端口的輸出方式的,整個(gè)驅(qū)動(dòng)用到P4口的有:
OLED4→P4.1  OLED5→P4.0,同理,我們把P4MDOUT的低2位配置成1。

這樣,整個(gè)INIT_CONFIG便配置完成了。下一講筆者將講述其他用戶驅(qū)動(dòng)子程序在EASY-M0806R上的實(shí)現(xiàn)。

本帖首發(fā)中國(guó)工控網(wǎng)科威PLC論壇,轉(zhuǎn)載請(qǐng)聲明!
lyq_4652
級(jí)別: *
精華主題: * 篇
發(fā)帖數(shù)量: * 個(gè)
工控威望: * 點(diǎn)
下載積分: * 分
在線時(shí)間: (小時(shí))
注冊(cè)時(shí)間: *
最后登錄: *
查看lyq_4652的 主題 / 回貼
7樓  發(fā)表于: 2008-08-07 10:36
實(shí)戰(zhàn)攻堅(jiān)!

上面一講我們講述了該如何對(duì)照原理圖的引腳分配情況來(lái)配置你的INIT_CONFIG子程序,這一講筆者說(shuō)說(shuō)其他3個(gè)初始化應(yīng)該如何編寫。

我們先在USER_DATA中定義幾個(gè)用戶變量:
INPUT_PORTA            EQU    DRAM_USER
INPUT_CNT                 EQU    DRAM_USER+1
XINPUT                    EQU    XRAM_USER

在解釋這些變量的含義之前,我們首先聊下PLC的工作狀態(tài)。
PLC的輸入端口是和梯形圖中的X端口相對(duì)應(yīng)的,也就是說(shuō),短接I0和COM0(輸入端口統(tǒng)一地端子),梯形圖中的X0將會(huì)吸合,反應(yīng)在元件監(jiān)控畫面上X0右邊會(huì)出現(xiàn)綠色的實(shí)心小正方形,表示它的觸點(diǎn)已被吸合。同理,I0~I7對(duì)應(yīng)的便是X0~X7。
而PLC的輸出端口是和梯形圖中的Y端口相對(duì)應(yīng)的,當(dāng)用戶在梯形圖中把Y0置1或是元件監(jiān)控里把Y0強(qiáng)制置1,那么O0端子便和COM1自動(dòng)短接了。同理,O0~O5對(duì)應(yīng)的便是Y0~Y5。在PLC端子口上是看不到I0和O0的,但是有它們對(duì)應(yīng)的X0和Y0。
下面我們講講這幾個(gè)用戶變量:
INPUT_PORTA:用來(lái)保存當(dāng)前8個(gè)輸入端口的輸入狀態(tài)(X0~X7)的。
INPUT_CNT:輸入端子采樣次數(shù)指針。
XINPUT:輸入端子采樣值緩沖區(qū)。

這些概念朋友們先大概了解一下便好,至于怎么應(yīng)用到它們,后面還會(huì)具體講到。

INIT_START
接下來(lái),我們開始編寫INIT_START用戶驅(qū)動(dòng)子程序了,添加的代碼如下:
MOV    INPUT_CNT,#08H        ;1
CLR        A                    ;2
MOV    DPTR,#RAM_PX+1    ;3
MOVX    @DPTR,A            ;4
MOV    DPTR,#RAM_PY+1    ;5
MOVX    @DPTR,A            ;6

1.    我們將INPUT_CNT這個(gè)變量初始化為8,這也就意味著,采樣的次數(shù)我們限定它為8次,如果你設(shè)置成4,那么輸入端口的采樣次數(shù)就為4,現(xiàn)在只要知道這些就好,我們以后在講到TMS這個(gè)用戶驅(qū)動(dòng)子程序時(shí),會(huì)詳細(xì)給大家分析為什么采樣輸入端口以及如何采樣它。
2.    不用講了吧…
3.    這個(gè)是將間接尋址指針指向X0~X7所在的地址單元,間接尋址指針的表達(dá)方式有2種,筆者慣用的是以DPTR形式來(lái)進(jìn)行尋址。至于另外一種,呵呵,自己查說(shuō)明書吧。
4.    這句話的意思是把寄存器A的值賦給X0~X7,因?yàn)锳的值為0,實(shí)際上這句話的作用就是把X0~X7所代表的寄存器的值清零?吹竭@里,可能有的朋友就又有問題了,為什么X0~X7所在的地址不是#RAM_PX而是#RAM_PX+1呢,其實(shí)這個(gè)是和內(nèi)核定義梯形圖單元的尋址地址有關(guān)。內(nèi)核規(guī)定,梯形圖的單元寄存器都是低位在后,高位在前,也就是說(shuō),#RAM_PX并不是對(duì)應(yīng)的X0~X7,而是X10~X17。
5.    這個(gè)是將間接尋址指針指向Y0~Y7所在的地址單元。
6.    同4。

INIT_RUN
直接讓它返回吧,在這個(gè)系統(tǒng)里面,沒必要配置這個(gè)。

INIT_SET
然后緊接著配置INIT_SET:
CLR        A                    
MOV    DPTR,#RAM_PX+1    
MOVX    @DPTR,A            
MOV    DPTR,#RAM_PY+1    
MOVX    @DPTR,A            
這里也是清除X0~X7和Y0~Y7的寄存器值,那為什么在這里又要清零呢?會(huì)不會(huì)跟之前的重復(fù)了呢?
當(dāng)然不會(huì),注意到系統(tǒng)會(huì)在什么時(shí)候調(diào)用INIT_SET呢?是在內(nèi)核重新上電后進(jìn)入梯型圖下載狀態(tài)或內(nèi)核從梯型圖運(yùn)型狀態(tài)進(jìn)入梯型圖下載狀態(tài)時(shí)調(diào)用此程序一次。
看到了吧,PLC在不斷電的情況下,也會(huì)在上面黑體的部分調(diào)用到它,舉個(gè)例子,PLC在運(yùn)行過程當(dāng)中,Y3處于閉合狀態(tài),現(xiàn)在你要重新灌梯形圖了,這個(gè)時(shí)候你當(dāng)然希望Y3不再閉合了,而是等你重新下載梯形圖完畢以后,系統(tǒng)重新判斷Y3到底該不該為1。由于這個(gè)時(shí)候PLC并不斷電,那么調(diào)用INIT_START也就無(wú)從談起,也就無(wú)法調(diào)用那里面的清零語(yǔ)句。所以你必須要在INIT_SET把它兩給的值清除了,才能保證PLC的正常工作。

STEP
也是空的,沒必要配置~

下一講里,我們講TMS用戶驅(qū)動(dòng)子程序,也就是用戶2.5ms中斷了,這個(gè)可是個(gè)重點(diǎn)哦~^-^~!

本帖首發(fā)中國(guó)工控網(wǎng)科威PLC論壇,轉(zhuǎn)載請(qǐng)聲明!
lyq_4652
級(jí)別: *
精華主題: * 篇
發(fā)帖數(shù)量: * 個(gè)
工控威望: * 點(diǎn)
下載積分: * 分
在線時(shí)間: (小時(shí))
注冊(cè)時(shí)間: *
最后登錄: *
查看lyq_4652的 主題 / 回貼
8樓  發(fā)表于: 2008-08-08 10:49
實(shí)戰(zhàn)攻堅(jiān)!

下面我們講講該在TMS用戶驅(qū)動(dòng)子程序里面寫些什么代碼。

首先筆者得說(shuō)說(shuō)科威PLC的輸入端口采樣原理,為什么要進(jìn)行輸入端口采樣呢?答案很簡(jiǎn)單,就是為了濾波。在PLC實(shí)際運(yùn)行過程中,X端口可能會(huì)因?yàn)楝F(xiàn)場(chǎng)干擾收到一些毛刺信號(hào),這些毛刺信號(hào)如果不進(jìn)行處理,就會(huì)影響到PLC對(duì)X端口的狀態(tài)的判斷,那么我們必須得剔除掉這些毛刺,使系統(tǒng)工作在一個(gè)穩(wěn)定的環(huán)境。
我們規(guī)定,如果連續(xù)采樣8次X端口的值都是一致的,就判斷此刻X端口的狀態(tài)是實(shí)際的輸入狀態(tài),這個(gè)也就是為什么我們把INPUT_CNT這個(gè)變量設(shè)置為8的原因。

還是老規(guī)矩,筆者貼出TMS的代碼并為大家分析:
TMS
TMS:            MOV    C,KEY_SET            ;1
                MOV    P4.3,C                ;2
                MOV    C,PLC_PRO_ERR        ;3
                CPL        C                    ;4
                MOV    P4.2,C                ;5
                MOV    A,INPUT_CNT        ;6
                JNZ        TMS1                ;7
                RET        

TMS1:            DEC    A                    ;8
                MOV    DPTR,#XINPUT        ;9
                ADD    A,DPL                ;10
                MOV    DPL,A                ;11
                MOV    A,DPH                ;12
                ADDC    A,#00H                ;13
                MOV    DPH,A                ;14    
                MOV    A,P3                ;15
                MOVX    @DPTR,A            ;16
                DEC    INPUT_CNT            ;17
                RET

1.    第1~5句:這4條語(yǔ)句是給RUN/SET和ERR兩個(gè)燈賦狀態(tài)的。在原理圖中看到,由于ERR的LED與實(shí)際的P4.2中間反了一次向,故此在程序中也需要對(duì)此端口反向賦值。
2.    第6句:取INPUT_CNT當(dāng)前值賦給寄存器A
3.    第7句:這句是一句跳轉(zhuǎn)指令,作用是看對(duì)X輸入端口當(dāng)前的8次采樣完成了沒有,如果完成了,就直接返回,在SCAN用戶驅(qū)動(dòng)子程序會(huì)對(duì)其X0~X7寄存器的值進(jìn)行更新;如果8次采樣沒有完成,則跳轉(zhuǎn)到TMS1中進(jìn)行X輸入端口采樣。
4.    第8~16句:將P3端口的值(即當(dāng)前X輸入端口的采樣值)存放到從#XINPUT+7開始到#XINPUT一共8個(gè)單元。值得注意的是,完成8次采樣的時(shí)間為2.5ms * 8 = 20ms。也就是說(shuō),從第1次采樣開始到8次采樣結(jié)束需要20ms的時(shí)間。結(jié)束時(shí),#XINPUT~#XINPUT+7這8個(gè)單元的地址已被填充,等待SCAN用戶驅(qū)動(dòng)子程序的處理。這段程序通過改變采樣指針DPTR的DPH和DPL,使其指向不同的外部尋址單元,這個(gè)小技巧希望大家能夠熟練掌握。
5.    第17句:將INPUT_CNT減1。不要忘記這句話,否則你的程序?qū)⑹冀K填充#XINPUT+7這個(gè)單元的數(shù)據(jù),采樣指針永遠(yuǎn)也指不到#XINPUT+6和其以下的單元。

好了,TMS就給大家分析完了,下一講筆者將給大家講述最后一個(gè)部分:SCAN。

本帖首發(fā)中國(guó)工控網(wǎng)科威PLC論壇,轉(zhuǎn)載請(qǐng)聲明!
lyq_4652
級(jí)別: *
精華主題: * 篇
發(fā)帖數(shù)量: * 個(gè)
工控威望: * 點(diǎn)
下載積分: * 分
在線時(shí)間: (小時(shí))
注冊(cè)時(shí)間: *
最后登錄: *
查看lyq_4652的 主題 / 回貼
9樓  發(fā)表于: 2008-08-09 10:35
實(shí)戰(zhàn)攻堅(jiān)!

本節(jié),給大家講解針對(duì)EASY-M0806R這款PLC的SCAN用戶驅(qū)動(dòng)子程序該完成的功能。

通過前面的講解,大家應(yīng)該知道,SCAN是在梯形圖完成一次掃描以后被系統(tǒng)調(diào)用的程序,在這個(gè)程序里面,我們需要更新輸入輸出口的狀態(tài)以及LED的狀態(tài)。

SCAN
SCAN:            LCALL    USER_SCAN_O            ;輸出端口和LED更新
                LCALL    USER_SCAN_I            ;輸入端口和LED更新
                RET

USER_SCAN_O:  
;刷新輸出端口
MOV    DPTR,#RAM_PY+1        ;Y00--Y05
                MOVX    A,@DPTR
                CPL        A
                MOV    SFRPAGE,#0FH
                ANL    A,#3FH                    
                MOV    B,A
                MOV    A,P1
                ANL    A,#0C0H                    
                ORL    A,B                        ;使P1.6,P1.7保持原來(lái)的狀態(tài)
                MOV    P1,A                    ;刷新輸出
;刷新輸出LED
                 SWAP    A
                MOV    C,ACC.4            
                MOV    P0.4,C
                MOV    C,ACC.5
                MOV    P0.5,C
                MOV    C,ACC.6
                MOV    P0.6,C
                MOV    C,ACC.7
                MOV    P0.7,C
                MOV    C,ACC.0
                MOV    P4.1,C
                MOV    C,ACC.1
                MOV    P4.0,C
                RET

                        
USER_SCAN_I:  MOV    A,INPUT_CNT
                JZ        USER_SCAN_I1
                RET
                                                                
USER_SCAN_I1:    LCALL    USER_SCAN_IS    ;判斷8次采樣值是否相同    
                JB        F0,USER_SCAN_I2
                MOV    C,ACC.7            ;調(diào)整輸入口
                MOV    F0,C
                MOV    C,ACC.0
                MOV    ACC.7,C
                MOV    C,F0
                MOV    ACC.0,C
                MOV    C,ACC.6
                MOV    F0,C
                MOV    C,ACC.1
                MOV    ACC.6,C
                MOV    C,F0
                MOV    ACC.1,C
                MOV    C,ACC.5
                MOV    F0,C
                MOV    C,ACC.2
                MOV    ACC.5,C
                MOV    C,F0
                MOV    ACC.2,C
                MOV    C,ACC.4
                MOV    F0,C
                MOV    C,ACC.3
                MOV    ACC.4,C
                MOV    C,F0
                MOV    ACC.3,C
                MOV    INPUT_PORTA,A        ;相同則更新輸入數(shù)據(jù)寄存器
                MOV    DPTR,#RAM_PX+1    ;X00--X07
                MOV    A,INPUT_PORTA
                MOVX    @DPTR,A            ;更新X00--X07
;刷新輸入LED
MOV    A, INPUT_PORTA
CPL        A
                MOV    P2,A
USER_SCAN_I2:    MOV    INPUT_CNT,#08H
                RET

;判斷8個(gè)采樣數(shù)據(jù)是否相同,相同則F0=0
USER_SCAN_IS:    MOV    DPTR,#XINPUT
                MOVX    A,@DPTR
                MOV    M0,A
                MOV    R7,#7

USER_SCAN_IS1:    INC        DPTR
                MOVX    A,@DPTR
                CJNE    A,M0,USER_SCAN_IS2
                DJNZ    R7,USER_SCAN_IS1
                CLR        F0
                RET

USER_SCAN_IS2:    SETB    F0
                RET    

關(guān)于本段代碼的詳細(xì)說(shuō)明,筆者將改變一下方式,在下面的回帖為大家講解。當(dāng)然筆者在關(guān)鍵處已經(jīng)做了注釋,大家可以先看看并結(jié)合之前的程序研究一下,發(fā)帖提出問題,看看筆者的回答與自己的理解有何偏差。

如果沒有人發(fā)帖,筆者自然是希望看文章的朋友們都理解了筆者的代碼,就小小的懶惰一回吧,嘿嘿~!

當(dāng)然如果大家的問題很多,那么筆者就寫“科威PLC芯片組開發(fā)實(shí)例(十二)”,詳細(xì)給大家說(shuō)明SCAN中代碼的含義。

本帖首發(fā)中國(guó)工控網(wǎng)科威PLC論壇,轉(zhuǎn)載請(qǐng)聲明!