lyq_4652
級別: *
|
工欲善其事,必先磨其器。 做科威PLC芯片組開發,需要準備什么工具呢? 不必著急,給你一一道來: 1. KEIL2或者KEIL3,這個是必須的。下載地址筆者就不貼了,網上都有自己找。此款工具是你編寫驅動所必須的。當然你也可以用新華龍公司提供的編程工具Cynal來做,殊途同歸。 2. DOWNHEX,此軟件屬科威公司開發,專用于驅動下載。所以你不要用KEIL自帶的下載功能進行驅動下載,沒有用,非用此工具下載不可。要搞清楚的是,現在你需要編寫的只是驅動,科威PLC芯片組的實時操作系統會將你的驅動嵌入到系統內,驅動并不是要覆蓋這個系統,而只是補充此系統。驅動中你所編寫的功能會被操作系統調用并執行。DOWNHEX的作用,就是將你編寫的驅動形成的HEX代碼保存在芯片組中的一個固定區域,系統運行過程中會調用你寫的程序。 3. CANSET,此軟件也屬科威公司開發,專用于編寫CAN網絡設置參數,也就是說,你想要激活科威PLC芯片組的CAN網絡通訊功能,就必須使用這款工具。如果你不用到此功能,那你當然也可以不必使用此工具,但是做科威PLC芯片組開發不用到CAN功能,那可是暴殄天物,因為此功能可是科威PLC芯片組最大的亮點特色之一喲! 4. FX2N編程軟件,嚴格說起來,這個和編寫驅動沒有太大關系,但是,此軟件和科威PLC芯片組可是大大的有關系!這個軟件是編寫梯形圖的軟件,想要讓你的PLC運行梯形圖,當然還得靠它。 以上的前3種工具,筆者會在開發過程中告訴你應該怎樣使用,所以你只要先有個大概的概念即可。 除此之外,你還得有一本C8051F040的說明書,有許多寄存器的功能定義在使用過程中你非得查閱此書不可。網上有中文的和英文的版本,筆者用的是中文的,呵呵,如果喜好用英文的,那你是高手!什么?你已經把說明書的內容都爛熟于心了?那你是高手中的高手,這段話當我沒說…ORZ 在網上找到c8051F040.inc的頭文件,此頭文件包含了所有F040的寄存器地址定義,開發過程中需要把此文件加到你的工程之中。如果不加,那么你所用的所有F040的寄存器,編譯器都會提示你undefined。 還得找到easycore.inc以及easycore.lib兩個文件。具體這兩個文件的作用,我們以后再談。 在從事開發之前,如果你對F040完全不了解,建議你還是花個幾天時間閱讀一下它的說明書。當然,想要把它完全都看懂,沒有一定編程實際經驗的話,絕對是個不可能完成的任務。只需要在看了以后,能夠對此CPU的性能和各功能模塊有一定了解即可。說白了,筆者認為,此說明書存在的目的,就是為了能在開發過程中遇到的問題有個權威的查閱之處,而并不是去把它死記硬背,那是完全沒有必要的事情。 下一講,我們會正式進入正題,講解如何編寫一個簡單的驅動。 PS:在本文提到的各種工具和資料,如果各位懶得去搜索,直接把郵箱貼在下面,筆者看到了會給你發過去^-^。 本帖首發中國工控網科威PLC論壇,轉載請聲明! |
---|---|
|
lyq_4652
級別: *
|
如何搭建用戶驅動環境? 首先,教大家如何使用KEIL3創建一個用戶驅動工程(筆者目前用的是KEIL3,只能就此講解,所以你用的如果是KEIL2或者Cynal,那么就自行摸索,總的來說,功能上都相差不大。) 首先要注冊KEIL3,使之可以編譯超過2K范圍的代碼。至于怎么注冊,請在網上找,筆者不在此贅述。 新建一個文件夾,此文件夾為你將要做的項目文件夾(比如D:\PLC_DRIVE,以下的教程皆假定你的項目在此文件夾內來闡述)。 然后打開KEIL3,在菜單欄選擇Project→New Project…,將會彈出一個名為“Create New Project”的對話框,在對話框中選擇D:\PLC_DRIVE并雙擊進入,創建一個名為“PLCDR”的uv2文件。 接下來會彈出一個選擇芯片類型的對話框,下拉豎直條選擇“Silicon Laboratories, Inc.”展開選擇“C8051F040”,點擊確定。 隨后系統問你是否需要“Copy Standard 8051 Startup Code to Project Folder and Add File to Project?”,這句話的意思是問你是否需要為你的項目添加標準的8051規范。這個東西對我們這個項目的開發沒多大用,推薦你選擇否,反正筆者就是這么干的。 這個時候基本的項目框架就搭建起來了,現在是時候為你的驅動項目添加“血肉”了。 選擇菜單中的File→New…,點擊“保存”,將此Text1空白文檔保存在D:\PLC_DRIVE中,并更改此文件名為“PLCDR.ASM”,注意后綴名是“.ASM”而不是“.TXT”了。 這個時候,細心的你可能已經發現了,我們將會用51匯編來實現驅動程序的編寫。在這個匯編已經沒落,甚至連C也慢慢的被人拋棄的時代, C#,.NET,.COM,JAVA,J2EE等流行語言及技術大行其道的今天,我們為什么還要用匯編來編寫程序呢?而且是在KEIL也是支持C語言的情況下我們做出的選擇,看似更加的沒有道理。其實這是仁者見仁,智者見智的。在筆者看來,匯編雖然比C更加的晦澀難懂,但它最貼近硬件的特性卻能夠使我們的驅動程序更加的高效,在F040這個8位小型CPU上,使用匯編語言能更加讓我們“精打細算”,使我們的每條語句都精確到0.0X個US(科威PLC芯片組的系統時鐘頻率為24.5MHZ,也是F040所能達到的最高系統時鐘頻率),PLC是做什么的?當然是做控制的,所以實時性,高效性以及安全性是PLC永恒的話題。我們選擇匯編語言作為驅動程序的開發的理由也正因如此。當然,如果你對匯編一竅不通的話,筆者也建議你耐心把下面的教程看完,雖然匯編與C的差異性還是蠻大的,但是多多少少會對你對芯片組開發有一定的幫助。 呵呵,話題扯遠了,言歸正轉,你注意到左邊那個“Project Workspace”浮動工具欄沒?雙擊里面的Source Group 1,路徑選擇到“D:\PLC_DRIVE”,選擇“PLCDR.ASM”并點擊確定。什么?沒有這個“PLCDR.ASM”?那你得把文件類型改為“all files”才能看的到。個人BS了KEIL公司一下,居然連.ASM的文件類型都沒有…看來也是個喜新厭舊的主~ 這個時候,你會發現Source Group 1左邊有個小+號,點擊下拉,PLCDR.ASM躍然紙上了,哦不,是躍然于顯示屏上了。 至此,準備工作已經完成,下一講我們就要介紹此項目工程在KEIL中的一些參數設置,以及科威PLC芯片組用戶驅動開發所需要準備的幾個頭文件和函數庫。 本帖首發中國工控網科威PLC論壇,轉載請聲明! |
---|---|
|
lyq_4652
級別: *
|
到底我該怎么編寫一個用戶驅動呢? 上一講我們配置了用戶驅動在KEIL3中的工程環境,下面我們來談談PLCDR項目在KEIL中應該設置哪些參數。 首先,你得找到一個名為“Options For Target”的圖標,就是那個“LAOD”圖標旁邊那個象個魔法棒的圖案,點擊彈出“Options For Target Target1”對話框。當然你也可以選擇菜單的Project→Options For Target Target1來把此對話框調出。 找到OutPut選項,勾上下面的“Create HEX File ”的單選框,前面我們曾經說過,驅動加載到科威PLC芯片組中是要以HEX形式的文件通過DOWNHEX軟件下載來實現的。所以得讓KEIL給你生成一個HEX才行。 然后找到A51選項,將“Define 8051 SFR Names”前面的勾去掉。如果啟用這個功能,KEIL就會在編譯你的項目的時候,自動調用51默認的寄存器定義,那么就會和前面我們所提到的c8051F040.inc這個頭文件所定義的寄存器相沖突。結果會在你編譯項目的過程中,會出現一大堆的“redefined”錯誤。 除此之外,都默認就好,點擊確認完成參數配置。 接下來,將你找到的c8051F040.inc,easycore.inc以及easycore.lib這3個文件都復制到D:\PLC_DRIVE路徑下,并在此路徑下新建一個“USER_DATA.inc”的文件。 下面我們說說,這幾個文件的含義: 1. c8051F040.inc,這個筆者前面講過,不再重復; 2. easycore.inc,你可以打開它來看看,會發現這里面定義了用戶所可以用到的寄存器組還有相關的變量地址。F040中共定義了4個R0~R7寄存器組,用戶只能使用0區,其他的對不起,內核(我們習慣把芯片組內的實時操作系統稱之為內核,很形象,不是嗎?)都給占用了~然后是BRAM_USER,這個是用戶可用的位變量尋址,采用的是直接位尋址方式,一共可以定義32個位,也就是4個字節。少了點,可是沒辦法,內核占了大頭…DRAM_USER,這個是用戶可用的字節變量尋址,采用的是直接尋址方式,可以定義16個,還是少了點,但是還是沒辦法…-_-!最后是XRAM_USER,這個用戶能用的倒是多啊,有幾千個,但是可惜的是它是間接字節尋址。系統讀取這個區域的數據,那效率是刷刷往下降啊!但是還是得用,要不然變量不夠啊,呵呵。F040要是直接尋址的存儲空間再大些就好了,可是這是筆者的一相情愿,殘念……最后面就是有關梯形圖的變量地址空間了,你可以看到D,M,S等梯形圖內所用的這些寄存器在內核里面所占的地址。中間的那一塊暫時跳過不講,以后找機會給大家說明,不過可能有的讀者已經了解那些定義大概是什么意思了,不管了解不了解,讓我們繼續GO ON! 3. easycore.lib,這個庫直接從KEIL里面是看不了的,你想要看它,就從記事本里面看吧。里面是為了方便用戶所定義的一些系統函數,比如雙字節乘除,浮點數運算等等,如果你要調用這些函數,注意出口入口要設置對哦。 4. USER_DATA.inc,這個文件暫時是空白的,留給你自己發揮創造的,你可以在里面定義自己的位變量啦,字節變量啦,還有變量重定義等。比如你在里面寫一句“MODE_DATA EQU DRAM_USER ;模式選擇”,意思就是你將直接字節尋址的第一個單元賦予了MODE_ONOFF這個名字,那么你在驅動中就可以直接調用MODE_DATA這個變量啦。 后面那個分號以及分號以后的文字,是這條語句的注釋。在KEIL給51匯編加注釋有2中方法,一個是“;”,相當于C里面的“//”,另外一個和C相同,是“/* */”。 下一講,筆者將講述科威PLC芯片組開發用戶驅動的具體格式。 本帖首發中國工控網科威PLC論壇,轉載請聲明! |
---|---|
|
lyq_4652
級別: *
|
這一講里面將會講解科威PLC芯片組開發用戶驅動的具體格式。筆者始終認為,學編程,從看代碼開始是捷徑!所以,我們在PCLDR.ASM內添加以下一段代碼。 $INCLUDE(C8051F040.INC) ; Register definition file. -------------------1 $INCLUDE(easycore.INC) ; easycore 符號定義------------------------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 ;===============用戶應用程序調用入口==================== ORG 0E0A0H ;用戶端口初始化 LJMP INIT_CONFIG ;----------------------- --------------------18 ORG 0E0A3H ;用戶上電初始化 LJMP INIT_START ;----------------------- --------------------19 ORG 0E0A6H ;用戶設置初始化 LJMP INIT_SET ;----------------------- --------------------20 ORG 0E0A9H ;用戶運行初始化 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 然后點擊編譯,如無意外,KEIL將會編譯成功并生成“PLCDR.HEX”文件,該文件可以在項目路徑下找到。 至此,你的第一個驅動程序已經編寫完成。只不過這是一個簡單的驅動程序,簡單到什么也沒有的驅動程序。嘿嘿,如果把這段HEX代碼下到你的PLC內,PLC的IO口可能會亂跳的哦~不過,梯形圖的解釋倒是獨立于驅動之外的,加載了一個什么也沒有的驅動,PLC芯片組也是可以正常運行梯形圖的。 在下一講里,筆者將會逐句給你分析以上程序的每一條語句哦~其實從那些簡短的注釋里,相信不少讀者已經看出了些許端倪了。 本帖首發中國工控網科威PLC論壇,轉載請聲明! |
---|---|
|
lyq_4652
級別: *
|
上講驅動語句解釋: 在上面一講,筆者給出了一段基本用戶驅動語句段的代碼,下面是詳細解釋它們的時候了。 1. 第1~4句:是將3個頭文件和1個庫文件添加到你的驅動工程項目中,這個就不在解釋了。 2. 第5~24句:是將F040的中斷跳轉重定義,查閱F040的說明書我們可以看到,0X0003H是外部中斷0的代碼起始地址,在內核中,將外部中斷0的起始代碼重新定義到0E003H開始了。這里就產生了3個問題: ① 為什么要將中斷的起始代碼地址重定義? 答:這個是為了方便代碼管理,前面筆者曾經提到過,驅動下載到內核里,是存放在一 塊相應的地址空間由內核調用的。這個地址你現在可以看到,是從0XE000H開始的,由于用戶中斷也屬用戶驅動的一部分,所以,它的這部分代碼也必須保存到0XE000H以后的一個地址段內,而默認的中斷起始代碼從哪里開始呢?以外部中斷0為例,你可以從說明書上看到,它的起始地址是0X0003H,這樣用戶驅動流程代碼和用戶驅動中斷代碼就被分成了2個地址段,給內核的管理造成了麻煩。所以我們必須要進行中斷代碼地址重定義的工作。 ② 如何實現中斷的起始代碼地址重定義? 答:還是以外部中斷0為例,內核在這里直接用了一個“LJMP 0XE003H”即完成了地址重定義的工作,是不是很簡單? ③ 科威PLC芯片組還有其他的中斷重定義了嗎?我可以用它們嗎? 答:我們只能夠用到上面代碼給出的這些中斷,還有的中斷比如T0,T1等中斷已被內核占用,我們編寫用戶驅動就無緣使用它們啦! 3. 第18句:用戶I/O口配置程序:根據設計的輸入輸出功能配置相應的端口(推挽或者漏級),用戶不可配置的I/O口資源為P4.4、P4.5、P4.6、P4.7、P5、P6、P7及UART0。理由還是那句話:內核已占用…此段程序會在內核重新上電后調用一次。 4. 第19句:用戶上電初始化程序:用戶嵌入程序中用到的輸入輸出變量,中間變量,指針變量,位變量等在重新上電后必需進行初始化處理,此段程序在內核重新上電后調用一次。 5. 第20句:用戶設置初始化程序:內核重新上電后進入梯型圖下載狀態或內核從梯型圖運型狀態進入梯型圖下載狀態時調用此程序一次。 6. 第21句:用戶運行初始化程序:內核重新上電后第一次運行梯型圖或內核從下載梯型圖狀態進入梯型圖運行狀態時調用此程序一次。這個子程序大家可以看到,與上面一個的流程是相反的。 7. 第22句:用戶演算周期掃描程序:所有梯形圖執行完后,即調用該程序,調用周期為梯型圖演算周期,一般的數據處理、開關量輸入/輸出的刷新及代碼執行時間較長的程序均放在此程序中執行。 8. 第23句:用戶每步執行程序:梯形圖每執行一步,即調用此程序一次。需要快速執行的事件可在此程序或用戶中斷程序中完成,內核周期性地調用此程序,周期小于50US。 50US有多少個指令周期呢?我們可以算算:設1個指令周期的執行時間為t,系統時鐘頻率為f,那么1S=1000000US, f = 24.5MHZ,那么t = 1000000/24500000 = 0.04US,也就是說50US可以執行的指令周期數為50/0.04 = 1250個。這里有兩點需要說明一下,一條語句所占的指令周期并不一定只有一個,比如NOP指令所占的指令周期為1,但是CJNE指令就不止1個了,具體占了幾個筆者不記得了~,這個可以在說明書里面查到。另外一點是假設你編寫的總代碼折合成指令周期數是2000個,那是不是就不能滿足要求了呢?答案是不一定,只要你最長的一次執行過程所花費的指令周期數不超過1250個就行了,因為往往在程序里會有條件跳轉的代碼。舉個例子吧,假設你的STEP里面有2個條件執行過程A和B,A條件的執行過程一共有1100個指令周期,B條件有900個。雖然A+B一共有2000個超過了1250個,但是因為是條件跳轉,程序是不可能同時執行A和B的。所以算起來你的程序最長的指令周期數是1100個而不是2000個!哎呀,估計越講越難讓人理解了…打住,往下走吧,畢竟,計算每條語句所占用的系統時間并將其代碼優化都是些達人們,我們還是先看簡單的。 9. 第24句:用戶2.5mS定時運行程序:需要定時采樣的流程可放在此程序中完成,但該段程序代碼執行時間必須小于50 US。數據處理程序不宜放在此段程序中執行。注意這里是內核給提供的軟中斷,如果你的驅動里面沒有什么高級的中斷并頻繁發生,那么它就是2.5ms調用一次,很準!同時你得注意,它的返回語句不是“RETI”而是“RET”,為什么?因為它是“軟”的嘛,是內核給定義的,又不是F040的規范中斷,呵呵! 10. 第25句:用戶驅動程序編程起始位置,從這里往下就是你自由發揮的空間了哦~ 11. 第26句:別忘了給你的驅動程序加個完美的“句號”。 看到這里,你應該對科威PLC芯片組的開發有了一定的了解了吧。?完全沒了解??看來筆者的水平差了點,就請將就多看幾遍吧…-_-!不是有一句話就作“書讀百遍,其意自現”的么。有問題或不懂的給回下貼嘛,筆者看到了一定給你解答^-^~! 在下一講里面,就要開始實戰了,筆者將基于科威公司出產的EASY-M0806R這款PLC重新編寫IO驅動程序,手頭上有這款PLC的朋友也可以跟著做哦~! 本帖首發中國工控網科威PLC論壇,轉載請聲明! |
---|---|
|
lyq_4652
級別: *
|
實戰開始,苦手對象:EASY-M0806R 首先,我們得搞清楚,EASY-M0806R的IO引腳的分配情況,這款PLC有8個輸入點,6個輸出點,那么就相應的有8+6 = 14個IO引腳對應它們的輸入和輸出,對應原理圖我們得知: 8個輸入點對應的引腳是: 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個輸出點對應的引腳是: OUT0→P1.0 OUT1→P1.1 OUT2→P1.2 OUT3→P1.3 OUT4→P1.4 OUT5→P1.5 其次,每個輸入輸出點都對應一個LED,當輸入輸出點吸合的時候,對應的LED將被點亮,那么對應原理圖我們得知14個LED對應的引腳是: 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 與此同時,PLC還有一個RUN/SET的輸入,該輸入負責管理PLC的運行狀態和下載狀態,對應著不同的狀態,有一個專門LED點亮/熄滅來判斷此輸入的狀態,一般來說,運行狀態時,該LED被點亮,下載狀態則反之。根據原理圖我們得知: RUN/SET-LED→P4.3 PLC如果錯誤的被執行,應該還有一個錯誤的LED將被點亮,這個LED對應的引腳為: ERR-LED→P4.2 那么我們怎么得知PLC運行/下載的狀態,還有出錯的狀態呢?請看easycore.inc文件,有3個變量定義: KEY_SET EQU 3FH ;1有效(下載梯形圖) KEY_PRO EQU 3EH ;0有效(下載用戶程序) PLC_PRO_ERR EQU 3DH ;梯形圖錯誤標志,1有效 這個是我們前幾節所沒有講到的,通過檢測這些位變量,我們就可以對RUN/SET-LED和ERR-LED進行控制了。 知道了這些以后,我們就對EASY-M0806R的IO引腳分配有了大致的了解,趁此機會,我們把easycore.inc最后剩下沒講完的變量也拉出來遛一下吧~ M0~M15:這16個字節變量可是直接尋址方式的喲,但是應用它們有個局限性,那就是必須得在SCAN里面應用,其他地方是不允許調用這16個字節變量的,如果你非要在其他地方使用,那么就必須得把它們壓棧,不過還是不推薦此方法,真的要壓棧的話,還不如壓公共直接尋址變量區DRAM_USER區域呢。 FLOAT_M1~ FLOAT_M4,W_R0~ W_R7,W_DATA:這幾個變量是專門調用easycore.lib函數庫里面的函數所要用到的出口入口的變量。大致了解一下它們的含義便行,如果你到了需要調用easycore.lib函數庫里面的函數這個階段,那么本文對你來說,相信應該已經沒有多大意義了^-^~! 下一講我們將分模塊來詳細敘述如何根據我們所掌握的IO口引腳信息,來填充我們的驅動項目工程。 PS:本節所講的IO口配置可能會與實際IO口配置略有出入,大家當以實際的原理圖為準! 本帖首發中國工控網科威PLC論壇,轉載請聲明! |
---|---|
|
lyq_4652
級別: *
|
實戰攻堅! 上一講我們了解了EASY-M0806R的IO口分配情況以及各種LED的引腳情況,那么下面我們就要開始一步一步的編寫我們的驅動代碼了~ 首先是INIT_CONFIG用戶驅動子程序,該程序里面,要添加的內容在前文中已有說明。那我們該如何配置這些IO口方式呢? INIT_CONFIG 首先我們的第一句話便是: MOV SFRPAGE,#0FH 那么SFRPAGE是什么意思呢?呵呵,這就要看你對以前看的F040說明書熟悉程度了,什么?你完全不知道??-_-!那就現翻吧~筆者當年也好不到哪去,嘿嘿。 從說明書中可得知,這是一個選擇SFR頁數的功能寄存器,我們要調配IO端口的參數寄存器PnMDOUT,就首先得把SFR頁數置為15,這個是F040規劃的,就不再剝根問底了。值得提出的是,初學者常犯的一個錯誤就是在配置功能寄存器的時候,沒有及時更改它所屬的SFR頁數,導致程序運行錯誤。比如,配置了P0MDOUT功能寄存器,這個時候你是把SFRPAGE置成15了。但是在調配TMR4CN功能寄存器的時候,卻忘了把SFRPAGE改為2。這個時候錯誤便不可避免的出現了。 其次,我們開始配置上面所涉及到的EASY-M0806R的IO口的配置寄存器了,也許有的朋友會問到了,怎么初始化沒有延遲啊,選擇系統時鐘頻率啊,調配交叉開關啊?這些步驟確實是一個操作系統運行初始化所必須要配置的部分,但是在我們的驅動里面就不用重新配置了,因為內核里面已經定義過了一次。當然,也許你做的PLC有特殊的用途需要重新配置這些,那么也可以,不過還是那句話,時刻記住以內核為主,所以在重新配置這些之前你要考慮清楚怎么配置才不會和內核的配置起沖突。 科威PLC一般來說,輸入端口要配置成漏極方式,輸入端口要配置成推挽方式,LED也都是推挽方式。當然具體的要視其原理圖決定。根據這個原則,我們配置了下面4條語句: ORL P0MDOUT,#0F0H ;1 ORL P1MDOUT,#3FH ;2 ORL P2MDOUT,#0FFH ;3 ANL P3MDOUT,#00H ;4 ORL P4MDOUT,#03H ;5 也許細心的你會問:為什么都要用ORL和ANL指令而不是用MOV呢?這個就是筆者的習慣了,ORL和ANL指令的好處是只用改變你所需要的位,而其他的可以保持不變,以免引起不必要的錯誤。 我們來分析這4句話的含義: 1. 這句是配置P0端口的輸出方式的,由上一講我們得知,整個驅動用到P0口的有: OLED0→P0.4 OLED1→P0.5 OLED2→P0.6 OLED3→P0.7,由于LED需要配置成推挽輸出方式,那么我們就將P0MDOUT的高4位都配置成1即可。 2. 這句是配置P1端口的輸出方式的,整個驅動用到P1口的有: OUT0→P1.0 OUT1→P1.1 OUT2→P1.2 OUT3→P1.3 OUT4→P1.4 OUT5→P1.5,由于輸出端口需要配置成推挽輸出方式,那么我們把P1MDOUT的低6位都配置成1即可。 3. 這句是配置P2端口的輸出方式的,整個驅動用到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端口的輸出方式的,整個驅動用到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,由于輸入端口需要配置成漏極輸出方式,故我們把整個P3口輸出都配置成0。 5. 這句是配置P4端口的輸出方式的,整個驅動用到P4口的有: OLED4→P4.1 OLED5→P4.0,同理,我們把P4MDOUT的低2位配置成1。 這樣,整個INIT_CONFIG便配置完成了。下一講筆者將講述其他用戶驅動子程序在EASY-M0806R上的實現。 本帖首發中國工控網科威PLC論壇,轉載請聲明! |
---|---|
|
lyq_4652
級別: *
|
實戰攻堅! 上面一講我們講述了該如何對照原理圖的引腳分配情況來配置你的INIT_CONFIG子程序,這一講筆者說說其他3個初始化應該如何編寫。 我們先在USER_DATA中定義幾個用戶變量: INPUT_PORTA EQU DRAM_USER INPUT_CNT EQU DRAM_USER+1 XINPUT EQU XRAM_USER 在解釋這些變量的含義之前,我們首先聊下PLC的工作狀態。 PLC的輸入端口是和梯形圖中的X端口相對應的,也就是說,短接I0和COM0(輸入端口統一地端子),梯形圖中的X0將會吸合,反應在元件監控畫面上X0右邊會出現綠色的實心小正方形,表示它的觸點已被吸合。同理,I0~I7對應的便是X0~X7。 而PLC的輸出端口是和梯形圖中的Y端口相對應的,當用戶在梯形圖中把Y0置1或是元件監控里把Y0強制置1,那么O0端子便和COM1自動短接了。同理,O0~O5對應的便是Y0~Y5。在PLC端子口上是看不到I0和O0的,但是有它們對應的X0和Y0。 下面我們講講這幾個用戶變量: INPUT_PORTA:用來保存當前8個輸入端口的輸入狀態(X0~X7)的。 INPUT_CNT:輸入端子采樣次數指針。 XINPUT:輸入端子采樣值緩沖區。 這些概念朋友們先大概了解一下便好,至于怎么應用到它們,后面還會具體講到。 INIT_START 接下來,我們開始編寫INIT_START用戶驅動子程序了,添加的代碼如下: 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這個變量初始化為8,這也就意味著,采樣的次數我們限定它為8次,如果你設置成4,那么輸入端口的采樣次數就為4,現在只要知道這些就好,我們以后在講到TMS這個用戶驅動子程序時,會詳細給大家分析為什么采樣輸入端口以及如何采樣它。 2. 不用講了吧… 3. 這個是將間接尋址指針指向X0~X7所在的地址單元,間接尋址指針的表達方式有2種,筆者慣用的是以DPTR形式來進行尋址。至于另外一種,呵呵,自己查說明書吧。 4. 這句話的意思是把寄存器A的值賦給X0~X7,因為A的值為0,實際上這句話的作用就是把X0~X7所代表的寄存器的值清零。看到這里,可能有的朋友就又有問題了,為什么X0~X7所在的地址不是#RAM_PX而是#RAM_PX+1呢,其實這個是和內核定義梯形圖單元的尋址地址有關。內核規定,梯形圖的單元寄存器都是低位在后,高位在前,也就是說,#RAM_PX并不是對應的X0~X7,而是X10~X17。 5. 這個是將間接尋址指針指向Y0~Y7所在的地址單元。 6. 同4。 INIT_RUN 直接讓它返回吧,在這個系統里面,沒必要配置這個。 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的寄存器值,那為什么在這里又要清零呢?會不會跟之前的重復了呢? 當然不會,注意到系統會在什么時候調用INIT_SET呢?是在內核重新上電后進入梯型圖下載狀態或內核從梯型圖運型狀態進入梯型圖下載狀態時調用此程序一次。 看到了吧,PLC在不斷電的情況下,也會在上面黑體的部分調用到它,舉個例子,PLC在運行過程當中,Y3處于閉合狀態,現在你要重新灌梯形圖了,這個時候你當然希望Y3不再閉合了,而是等你重新下載梯形圖完畢以后,系統重新判斷Y3到底該不該為1。由于這個時候PLC并不斷電,那么調用INIT_START也就無從談起,也就無法調用那里面的清零語句。所以你必須要在INIT_SET把它兩給的值清除了,才能保證PLC的正常工作。 STEP 也是空的,沒必要配置~ 下一講里,我們講TMS用戶驅動子程序,也就是用戶2.5ms中斷了,這個可是個重點哦~^-^~! 本帖首發中國工控網科威PLC論壇,轉載請聲明! |
---|---|
|
lyq_4652
級別: *
|
實戰攻堅! 下面我們講講該在TMS用戶驅動子程序里面寫些什么代碼。 首先筆者得說說科威PLC的輸入端口采樣原理,為什么要進行輸入端口采樣呢?答案很簡單,就是為了濾波。在PLC實際運行過程中,X端口可能會因為現場干擾收到一些毛刺信號,這些毛刺信號如果不進行處理,就會影響到PLC對X端口的狀態的判斷,那么我們必須得剔除掉這些毛刺,使系統工作在一個穩定的環境。 我們規定,如果連續采樣8次X端口的值都是一致的,就判斷此刻X端口的狀態是實際的輸入狀態,這個也就是為什么我們把INPUT_CNT這個變量設置為8的原因。 還是老規矩,筆者貼出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條語句是給RUN/SET和ERR兩個燈賦狀態的。在原理圖中看到,由于ERR的LED與實際的P4.2中間反了一次向,故此在程序中也需要對此端口反向賦值。 2. 第6句:取INPUT_CNT當前值賦給寄存器A 3. 第7句:這句是一句跳轉指令,作用是看對X輸入端口當前的8次采樣完成了沒有,如果完成了,就直接返回,在SCAN用戶驅動子程序會對其X0~X7寄存器的值進行更新;如果8次采樣沒有完成,則跳轉到TMS1中進行X輸入端口采樣。 4. 第8~16句:將P3端口的值(即當前X輸入端口的采樣值)存放到從#XINPUT+7開始到#XINPUT一共8個單元。值得注意的是,完成8次采樣的時間為2.5ms * 8 = 20ms。也就是說,從第1次采樣開始到8次采樣結束需要20ms的時間。結束時,#XINPUT~#XINPUT+7這8個單元的地址已被填充,等待SCAN用戶驅動子程序的處理。這段程序通過改變采樣指針DPTR的DPH和DPL,使其指向不同的外部尋址單元,這個小技巧希望大家能夠熟練掌握。 5. 第17句:將INPUT_CNT減1。不要忘記這句話,否則你的程序將始終填充#XINPUT+7這個單元的數據,采樣指針永遠也指不到#XINPUT+6和其以下的單元。 好了,TMS就給大家分析完了,下一講筆者將給大家講述最后一個部分:SCAN。 本帖首發中國工控網科威PLC論壇,轉載請聲明! |
---|---|
|
lyq_4652
級別: *
|
實戰攻堅! 本節,給大家講解針對EASY-M0806R這款PLC的SCAN用戶驅動子程序該完成的功能。 通過前面的講解,大家應該知道,SCAN是在梯形圖完成一次掃描以后被系統調用的程序,在這個程序里面,我們需要更新輸入輸出口的狀態以及LED的狀態。 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保持原來的狀態 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 ;調整輸入口 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 ;相同則更新輸入數據寄存器 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個采樣數據是否相同,相同則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 關于本段代碼的詳細說明,筆者將改變一下方式,在下面的回帖為大家講解。當然筆者在關鍵處已經做了注釋,大家可以先看看并結合之前的程序研究一下,發帖提出問題,看看筆者的回答與自己的理解有何偏差。 如果沒有人發帖,筆者自然是希望看文章的朋友們都理解了筆者的代碼,就小小的懶惰一回吧,嘿嘿~! 當然如果大家的問題很多,那么筆者就寫“科威PLC芯片組開發實例(十二)”,詳細給大家說明SCAN中代碼的含義。 本帖首發中國工控網科威PLC論壇,轉載請聲明! |
---|---|
|