EMC++ 使用手冊
EMC++ 是國內自行開發的八位元單晶片高階指令程式
特點如下:
1.直接使用在組合語言文字檔案下
2.可外掛程式檔,具有5層能力
3.提供函數sin,cos,..等運算
4.有 +,-,*,/ ..等很多運算符號
5.BIT單ㄧ名稱變數
6.BIT之布林代數之運算
7.左右旋之多重參數設定
8.加減法可含C旗標之巨集運算
9.函數庫之呼叫,並可傳遞或返回引數
10.高階指令之使用,具有32層處理能力,位元及位元組均可使用
IF - ELSE - ENDIF
FOR - NEXT -CONTINUE - BREAK
DO - WHILE - BREAK
SWITCH - CASE - DEFAULT - ENDS - BREAK
11.自動跳、切頁處理
12.EMC-ICE線上直接編輯簡易語言程式
目錄
(V1.04)
0.作者的話
1.KEYPRO安裝
2.軟體安裝
3.程式編輯
4.工作環境設定
5.常數(函數SIN...)之使用
6.定義與字串之使用
7.四則運算、邏輯運算、左右旋、I/O設定
8.BIT宣告與使用
9.函數宣告與使用
10.IF-ELSE-ENDIF指令說明
11. FOR-NEXT-CONTINUE-BREAK指令說明
12.DO-WHILE-BREAK指令說明
13.SWITCH-CASE-DEFAULT-ENDS-BREAK指令說明
14._IF,_FOR之使用(EMC,PIC適用)
15.切頁設定(跳曜、函數呼叫及返回)
16.各系列晶片補充說明
17.ELC.LIB之設定與PE2.EXE之使用
18.範例程式功能說明
19.其它
0.作者的話
0.1 嗨!您好,首先感謝您購買本軟體,在使用本軟體以前,作者希望您已經會使用以下的軟體,一:文書編輯器、二:單晶片的組譯程式、三:單晶片ICE或相關程式,若以上這些程式都還不會用時,請先不用使用本軟體,因為會找不出錯誤出在那個程式上,當上面軟體都沒有問題時,作者也希望您對您所使用的單晶片先瞭解一下,或者先看看作者所附的示範程式等等,這樣會比較好,因為不同的晶片在本軟體下,使用上會有點差異,當上面都沒有問題時,那就恭喜您啦 ^_^ ,本軟體將會帶給您設計上的便利喔!
0.2 另外,本使用說明書前面章節所講述的為共用指令,若為較特殊或各系列晶片應注意事項,在第16章節會補充說明,若還有任何本軟體上的疑問,歡迎使用E-mail寫信給作者,若是想取得晶片最新的消息,請翻至第19章,那兒有提供各廠商的網址.
0.3 因本軟體會不斷地更新版本,甚至至windows版本,故作者希望您有E-mail帳號,這樣就能即時獲得最新版本.
0.4 本磁片所附之檔案,無附送其組譯程式,請向其IC代理商索取,因牽涉軟體使用權等問題...或經其原公司同意後,才加以附贈之.
0.5 本說明書所轉換出來之指令碼,是以EMC晶片指令為藍本,若讀者想取得該使用晶片之指令時,建議讀者邊學習邊操作,這樣對學習的效果較佳,並同時可以瞭解本軟體所轉換出的指令架構.
1.KEPPRO之安裝
1.1 請將KEYPRO安裝在電腦之印表機埠上,程式會自動搜尋,並顯示其KEYPRO之序號及支援晶片在螢幕上,如無安裝KEYPRO時,軟體無法繼續往下執行.
1.2 如KEYPRO安裝後,仍無法執行時,可能電腦正在執行印表作業或與其它KEYPRO相互衝突,此時先將其它KEYPRO拔除,單一安裝KEYPRO再進行測試.
1.3 並列埠之設定,可在執行程式ELC.EXE後加上參數/L1(代表LPT1)、/L2(代表LPT2)及/L3(代表LPT3),如果加上參數後,程式就不會進行掃描,可防止與其它並列埠之衝突,但輸入參數時,須先知道目前KEYPRO安裝在那一並列埠上,否則程式將無法執行.
1.4 若使用EMC-ICE時,且KEYPRO裝在其ICE與連接線之間時,此時必須將KEYPRO內部電路做調整,先將KEYPRO外殼須拆開來,會找到KEYPRO字樣,其下方之200歐姆電阻換成一50歐姆電阻,若以後又改接印表機時,再接回200歐姆電阻即可,方可使用,出廠時KRYPRO為設定接50歐姆(EMC的KEYPRO),其餘晶片為設定接200歐姆電阻.
1.5 在此建議KEYPRO獨立使用,連印表機之排線亦不要連接.
2.軟體之安裝
2.1 請執行磁片上之程式INSTALL.BAT,安裝程式會在硬碟(C:)中建立一子目錄(C:\ELC),並將所有程式安裝完成,簡易語言執行檔為ELC.EXE,欲執行晶片程式轉換時,只要執行ELC.EXE即可,ELC.EXE輸入參數如下:
指令
[ELC.EXE](輸入檔名) (輸出檔名) (/L1...)
範例
C:\>ELC DEMO.ELC DEMO.DT /L1 (ENTER)
執行的畫面:
3.程式編輯之流程
3.1 本軟體程式執行之流程:
『程式撰寫』>『簡易語言程式轉換』>『進行組譯』>『ICE測式』>『程式完成』
3.2 『程式編輯』,與一般寫組合語言是一樣的,並且多加了簡易語言的指令,當在撰寫程式時,可以用原來的組合指令,也可以用簡易語言的指令,相互使用之.
範例
NOP ;原組合指令
NOP ;
A=DATA+2 ;簡易語言指令
…
3.3 『簡易語言轉換』,當程式編輯好了以後,就可執行程式轉換,也就是執行ELC.EXE此程式,此程式可放入批次檔內使用,或者直接執行ELC.EXE程式,再輸入檔名也可以,一些訊息都會顯示在WORK MESSAGE之視窗中,包含程式那裡錯了,都會顯示之,若要離開,只要按ESC即可,當轉換後,會產生標準指令檔案外,另產生程式的錯誤檔(*.ERR),與程式的資訊檔(*.INF)等.
範例
C:\>ELC DEMO.ELC DEMO.DT /L1 (ENTER)
經轉換後產生DEMO.DT與DEMO.ERR與DEMO.INF等檔案
3.4 『組譯』,是將組合語言轉換成機械碼的一個程式,當轉換出來的機械碼檔案,就可燒寫在單晶片上,或使用在ICE上.
範例
C:\>COMPI DEMO.DT (ENTER)
3.5 『ICE模擬』,是模擬單晶片的一個電子工具,可以看程式是如何執行的,或抓出程式的問題,是很好用的工具,EMC-ICE須搭配本軟體所附的PE2.EXE(後面說明)使用,這樣就可在使用EMC-ICE時,直接線上編輯簡易語言之程式.
3.6 INCLUDE之使用,在程式編輯中,可以使用假指令INCLUDE來含入其它的程式檔案,好像本軟體所用的MATH.H,若在程式中有用到乘與除,則須含入MATH.H此檔案.
語法
[#INCLUDE] [FILE.NAME]
範例
#INCLUDE MATH.H
4. 環境設定
4.1 在本軟體執行轉換後,會將原簡易語言之指令,轉換成註解,形成與指令之對照表,而註解之功能,有以下參數之設定,在本軟體一開始執行式,內定為產生對照表模式,從第23字元開始.
語法
[#DOC] [+,-,NUMBER]
範例
#DOC + ;產生對照表
#DOC 23 ;從第23字元開使產生對照表
範例二
A=A+2
經轉換後
ADD A,@2 ; A=A+2
5. 常數(函數)之使用
5.1 本章所講的是對一些常數或函數之運用,好像大家都背過九九
乘法
99乘法表99乘法表打印九九乘法表a4打印九九乘法表免费下载大九九乘法表免费打印
表,但12*13就沒有背過了,像這類的運算均可交給此軟體處理,本軟體的運算符號有四則運算加減乘除,邏輯運算或(OR)和(AND)及互斥(XOR),比較式有等於(==),大於(>)...,以下將列出其運算符號,並將從最高優先運算開使排起.
運算符號一欄表
優先權
運算符號
說 明
1
( )
為左右括號,裡面之運算,最優先處理
2
!,~,++,--
!為反相,~為補數,++為加一,--為減一 之運算
3
*,/,%
*為乘法,/為除法,%為餘數 之運算
4
+,-
+為加法,-為減法 之運算
5
<<,>>
<<為左旋,>>為右旋 之運算
6
<,<=,>,>=
為比較符號
7
==,!=
為比較符號
8
&
為和(AND)之運算
9
^
為互斥(XOR)之運算
10
|
為或(OR)之運算
11
&&
為比較符號,進行AND運算
12
^^
為比較符號,進行XOR運算
13
||
為比較符號,進行OR運算
範例(以下所使用A為假設各晶片之暫存器,如PIC為W,EMC為A等等)
A=10+2*3 ;得A=16
A=10<<2 ;得A=40
A=10>5+1>2 ;得A=0
A=10*(1|2) ;得A=30
5.2 常數之種類
5.2.0 常數之種類亦指我們平常所看到的數字,但我們所接受的都是十進制,在電腦的世界裡,都是二進制,因二進制不易理解,而產生出來的種類有二進制,八進制,十進制,及十六進制,故在此介紹各位如何輸入各進制的常數方法.
進制種類一欄表
項次
進制種類
範例
1
2
0B100,0B001
2
8
0123,011
3
10
1234,321
4
16
0X12A,0XFF
5
16
2CH,0ABH,12H
5.2.1 『二進制』,只有0與1,在0與1的最前面加上0B就代表此數字為二進制,如0B111為十進制的7,其值是一樣的.
5.2.2 『八進制』,只有0至7,在數字最前面加上0就代表此數字為八進制,如輸入011,為十進制9,其值是一樣的.
5.2.3 『十進制』,只有0至9.
5.2.4 『十六進制』,有0至9及A至F等,在數字前面加上0X或在數字後面加上H都是為十六進制,但0X是為標準十六進制模式,建議您採用0X模式,但有些組譯軟體不接受0X模式,故此,您必須先瞭解組譯軟體所能接受之種類,在本軟體中,若用0X模式時,轉換出來之值,均為十進制,然而有些為晶片之假指令,如ORG等,這些一般都採用XXXXH模式,故此,若是用本軟體之指令其兩種模式都可以使用,而組譯器或是其晶片之指令,須看其原廠之使用手冊.如 0XA0 與 0A0H 均為十進制160,其值是一樣的.
範例
A=0B11+0X10 ;得A=19
A=0X123 ;得A=23,因A為8BIT暫存器
若想得高位元,可寫以下之式子
A=0X123/256 ;得A=1
5.2.5 指數之用法,當我們在輸入一個很大的數字時,且此數字後面有許多個零時,可以用指數的方式加以輸入.
語法
[NUMBER][E](+,-)[NUMBER]
範例
A=1E2 ;得 A=100
A=12E6/4 ;得 A=3E6
A=1000E-2 ;得 A=10
5.3數學函數之使用
5.3.0 函數是相當重要,在數學函數中,扮演著重要的角色,在此介紹函數的使用方法,然而這些函數最終轉換為常數,也就是說它不是程式,而是在本軟體已經先換算好了,所以輸入之值必為常數,而非變數,而程式函數是自己要開發的,好像本軟體所用的乘與除是要另外寫程式而變成一程式函數等.
常數函數一欄表
項次
語法
說 明
1
SIN(n)
求得正弦函數
2
COS(n)
求得餘弦函數
3
TAN(n)
求得正切函數
4
ABS(n)
求得絕對值
5
SQRT(n)
開根號
6
INT(n)
求得整數
5.3.1 SIN為數學函數,用來求得正弦函數數值,此SIN為徑度量,其一圓周之範圍為0至2*3.141592,當然這些值可以是倍數或任意值,而SIN所輸出之值為0至1,所以一般都必須乘上一常數,以8BIT來講,都乘以255或乘以100,而其輸出範圍就會變大,當然您也可以乘以更大,只是多占些程式碼而以,但確能提高準確度.
語法
SIN(NUMBER)
範例
A=SIN(3.141592/2)*100 ;得A=100,因為90度角
A=SIN(3.141592/4)*100 ;得A=70,因為45度角
5.3.2 COS為數學函數,用來求得餘弦函數值,用法與SIN一樣.
語法
COS(NUMBER)
5.3.3 TAN為數學函數,用來求得正切函數值,用法與SIN一樣.
語法
TAN(NUMBER)
5.3.4 ABS(NUMBER)為數學函數-絕對值,其輸出都是正數.
語法
ABS(NUMBER)
範例
A=ABS(-10) ;得A為10
5.3.5 SQRT(NUMBER)為數學函數-開根號.
語法
SQRT(NUMBER)
範例
A=SQRT(9) ;得A為3
5.3.6 INT為數學函數-整數.
語法
INT(NUMBER)
範例
A=INT(10.123) ;得A為10
綜合範例
A=10+(SIN(3.141592/4)*100<<1) ;得A=151
A=!(10>5)*100 ;得A=0
6. 定義與字串之使用
6.1『定義』,定義之用途是將程式中與TXT1相同之文字改成TXT2之文字,此用於程式之最前面幾行,通常程式用到的常數如果是一樣而且很多時,用定義來表示時,就很好用,不必改一大堆,而且還有可能漏掉而沒有改到,造成程式的BUG.其中TXT1為一文字,不能為一數字,TXT2可以為任易字串,TXT1與TXT2以空白字元作區分.
語法
[#DEFINE] [TXT1] [TXT2]
範例
#DEFINE ABC DATA
DATA=2
A=ABC+3 ;得A=5
6.2 『字串定義』,上面我們曾說過常數的種類設定,現在要說明字串或文字的定義,在本軟體裡,我們使用單引號或雙引號來表示,單引號表示法‘TXT’,雙引號表示法“TXT”,內部的TXT文字將被轉成常數,或一堆常數變成程式碼,一般來講單引號所含的TXT通常只有一個文字,而此文字將被轉成ASCII碼,若在單引號內之TXT僅有一個文字,本軟體會轉換成常數(如‘A’,得常數65),若兩個以上時,則被轉成字串常數,無法做常數運算,須注意.而雙引號之文字(TXT)通常都是兩個以上,而轉成一堆ASCII碼,若只有一個文字時,亦被當做字串,與單引號不同之處.在此介紹RETNRUN與字串之用法,在指令RETURN後面可加上一字串或多字串或常數或多常數,而用逗號加以隔開,這樣的用法通常都是用來建資料表,故此若您用這樣來建表,RETURN指令不會支援切頁功能,純資料建表功能,RETURN切頁功能將在後面詳加敘述之.
語法
RETURN [TXT,NUMBER],(TXT,NUMBER)...
範例
RETURN 'ABC',123,4+3
經轉換後
RETL @65 ;RETURN 'ABC',123,4+3
RETL @66 ;
RETL @67 ;
RETL @123 ;
RETL @7 ;
6.2.1 字串其它設定,如果您學過C語言,就知道字串中的“\n”是在做什麼,以功能來講,是換行的功能,以資料來講地話,只是常數10而已,但在鍵盤上找不到其鍵碼,故此,我們知到“\n”是擴充碼,方便我們之輸入,而字元‘\’就是關鍵字,其後‘n’是其識別碼,不同的識別碼,可轉出不同的相對碼或功能,在本軟體中,也是以字元‘\’為關鍵字,而其後的字元為識別字元,以下將列出所有的識別字元(注意大小寫)與其功能,若不在列出之中之字元時,將會被轉換成自己的ASCII碼(如‘\1’得49).
識別字元一欄表
識別字元
數值
功 能(以電腦而言)
a
7
BEL 嗶一聲
b
8
BS 退一字元(BACK SPACE)
f
0xc
FF 每頁最前頭,即第一行
n
0xa
LF 跳一行
r
0xd
CR 到第一字元,即歸位
t
9
HT 水平TAB移動
v
0xb
VT 垂直TAB移動
範例
RETURN '\n','\a','\1','\n'+'\a'
經轉換後
RETL @10 ;RETURN '\n','\a','\1','\n'+'\a'
RETL @7 ;
RETL @49 ;
RETL @17 ;
6.2.2 在字串中,若使用單引用時,其雙引號之字元可以直接使用之,反之若用雙引號時,單引號之字元可以直接使用之,若使用單引號時,且其字串有單引號之字元時,須用‘\’字元加以處理,雙引號亦是一樣.
範例
RETURN '"\''
RETURN "\"'"
經轉換後
RETL @34 ; RETURN '"\''
RETL @39 ;
RETL @34 ; RETURN "\"'"
RETL @39 ;
7. 四則運算、邏輯運算、左右旋、I/O設定
7.1 在本章所講的運算,均會轉成指令碼,而且有一定的輸入語法,這些語法有用到的種類(運算元素)有常數(NUMBER)、變數(RAM)、暫存器(W或A),在常數部分可以事先由許多的常數先進行運算,但最後只須剩下一個常數,不管這常數是否超過255,或者是含有小數等等,均以LOW位元組處理之;而變數可分為BYTE與BIT兩種變數,在此以“BYTE”與“BIT”做為變數符號,變數是為晶片內部的記憶體,在程式前端須先宣告其位置,在組譯時才不會發生錯誤;暫存器也是晶片內部的記憶體,但與變數不同的是在晶片指令裡以有此暫存器之定義,所以不必宣告其位置,如8051為A,PIC為W,EMC為A等等,在此以‘A’為暫存器之符號.在以下之語法中以‘[...]’代表元素體,而內部為運算元素,每個元素以逗點(‘,’)分開,而以多個‘[..]’(元素體)形成一種語法,另外介紹另一元素體為‘(...)’,其意義是為其中的元素可用或不用.
7.2 在BYTE前面若加在‘&’字元,則代表其BYTE的記憶體位置,會變成一常數處理之,但先前須先定意(EQU等),方可使用,否則無效.
語法
[&][BYTE]
範例
DATA EQU 10H
A=&DATA+2 ;得A為12H
7.3 I/O設定,在EMC晶片中,I/O腳為輸出或輸入,是有一方向暫存器加以控制,而如何設定呢?由下列之兩語法處理之.
語法一
[!BYTE][=][A,BYTE,NUMBER]
說明
存入方向控制暫存器
語法二
[A,BYTE][=][!BYTE]
說明
讀取方向控制暫存器
7.4 另EMC晶片有一模態設定暫存器,其設定方法如下.
語法一
[!OPTION][=][A,BYTE,NUMBER]
說明
存入模態設定暫存器
語法二
[A,BYTE,NUMBER][=][!OPTION]
說明
讀取模態設定暫存器
綜合範例
!OPTION=7
!P6=0B10101111
經轉換後
MOV A,@7 ; !OPTION=7
CONTW ;
MOV A,@175 ; !P6=0B10101111
IOW P6 ;
7.5 運算符號表:
項次
名稱
符 號
1
運算符號_1
+,-,*,/,%,&,^,|,<<,>>
2
運算符號_2
=,+=,-=,*=,/=,%=,&=,^=,|=,<<=.>>=
3
運算符號_3
~,!
4
比較符號
==,>,<,>=,<=,!=,(&,^,|,BYTE使用),(&&,^^,|| (BIT使用)
7.6 四則運算語法表
(注意,以下之運算語法有可能破壞A值,所以不要在A暫存器中存任何重要之變數)
項次
語 法
說 明
1
[A,BYTE][=][A,BYTE,NUMBER]
資料搬移
2
[A,BYTE][=&][BYTE]
資料位置搬移
3
[A,BYTE][運算符號_2](~)[A,BYTE,NUMBER][...]
取補數
4
[++,--][A,BYTE]或[A,BYTE][++,--]
加減一
5
[A,BYTE][=][++,--][A,BYTE]
先加減一後做搬移
6
[A,BYTE][=][A,BYTE][++,--]
先搬移後做加減一
7
[A,BYTE][+=,-=][A,BYTE]
加減法,先加減後回存
8
[A,BYTE][=][A,BYTE,NUMBER][+,-][A,BYTE,NUMBER]
兩變數做加減後回存
9
[A,BYTE][<<=,>>=][NUMBER](+C,+_1,+_0)
若無參數時,為暫存器本身自旋之,若為+C時則暫存器左右旋並含C旗標,_1與_0為旋入C之值
10
[A,BYTE]=[A,BYTE,NUMBER][<<,>>][NUMBER]
(+C,+_1,+_0)
(同上),最後再做搬移
11
[A,BYTE][&=,^=,|=][A,BYTE,NUMBER]
AND,XOR,OR運算
12
[A,BYTE][=][A,BYTE,NUMBER][&,^,|][A,BYTE,NUMBER]
AND,XOR,OR運算
13
[A,BYTE][*=,/=,%=][A,BYTE,NUMBER]
乘、除、餘數運算
14
[A,BYTE][=][A,BYTE,NUMBER][*,/,%][A,BYTE,NUMBER]
乘、除、餘數運算
語法(1) 資料搬移
[A,BYTE][=][A,BYTE,NUMBER]
指令圖解
範例
DATA == 0x10
DATA2 == 0x13
DATA2=DATA
語法(2) 資料位置搬移
[A,BYTE][=&][BYTE]
指令圖解
範例
DATA == 0x10
DATA2 == 0x13
DATA2=&DATA
語法(3) 取補數
[A,BYTE][運算符號_2]
(~)[A,BYTE,NUMBER][...]
指令圖解
範例
DATA == 0x10
DATA2 == 0x11
DATA2=~DATA
語法(4) 加減一
[++,--][A,BYTE]或[A,BYTE][++,--]
指令圖解
範例
DATA == 0x10
DATA++
語法(5) 先加減一後做搬移
[A,BYTE][=][++,--][A,BYTE]
指令圖解
範例
DATA == 0x10
DATA2 == 0x11
DATA2=++DATA
語法(6) 先搬移後做加減一
[A,BYTE][=][A,BYTE][++,--]
指令圖解
範例
DATA == 0x10
DATA2 == 0x11
DATA2=DATA++
語法(7) 加減法,先加減後回存
[A,BYTE][+=,-=][A,BYTE]
指令圖解
範例
DATA == 0x10
DATA2 == 0x11
DATA2+=DATA
語法(8) 兩變數做加減後回存
[A,BYTE][=][A,BYTE,NUMBER][+,-]
[A,BYTE,NUMBER]
指令圖解
範例
DATA == 0x10
DATA2 == 0x11
DATA3 == 0X12
DATA2=DATA+DATA3
語法(9) 暫存器左右旋並可含C旗標,_1與
_0為旋入C之值
[A,BYTE][<<=,>>=][NUMBER](+C,+_1,+_0)
指令圖解
範例
DATA == 0x10
DATA<<=1
DATA<<=1+C
DATA>>=1+_0
DATA<<=1+_1
語法(10) 同語法(9),最後做搬移
[A,BYTE]=[A,BYTE,NUMBER][<<,>>]
[NUMBER](+C,+_1,+_0)
指令圖解
範例
DATA == 0X10
DATA2 == 0X11
DATA2=DATA<<1
DATA2=DATA<<1+_0
語法(11) AND,XOR,OR運算
[A,BYTE][&=,^=,|=][A,BYTE,NUMBER]
指令圖解
範例
DATA == 0x10
DATA2 == 0x11
DATA2&=DATA
DATA2^=DATA
語法(12) AND,XOR,OR運算
[A,BYTE][=][A,BYTE,NUMBER][&,^,|]
[A,BYTE,NUMBER]
指令圖解
範例
DATA == 0x10
DATA2 == 0x11
DATA3 == 0x12
DATA2=DATA|DATA3
語法(13) 乘、除、餘數運算
[A,BYTE][*=,/=,%=][A,BYTE,NUMBER]
指令圖解
範例
DATA == 0x10
DATA2 == 0x11
DATA2*=DATA
語法(14) 乘、除、餘數運算
[A,BYTE][=][A,BYTE,NUMBER][*,/,%]
[A,BYTE,NUMBER]
指令圖解
範例
DATA == 0x10
DATA2 == 0x11
DATA3 == 0X12
DATA2=DATA%DATA3
綜合範例
A=~DATA
A+=~DATA
A++
A=++DATA
DATA=A--
A+=DATA
A=DATA+DATA2
A<<=2+C ;含C旗標,即 C<
>=1 ;不含C旗標,DATA之八BIT自旋之
DATA<<=2+_0 ;即C<,>=,<,<=,&,^,|
BIT比較符號
==,!=,&&,^^,||
IF比較式之語法for BYTE一欄表
項次
語 法
1
[IF][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER]
2
[IF][!(][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER][)]
3
[IF][++,--][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER]
4
[IF][A,BYTE,NUMBER][++,--][BYTE比較符號][A,BYTE,NUMBER]
5
[IF][!(][++,--][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER][)]
6
[IF][!(][A,BYTE,NUMBER][++,--][BYTE比較符號][A,BYTE,NUMBER][)]
7
[IF][NUMBER]
IF比較式之語法for BIT一欄表
項次
語 法
1
[IF](!)[BIT]
2
[IF](!)[BIT,0,1][==,!=](!)[BIT,0,1]
3
[IF](!)[BIT][ BIT比較符號](!)[BIT]
4
[IF][!(](!)[BIT][ BIT比較符號](!)[BIT][)]
10.1 以下先介紹IF比較式for BYTE之比較語法,當在比較運算中,有可能破壞A值,所以不要在A暫存器中存任何重要之變數.
語法 (1)
[IF][A,BYTE,NUMBER][BYTE比較符][A,BYTE,NUMBER]
範例
當A大於或等於100,DATA設為10,否則設為20
IF A>=100
DATA=10
ELSE
DATA=20
ENDIF
經轉換後
ADD A,@155 ; IF A>100
JBS 3,0 ;
JMP _I000 ;
MOV A,@10 ; DATA=10
MOV DATA,A ;
JMP _I001 ; ELSE
_I000: ;
MOV A,@20 ; DATA=20
MOV DATA,A ;
_I001: ; ENDIF
語法(2) BYTE比較後之值反相
[IF][!(][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER][)]
範例
當A大於或等於100,DATA設為20,否則設為10
IF !(A>=100)
DATA=10
ELSE
DATA=20
ENDIF
語法(3) 先加減一後比較之
[IF][++,--][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER]
範例
當A加一後若大於或等於100,DATA設為10,否則設為20
IF ++A>=100
DATA=10
ELSE
DATA=20
ENDIF
語法(4) 先比較後加減一
[IF][A,BYTE,NUMBER][++,--][BYTE比較符號][A,BYTE,NUMBER]
範例
當BUF大於或等於100,DATA設為10,否則設為20,最後BUF再加一,註:再未設DATA值前BUF已先執行加一之動作,方便說明之,須注意.若變數為A或NUMBER則沒有加減一之動作
IF BUF++>=100
DATA=10
ELSE
DATA=20
ENDIF
語法(5) 先加減一後反相比較之
[IF][!(][++,--][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER][)]
範例
當A加一後若大於或等於100,DATA設為20,否則設為10
IF !(++A>=100)
DATA=10
ELSE
DATA=20
ENDIF
語法(6) 反相比較後加減一
[IF][!(][A,BYTE,NUMBER][++,--][BYTE比較符號][A,BYTE,NUMBER][)]
範例
當BUF大於或等於100,DATA設為20,否則設為10,最後BUF再加一,註:再未設DATA值前BUF已先執行加一之動作,方便說明之,須注意.若變數為A或NUMBER則沒有加減一之動作
IF !(BUF++>=100)
DATA=10
ELSE
DATA=20
ENDIF
語法(7) 常數比較
[IF][NUMBER]
範例
由下列可知,DATA一定被設為10,而DATA=20之指令永遠不會被執行之,有時這樣的指令也是會用到地
IF 100
DATA=10
ELSE
DATA=20
ENDIF
10.2 以下介紹IF比較式for BIT之比較語法,這些語法雖有兩BIT之變數,在程式中只要有一個變數為BIT模式,語法即可成立,但須確定第二個變數也是BIT之種類,否則會造成程式執行錯誤.
語法(2) BIT比較,或兩BIT之比較
[IF](!)[BIT,0,1][==,!=](!)[BIT,0,1]
範例
當BIT_0與BIT_1都相同時,DATA被設為10
IF BIT_0==BIT_1
DATA=10
ENDIF
語法(3) 兩BIT之邏輯比較
[IF](!)[BIT][BIT比較符號](!)[BIT]
範例
當BIT_0與BIT_1都為1時,DATA被設為10
IF BIT_0&&BIT_1
DATA=10
ENDIF
語法(4) 兩BIT之反向邏輯比較
[IF][!(](!)[BIT][ BIT比較符號](!)[BIT][)]
範例
當BIT_0與BIT_1都為0時,DATA被設為10
IF !(BIT_0&&BIT_1)
DATA=10
ENDIF
11. FOR-CONTINUE-NEXT-BREAK指令說明
11.0 FOR也是一比較指令,是一迴圈比較指令,當判斷式成立後,則執行FOR至NEXT之間的程式碼,直到遇到NEXT時,則程式又回到FOR判斷式,進行判斷,當判斷又成立時,則又執行FOR至NEXT之間的程式碼,就這樣形成一個迴圈,故稱為迴圈比較指令.當判斷式不成立時即可跳出其迴圈程式,從NEXT以下程式碼繼續執行.當使用FOR時須與NEXT配對使用之.
FOR指令結構
[FOR][叛斷式]
…
[NEXT]
範例
當A之值大於10時,則一直執行DATA加一之動作,直到A之值不大於10,才脫離FOR … NEXT之迴圈
FOR A>10
DATA++
NEXT
11.1 CONTINUE之用法,由上面解說當一迴圈要遇到NEXT指令時,才會回到FOR判斷式,當程式走到一半時,若想再判斷是否符合判斷式時,可以用此指令CONTINUE,此時程式便跳往FOR判斷式,一個FOR與NEXT之間,可以用一個以上的CONTINUE,也可以不用,但CONTINUE必須使用於FOR與NEXT之間,否則程式將會有錯誤.
指令
[CONTINUE]
範例
遇到CONTINUE指令時,則回到FOR判斷式
FOR A>10
…
CONTINUE ;跳至 FOR A>10程式
…
NEXT
11.2 BREAK之用法,當一程式執行於FOR...NEXT迴圈時,若此時程式想跳離此FOR...NEXT迴圈時,並不經由FOR判斷時來處理時,可以用此指令BREAK來跳出FOR…NEXT之迴圈,BREAK跳出FOR…NEXT之迴圈是絕對跳出,不必經由判斷而跳出,在一FOR…NEXT迴圈中可以用一個以上之BREAK指令,也可以不用,但BREAK必須用FOR與NEXT之間,否則程式將會有錯誤.
指令
[BREAK]
範例
遇到BREAK指令時,則跳離FOR…NEXT迴圈
FOR A>10
…
BREAK ;跳離FOR…NEXT之迴圈
…
NEXT
11.3 CONTINUE與BREAK序之,當有兩個FOR…NEXT同時使用時,也就是有兩層FOR…NEXT之迴圈,此時在第一層與在第二層均有CONTINUE與BREAK指令時,此時第二層(較內部的那一層)的CONTINUE與BREAK,均會作用於第二層的FOR與NEXT之上,而不會作用於第一層的FOR與NEXT上,也就是說如果第二層的BREAK被執行時,只會跳出第二層的FOR…NEXT之迴圈,而繼續執行在第一層的FOR…NEXT迴圈中,而指令CONTINUE亦是如此.
範例
FOR A>10
FOR DATA>20
…
CONTINUE ;回到FOR DATA>20
…
BREAK ;跳至NEXT2
…
NEXT ;AS NEXT2
…
CONTINUE ;回到FOR A>10
…
BREAK ;跳至NEXT1
…
NEXT ;AS NEXT1
11.4 BREAK又序之,BREAK可用於FOR與NEXT之間,亦可用於DO與WHILE及SWITCH與ENDS之間,當程式混合這些指令使用時,而且形成許多迴圈時,此時BREAK則會脫離目前的這一迴圈之程式,而跳至上一迴圈之程式,請注意之.若想用BREAK指令跳出所有的迴圈時,那是不可能地,此時須用GOTO等指令,在欲跳往的那一程式之地方建一標名,並使用GOTO指令跳往那標名即可.
指令
[GOTO][LABLE.NAME]
範例
FOR DATA<10
FOR DATA2>100
…
GOTO _EXIT
…
NEXT
NEXT
_EXIT:
11.5 FOR之語法,與IF語法相同,說明請參考IF語法,在此一一列出
FOR比較式之語法for BYTE一欄表
項次
語 法
1
[FOR][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER]
2
[FOR][!(][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER][)]
3
[FOR][++,--][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER]
4
[FOR][A,BYTE,NUMBER][++,--][BYTE比較符號][A,BYTE,NUMBER]
5
[FOR][!(][++,--][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER][)]
6
[FOR][!(][A,BYTE,NUMBER][++,--][BYTE比較符號][A,BYTE,NUMBER][)]
7
[FOR][NUMBER]
FOR比較式之語法for BIT一欄表
項次
語 法
1
[FOR](!)[BIT]
2
[FOR](!)[BIT,0,1][==,!=](!)[BIT,0,1]
3
[FOR](!)[BIT][ BIT比較符號](!)[BIT]
4
[FOR][!(](!)[BIT][ BIT比較符號](!)[BIT][)]
11.6 FOR之其它用法,前面所講的FOR語法,都只用一個叛斷式程式碼.現在FOR有另一標準語法,其語法為FOR EXP1,EXP2,EXP3,其中EXP1、EXP2、EXP3是三段程式碼,以逗點做區分,其中EXP1是初值敘述程式碼,EXP2是判斷式敘述程式碼,EXP2是更新敘述程式碼,FOR指令之流程是這樣的:當程式遇到FOR指令時,會先執行EXP1之程式碼,之後再執行EXP2之判斷式程式碼,最後在FOR...NEXT迴圈中,若遇到NEXT或CONTINUE時,則會執行EXP3之更新程式碼,然後又回到EXP2之程式碼,若EXP2叛斷成立時,則繼續在FOR之迴圈內執行.另EXP1與EXP3須為本軟體之運算語法(如A=0,A++等).
語法
[ FOR] [EXP1],[EXP2],[EXP3]
範例
FOR DATA=0,DATA<100,DATA+=5
…
NEXT
11.6.1 FOR敘之,當EXP1或EXP3若沒有程式碼時,可以不用寫,但仍須以逗點隔開,也就是要有兩個逗點.現在已知道FOR已有兩種用法,但用那一種較好呢?若在FOR迴圈中沒有CONTINUE指令時,可以用11.5所列出的語法使用,再把EXP3之程式碼放在NEXT指令前面即可,這樣的程式碼會較短,而且EXP3可以有多個運算語法所組成,若有CONTINUE指令之出現且EXP3有程式碼時,則須用11.6之語法撰寫之.
範例
程式一開始設DATA為0,遇到NEXT指令後則DATA加一,當程式執行完後得DATA為10,DATA2為60.
DATA2=10
FOR DATA=0,DATA<10,DATA++
DATA2+=5
NEXT
經轉換後
MOV A,@10 ; DATA2=10
MOV DATA2,A ;
CLR DATA ;FOR DATA=0,DATA<10,DATA++
JMP _F001 ;
_F000: ;
INC DATA ;
_F001: ;
MOV A,@10 ;
SUB A,DATA ;
JBC 3,0 ;
JMP _F002 ;
MOV A,@5 ; DATA2+=5
ADD DATA2,A ;
JMP _F000 ; NEXT
_F002: ;
12. DO-WHILE指令使用
12.1 DO也是一判斷指令, DO與WHILE形成一迴圈,當程式執行至DO時,不進行判斷式處理,即馬上進入DO...WHILE之迴圈內,等到執行至WHILE時才加以執行判斷式,當判斷式成立時,則程式馬上又跳往DO的程式段,繼續執行DO...WHILE之迴圈,直到WHILE之判斷式不成立,才脫離DO...WHILE之迴圈.當使用DO時須與WHILE搭配使用,在DO與WHILE之間,亦可使用BREAK之指令,來跳脫此DO...WHILE之迴圈.所以由此可知不管WHILE判斷式是否成立,其DO與WHILE之中的程式碼,一定會被執行一次以上,除非使用BREAK指令跳開等等.
DO指令結構
[DO]
…
[WHILE][判斷式]
範例
當P5.0此腳位一直為1時,則DATA一直加一之.
DO
DATA++
WHILE P5.0==1
範例(2)
DO
A++
WHILE DATA>10
經轉換後
_D000: ; DO
MOV R_ACC,A ; A++
INCA R_ACC ;
MOV A,DATA ; WHILE DATA>10
ADD A,@245 ;
JBC 3,0 ;
JMP _D000 ;
12.2 WHILE之語法,與IF語法相同,說明請參考IF語法,在此一一列出
WHILE比較式之語法for BYTE一欄表
項次
語 法
1
[WHILE][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER]
2
[WHILE][!(][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER][)]
3
[WHILE][++,--][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER]
4
[WHILE][A,BYTE,NUMBER][++,--][BYTE比較符號][A,BYTE,NUMBER]
5
[WHILE][!(][++,--][A,BYTE,NUMBER][BYTE比較符號][A,BYTE,NUMBER][)]
6
[WHILE][!(][A,BYTE,NUMBER][++,--][BYTE比較符號][A,BYTE,NUMBER][)]
7
[WHILE][NUMBER]
WHILE比較式之語法for BIT一欄表
項次
語 法
1
[WHILE](!)[BIT]
2
[WHILE](!)[BIT,0,1][==,!=](!)[BIT,0,1]
3
[WHILE](!)[BIT][ BIT比較符號](!)[BIT]
4
[WHILE][!(](!)[BIT][ BIT比較符號](!)[BIT][)]
13. SWITCH-CASE-DEFAULT-ENDS-BREAK指令說明
13.1 SWITCH也是一比較指令,但與前面所講的比較指令稍有不同,前面所的比較指令,均只有一個比較判斷式,而此SWITCH卻可以有一個或多個判斷比較式,同常用此比較指令時,多半會有很多個判斷式,而每個判斷式成立後,均有成立後欲執行的程式碼,故會有很多段的程式碼.
13.2 SWITCH之語法為 SWITCH [A,BYTE,NUMBER],在此怎麼沒看到比較符號呢?而只看到變數呢?因為SWITCH之比較符號永遠為等號(==),然而和那一變數做比較呢?此時再教大家另一指令 CASE,CASE指令是和SWITCH配合使用,並且可以使用一個以上之CASE指令,CASE之語法為 CASE [A,BYTE,NUMBER],原來SWITCH [A,BYTE,NUMBER]的變數就是與CASE [A,BYTE,NUMBER]之變數來做比較,且比較符號為等號(==).
SWITCH指令結構
[SWITCH] [A,BYTE,NUMBER]
[CASE] [A,BYTE,NUMBER]
範例
SWITCH DATA
CASE 100
13.3 由上面舉例可知當DATA等於100時,即判斷式程式,必須有一段成立之程式碼要執行,但在那呢?這段程式碼要寫在CASE與CASE之間就可以了,如舉例
範例
SWITCH DATA
CASE 100
A=10
…
CASE 101
…
13.4 由上面舉例可知當DATA等於100時,其暫存器A會被設為10,並繼續執行底下程式碼,但是這時遇到原迴圈之CASE會如何呢?這是本段所要講的,也是使用SWITCH指令的重要的觀念,這時若遇到CASE時,程式會跳往下一個CASE成立之程式碼去執行,當又遇到CASE時,則又跳往執行下一個CASE成立之程式碼,直到沒CASE時,則跳出SWITCH指令迴圈,在SWITCH迴圈結束時須用指令ENDS來結束之,也是就SWITCH與ENDS是配對的,與指令IF與ENDIF是一樣的,如舉例.
SWITCH指令 用於結束SWITCH之迴圈
[ENDS]
範例
SWITCH DATA
CASE 100
…
CASE 101
…
ENDS
13.5 由上面可知道SWITCH之用法了,但還有BREAK與DEFAULT還沒有講,當程式遇到BREAK時,則會跳離SWITCH之迴圈,往ENDS以下之程式執行之,故此,當每成個程式段不想被連著執行時,可以用BREAK指令來處理,一般都使用於CASE之前一行,或程式段最後一行,而另一指令DEFAULT是代表成立否的程式碼,當遇到許多CASE判斷式時,且都沒有成立,此時若遇到DEFAULT時,則執行否的程式碼,使用DEFAULT須注意的有如下,一個SWITCH迴圈中,只能用一個DEFAULT指令,而且須放在CASE指令後面,而DEFAULT指令是不用加任何變數的,與BREAK指令一樣.
SWITCH指令
[DEFAULT]
範例
當DATA不是100時,就會去執行A=0的程式
SWITCH DATA
CASE 100
…
DEFAULT
A=0
ENDS
SWITCH所有指令之用法
SWITCH [A,BYTE,NUMBER]
CASE [A,BYTE,NUMBER]
…
BREAK ;跳離SWITCH迴圈
CASE [A,BYTE,NUMBER] ;可以兩個以上
…
DEFAULT
… ;否的程式碼
ENDS
範例
當DATA之值為100時,A被設為10,當DATA之值為101時,A被設為20,當DATA之值都不為100或101時,A被設為30.
SWITCH DATA
CASE 100
A=10
BREAK
CASE 101
A=20
DEFAULT
A=30
ENDS
經轉換後
MOV A,DATA ; SWITCH DATA
MOV R_ACC,A ;
MOV A,@100 ; CASE 100
XOR A,R_ACC ;
JBS 3,2 ;
JMP _S000 ;
MOV A,@10 ; A=10
JMP _S002 ; BREAK
_S000: ; CASE 101
MOV A,@101 ;
XOR A,R_ACC ;
JBS 3,2 ;
JMP _S001 ;
MOV A,@20 ; A=20
JMP _S002 ; DEFAULT
_S001: ;
MOV A,@30 ; A=30
_S002: ; ENDS
14. _IF,_FOR指令用法(僅EMC,PIC適用)
14.1 _IF與_FOR與指令IF及FOR是一樣的,都是比較指令,且所有語法都一樣,_IF與IF指令差別在_IF不須要ENDIF來搭配,為單一比較指令,其判斷式成立後,欲執行之程式碼,僅能只有一指令碼(即只有一個機械碼),而本軟體不會去判斷是否超過一個指令碼以上,所以在使用_IF指令時須相當的注意,但使用_IF與_FOR時,所轉換出程式碼較少,比較省程式的空間,為其_IF與_FOR之優點.
14.1.1 _IF 0與_IF [BIT][&&,^^,||][BIT]等語法不可用於EMC晶片上,因EMC組譯器不接受$符號處理,請注意.
14.2 _FOR與_IF一樣,不須要NEXT來搭配,但是_FOR與FOR另一不同之處,是_FOR沒有判斷式成立後之欲執行之程式碼,當判斷成立後,即馬上又回到_FOR判斷式,所以沒有欲執行程式碼.
14.3 因_IF與_FOR僅為EMC單晶片所支援之指令,或許未來陸續推出之單晶片亦有_IF與_FOR之指令,故此,在未來相容性上,請使用IF與FOR之兩指令,除非程式記憶體真的不夠用了,才使用之.
範例
_IF A==10
++DATA
_FOR RTCC<10
經轉換後
XOR A,@10 ; _IF A==10
JBC 3,2 ;
INC DATA ; ++DATA
_F000: ;
MOV A,@10 ; _FOR RTCC<10
SUB A,RTCC ;
JBS 3,0 ;
JMP _F000 ;
15.切頁設定(跳躍、函數呼叫及返回)(EMC,PIC適用)
15.0 EMC之單晶片,有程式記憶體與資料記憶體都有頁數之切換,當程式或資料寫滿了第一頁時,就要切至第二頁之程式計憶體與資料記憶體,這樣才有辦法容納大量的程式或資料,在寫程式中,若遇到換頁的位置(ADDRESS)時,須用ORG之假指令來設定,這樣才能控制程式的流向,在本軟體中,也是依據ORG所設之值,來判斷目前的程式碼是存放在第幾頁的記憶體中.當寫程式時,若有切頁的位置時,都須用ORG來設定,這樣本軟體才能正確地執行切頁之功能(如ORG 200H) ,以下開始介紹關於切頁的假指令.
15.1 GOTO切頁之設定
當程式使用GOTO之跳躍指令時,其跳躍之標名的程式位置,可能會在執行之程式頁,或其它的程式頁數,此時若不在執行之程式頁時,在跳躍之前就必須先設定頁控制之BIT值,此時就先須使用指令#GOTO +,這樣設定後,程式就會先設定頁控制之BIT,後執行跳躍指令,而正確地跳至標名所指位置,所以一般都設定在#GOTO +模式下,而本軟體亦內定模式.另外當本軟體找不到此標名時,會以當時之頁數處理,也就是不做程式頁切換的動作.
語法
[#GOTO] [+,-] [+]為致能使用,[-]為除能
範例
#GOTO +
範例(2)
ORG 0H
GOTO SATRT
START:
GOTO LABLE
ORG 400H
LABLE:
經轉換後
ORG 0H
JMP START ; GOTO START
START:
BS 3,5 ; GOTO LABLE
JMP LABLE ;
ORG 400H
LABLE:
15.2 函數程式之切頁設定
用法與#GOTO [+,-]一樣,而本軟體內定#CALL +模式,但使用函數呼叫時,必須有其函數之LABLE存在,若不存在時,會提出錯誤訊息.
語法
[#CALL] [+,-] [+]為致能使用,[-]為除能
範例
#CALL +
15.3 返回程式之切頁設定
請先看底下語法RET,其中[+]為切頁致能,[-]為切頁除能,[NUMBER]返回之頁數,由零開始當程式遇到RETURN指令時,亦可做切頁之設定,但因RETURN沒有其標名來做返回頁數之依據,所以須用假指令#RET NUMBER來設定,NUMBER為返回的頁數,由零開始,如EMC之程式0X0至0X3FF為第零頁,若要返回此頁時,只要寫#RET 0就可以了,當程式遇到ORG XXH時,其返回之頁數會依ORG XXH之值而重新設定返回之頁數,如0RG 400H為返回頁數1.
語法
[#RET] [+,-,NUMBER]
範例
#RET 2 ;設定返回第二頁
15.3.1 若一函數被呼叫時,雖然可正確地呼叫此函數之程式,但卻不知道是從何程式頁所呼叫之,此時必須有一變數來掌管,在返回時依此變數之值加以返回就可以了,但在呼叫前須先設定此掌管變數即可.
範例
依RET_PAGE之變數,做返回第0頁與第1頁之處理.
IF RET_PAGE==0
#RET 0
RETURN
ELSE
#RET 1
RETURN
ENDIF
15.4 RETURN之用法與注意事項
用法
RETURN [A,BYTE,NUMBER]
RETURN [TXT,NUMBER](,TXT,NUMBER)...
範例
RETURN DATA
RETURN ‘ABC’,100,200
15.5 當使用指令RETURN返回其變數時,程式亦會自動切頁返回,但若變數為兩個常數以上時,則不會切頁,因為此時為資料建表模式,所以不切頁.
範例
RETURN DATA ;有切頁
RETURN 10,20 ;無切頁
16.各系列晶片補充事項
16.0 在本說明書中所說的指令,若第一個字元為’#’時,則須放在每行的第一個字元,這樣才會生效.
範例
#CALL +
RETURN 10,20 ;無切頁
16.1 PIC 晶片
16.1.1 PIC環境設定,須先設定使用晶片的種類以及組譯器的種類,建議放在程式的前幾行.
語 法
說 明
[#PIC16C5X]
為33指令之晶片
[#PIC16C7X]
為37指令之晶片
[#MPASM]
Microchip公司之組譯程式
[#SPASM]
Parallax公司之組譯程式
範例
#PIC16C5X
#SPASM
DEVICE PIC16C57,XT_OSC,WDT_OFF,PROTECT_OFF
…
16.1.2 當程式有使用加減法含C旗標時,記得宣告BIT變數‘_C’.
範例
_C EQU R_BIT.0
16.2 EMC 晶片
16.2.0 EMC環境設定,須先設定使用晶片的種類,建議放在程式的前幾行,當設定不同晶片時,軟體會檢查記憶體的位置是否存在,若為無效位置時,程式會提出警告來.
語 法
說 明
[#EM56]
為EM78X56系列晶片
[#EM47]
為EM78X47系列晶片
[#EM48]
為EM78X48系列晶片
範例
#EM56
16.2.1 BIT定義與使用,當使用BIT時,須先以#DEFINE指令來定義,這樣才能使用單一變數來使用,另一用法為一字串中有一小數點,亦可作為BIT變數模式.
範例
使用BIT模式的兩種方式
R_BIT == 0X10
#DEFINE B_BIT R_BIT.0
B_BIT=0
R_BIT.1=1
16.2.2 當程式有使用加減法含C旗標時,記得宣告BIT變數‘_C’.
範例
#DEFINE _C R_BIT.0
17. ELC.LIB設定檔說明、PE2(僅EMC適用)之設定
17.0 在ELC.LIB檔案中,為本軟體之所有控制變數名稱之來源,有晶片的標準指令設定,晶片暫存器設定,本軟體共用變數設定,晶片之跳躍指令設定,晶片BIT暫存器之設定,故此所知,此ELC.LIB檔是極為重要,若設定錯誤則會導致轉換出不正確的指令碼來,所以修改時要相當的注意之,以下一一介紹如何設定之.
17.1 晶片的標準指令設定
當在ELC.LIB設定#DEFINE CODE後,為輸入晶片指令模式,也就是說以下所有LABLE均為晶片指令之名稱,直到再遇到#DEFINE [...],才轉換為其它設定模式,為何要輸入這些呢?雖然事先已經設定好了,但在未來新的組譯器或晶片時,會有新的指令或假指令等,因使只要在此設定完後,就可與這些新的軟體搭配使用之,在設定指令或假指令時,須注意若是跳躍指令須另外設定,可以減少轉換出之程式碼喔.在輸入完指令名稱後,還是輸入指令之機械碼之數,以EMC來講,因為精簡指令,大都為1個機械碼較多,有些指令則有3至4個之多,若不知道其機械碼之數時,其指令不影響程式內容時以0輸入,其餘以最少之機械碼或以1輸入之(如 DEVICE為0,ORG為1,ORG雖然不產生程式碼,但會改變程式之位置,所以須以1輸入之).
語法
[#DEFINE] [CODE] 晶片指令模式
[CODE.NAME] [CODE.SIZE] 晶片指令,機械碼之數
範例
#DEFINE CODE
DEVICE 0
NOP 1
ORG 1
17.2 晶片暫存器之設定
晶片暫存器為一晶片重要的資料交換記憶區,如PIC為W,EMC為A,8051為A等,程式可設定一個或兩個以上之暫存器名稱,但其作用是一樣的,一般而言都使用A較多.
語法
[#DEFINE] [OPKEY]
[REGISTER.NAME] [50]
範例
#DEFINE OPKEY
A 50
W 50
17.3 變數定義指令之設定
在許多不同的晶片中,有的用EQU來設定變數之值,有的用==來設定變數之值,在此就是要設定‘定義指令’之名稱,本軟體內部已定義有=與==兩種,其餘均可在此ELC.LIB設定之.
語法
[#DEFINE] [OPKEY]
[DEF.NAME] [8]
範例
#DEFINE OPEKY
EQU 8
17.4 軟體共用變數之設定
在本軟體運作許多指令使,都須借用許多共用變數,才能完成指令之運作,而這些變數在寫程式時,最好不要拿來存放資料,否則會無知無覺地被破壞掉了,而參數LEVEN為其階層,從0開使,一般只要設兩個共用變數即可,為其階層0與1,而第0階層之共用變數,會被使用最頻繁,若使用乘法時須用到四個共用變數,其階層0至3,若使用除法器使,則須用到五個共用變數,其階層0至4,目前所附MATH.H之乘除函數,均以R_ACC,R_ACC2,R_ACC3...之名稱來設定共用變數的名稱,若想修改其它名稱時,須同時修改MATH.H之程式,如R_ACC->X_ACC,R_ACC2->X_ACC2等.
語法
[#DEFINE] [RAM]
[SHARE.NAME] [LEVEN (0,1,2...)]
範例
#DEFINE RAM
R_ACC 0
R_ACC2 1
R_ACC3 2
…
17.5 晶片跳躍指令之設定
與晶片指令設定一樣,但晶片指令設定之跳躍指令均須在此設定.
語法
[#DEFINE] [OPKEY]
[GOTO.NAME] [3] [CODE.SIZE]
範例
#DEFINE OPEKY
GOTO 3 1
JMP 3 1
LJMP 3 3
17.6 晶片BIT暫存器之設定
為晶片內部BIT之設定,一般晶片都有C,AC,Z或其它等,均可在此設定,或可以在程式中用#BIT指令來設定,其作用是一樣的,在此如先設好時,寫程式時就不用設定了.
語法
語法 [#DEFINE] [OPKEY]
語法 [BIT.NAME] [5]
範例
#DEFINE OPEKY
C 5
DC 5
Z 5
…
17.6.1 若使用晶片為EMC時,須在程式中再以#DEFINE指令設定,以取代其BIT變數名稱(如#DEFINE C STATUS.0等),這樣才能符合組譯器之格式.
範例
EMC之程式中須這樣設定
STATUS == 0X03
#DEFINE C STATUS.0
#DEFINE DC STATUS.1
#DEFINE Z STATUS.2
17.6 PE2.EXE 之使用(僅EMC-ICE適用)
本磁片所附之PE2.EXE並不是文書處理器,而是用於EMC-ICE上,因EMC-ICE有線上編輯之功能,而簡易語言並非為EMC之組合語言,因而做一PE2.EXE之執行程式,讓EMC-ICE呼叫之,然後此PE2.EXE會去呼叫_PE2.EXE(真的文書編輯器)編輯簡易語言(簡易語言檔案內定為*.ELC),當編輯完後,此PE2.EXE又會去執行ELC.EXE檔案,此時就會產生EMC的組合語言(*.DT),最後再返回EMC-ICE上,這樣就可以在EMC-ICE上直接編輯簡易語言了,是一項很好用的功能,另PE2.EXE與_PE2.EXE與ELC.EXE與ELC.LIB最好放在EMC之工作目錄下,才不會有找不到檔案之問題,本磁片亦附PE2.CPP原始檔,若對參數不同時,可以自己修改之.
PE2.CPP原始程式
#include
#include
#include
#include
#include
void main(int argc,char **argv)
{
char txt[64],txt2[64],txt3[64];
char drv[32],dir[32],name[32],ext[32];
if (argc!=2)
exit(0);
fnsplit(argv[1],drv,dir,name,ext);
if (stricmp(ext,".DT")==0)
{
fnmerge(txt3,drv,dir,name,ext);
strcpy(ext,".ELC");
fnmerge(txt2,drv,dir,name,ext);
sprintf(txt,"_PE2 %s",txt2);
system(txt);
sprintf(txt,"ELC_EMC %s %s",txt2,txt3);
system(txt);
}
else
{
sprintf(txt,"_PE2 %s",argv[1]);
system(txt);
}
}
18.範例程式功能說明
18.1 在本軟體所附之磁片中,有十個範例程式,其檔名為EXP_00.ELC至EXP_09.ELC等,建議讀者可以一個一個實驗,程式內容十分容易瞭解,而且線路相當簡單,線路圖案檔名為EXP.GIF,可以用WINDOWS系統觀看並且列印出來,底下一一說明十個程式的作用與功能,若讀者使用軟體ICE或單步執行時,可以將程式中的延遲函數稍做修正,在DELAY()下一行多加上一個RETURN指令,這樣就可以使用單步執行或軟體ICE,不必等DELAY的時間了.
線路圖:
18.2 範例程式功能說明
項次
檔名
功 能 說 明
1
EXP_00
一個LED在閃動
2
EXP_01
二個LED在互相閃動
3
EXP_02
三個LED在輪流閃動
4
EXP_03
按下KEY則燈亮,放開KEY則燈滅
5
EXP_04
按一次KEY,則兩個燈ON<->OFF切換
6
EXP_05
按一次KEY,則兩個燈ON<->OFF切換
7
EXP_06
八個LED的霹靂燈
8
EXP_07
八個LED的霹霹燈 II
9
EXP_08
按一次KEY,改變霹靂燈跑的方向
10
EXP_09
按一次KEY,則八個燈閃五下,然後再回到原霹靂燈狀態
程式:EXP_00.ELC
;一個LED在閃動
F0 == 0
RTCC == 1
PC == 2
STATUS == 3
IND == 4
P5 == 5
P6 == 6
P7 == 7
C_WDT == 0XE
R_ACC == 0X10 ;SHARE BUF
R_ACC2 == 0X11 ;SHARE BUF
;DEFINE BIT
#DEFINE CY STATUS.0
#DEFINE Z STATUS.2
;DEFINE PORT
#DEFINE P_LED P6.0
;PROGRAM START
ORG 0
MAIN()
!C_WDT=0
!OPTION=0B111 ;main program
P5=0
P6=0
!P5=0XFF
!P6=0
R_ACC=0X11
DO
IND=R_ACC
F0=0
WHILE ++R_ACC!=0X16
LOOP:
DELAY()
IF P_LED==0
P_LED=1
ELSE
P_LED=0
ENDIF
GOTO LOOP
DELAY()
R_ACC=0
R_ACC2=0
DO
DO
WHILE --R_ACC!=0
WHILE --R_ACC2!=0
RETURN
程式:EXP_01.ELC
;二個LED互相在閃動
F0 == 0
RTCC == 1
PC == 2
STATUS == 3
IND == 4
P5 == 5
P6 == 6
P7 == 7
C_WDT == 0XE
R_ACC == 0X10 ;SHARE BUF
R_ACC2 == 0X11 ;SHARE BUF
;DEFINE BIT
#DEFINE CY STATUS.0
#DEFINE Z STATUS.2
;DEFINE PORT
#DEFINE P_LED0 P6.0
#DEFINE P_LED1 P6.1
;PROGRAM START
ORG 0
MAIN()
!C_WDT=0
!OPTION=0B111 ;main program
P5=0
P6=0
!P5=0XFF
!P6=0
R_ACC=0X11
DO
IND=R_ACC
F0=0
WHILE ++R_ACC!=0X16
LOOP:
DELAY()
IF P_LED0==0
P_LED1=0
P_LED0=1
ELSE
P_LED0=0
P_LED1=1
ENDIF
GOTO LOOP
DELAY()
R_ACC=0
R_ACC2=0
DO
DO
WHILE --R_ACC!=0
WHILE --R_ACC2!=0
RETURN
程式:EXP_02.ELC
;三個LED的霹靂燈
F0 == 0
RTCC == 1
PC == 2
STATUS == 3
IND == 4
P5 == 5
P6 == 6
P7 == 7
C_WDT == 0XE
R_ACC == 0X10 ;SHARE BUF
R_ACC2 == 0X11 ;SHARE BUF
R_WORK == 0X12
;DEFINE BIT
#DEFINE CY STATUS.0
#DEFINE Z STATUS.2
;DEFINE PORT
P_LED == 0X6
#DEFINE P_LED0 P6.0
#DEFINE P_LED1 P6.1
#DEFINE P_LED2 P6.2
;PROGRAM START
ORG 0
MAIN()
!C_WDT=0
!OPTION=0B111 ;main program
P5=0
P6=0
!P5=0XFF
!P6=0
R_ACC=0X11
DO
IND=R_ACC
F0=0
WHILE ++R_ACC!=0X16
LOOP:
DELAY()
P_LED=0
SWITCH R_WORK
CASE 0
P_LED0=1
BREAK
CASE 1
P_LED1=1
BREAK
CASE 2
P_LED2=1
DEFAULT
P_LED1=1
ENDS
IF ++R_WORK>=4
R_WORK=0
ENDIF
GOTO LOOP
DELAY()
R_ACC=0
R_ACC2=0
DO
DO
WHILE --R_ACC!=0
WHILE --R_ACC2!=0
RETURN
程式:EXP_03.ELC
;按下KEY則LED亮,放開KEY則滅
F0 == 0
RTCC == 1
PC == 2
STATUS == 3
IND == 4
P5 == 5
P6 == 6
P7 == 7
C_WDT == 0XE
R_ACC == 0X10 ;SHARE BUF
R_ACC2 == 0X11 ;SHARE BUF
;DEFINE BIT
#DEFINE CY STATUS.0
#DEFINE Z STATUS.2
;DEFINE PORT
#DEFINE P_KEY P5.2
#DEFINE P_LED P6.0
;PROGRAM START
ORG 0
MAIN()
!C_WDT=0
!OPTION=0B111 ;main program
P5=0
P6=0
!P5=0XFF
!P6=0
R_ACC=0X11
DO
IND=R_ACC
F0=0
WHILE ++R_ACC!=0X16
LOOP:
IF P_KEY==0
P_LED=0
ELSE
P_LED=1
ENDIF
GOTO LOOP
程式:EXP_04.ELC
;按下KEY後,LED ON/OFF 切換
F0 == 0
RTCC == 1
PC == 2
STATUS == 3
IND == 4
P5 == 5
P6 == 6
P7 == 7
C_WDT == 0XE
R_ACC == 0X10 ;SHARE BUF
R_ACC2 == 0X11 ;SHARE BUF
R_BIT == 0X12
;DEFINE BIT
#DEFINE CY STATUS.0
#DEFINE Z STATUS.2
#DEFINE B_KEY R_BIT.0
;DEFINE PORT
#DEFINE P_KEY P5.2
#DEFINE P_LED P6.0
;PROGRAM START
ORG 0
MAIN()
!C_WDT=0
!OPTION=0B111 ;main program
P5=0
P6=0
!P5=0XFF
!P6=0
R_ACC=0X11
DO
IND=R_ACC
F0=0
WHILE ++R_ACC!=0X16
LOOP:
IF P_KEY==1
IF B_KEY==0
B_KEY=1
IF P_LED==0
P_LED=1
ELSE
P_LED=0
ENDIF
DELAY()
ENDIF
ELSE
IF B_KEY==1
B_KEY=0
DELAY()
ENDIF
ENDIF
GOTO LOOP
DELAY()
R_ACC=0
R_ACC2=0
DO
DO
WHILE --R_ACC!=0
WHILE --R_ACC2!=0
RETURN
程式:EXP_05.ELC
;按下KEY後,兩LED之ON/OFF互換
F0 == 0
RTCC == 1
PC == 2
STATUS == 3
IND == 4
P5 == 5
P6 == 6
P7 == 7
C_WDT == 0XE
R_ACC == 0X10 ;SHARE BUF
R_ACC2 == 0X11 ;SHARE BUF
R_BIT == 0X12
;DEFINE BIT
#DEFINE CY STATUS.0
#DEFINE Z STATUS.2
#DEFINE B_KEY R_BIT.0
;DEFINE PORT
#DEFINE P_KEY P5.2
#DEFINE P_LED0 P6.0
#DEFINE P_LED1 P6.1
;PROGRAM START
ORG 0
MAIN()
!C_WDT=0
!OPTION=0B111 ;main program
P5=0
P6=0
!P5=0XFF
!P6=0
R_ACC=0X11
DO
IND=R_ACC
F0=0
WHILE ++R_ACC!=0X16
LOOP:
IF P_KEY==1
IF B_KEY==0
B_KEY=1
IF P_LED0==0
P_LED1=0
P_LED0=1
ELSE
P_LED0=0
P_LED1=1
ENDIF
DELAY()
ENDIF
ELSE
IF B_KEY==1
B_KEY=0
DELAY()
ENDIF
ENDIF
GOTO LOOP
DELAY()
R_ACC=0
R_ACC2=0
DO
DO
WHILE --R_ACC!=0
WHILE --R_ACC2!=0
RETURN
程式:EXP_06.ELC
;霹靂燈,用八個LED
F0 == 0
RTCC == 1
PC == 2
STATUS == 3
IND == 4
P5 == 5
P6 == 6
P7 == 7
C_WDT == 0XE
R_ACC == 0X10 ;SHARE BUF
R_ACC2 == 0X11 ;SHARE BUF
R_BIT == 0X12
;DEFINE BIT
#DEFINE CY STATUS.0
#DEFINE Z STATUS.2
#DEFINE B_DIR R_BIT.0
;DEFINE PORT
P_LED == 0X6
;PROGRAM START
ORG 0
MAIN()
!C_WDT=0
!OPTION=0B111 ;main program
P5=0
P6=0
!P5=0XFF
!P6=0
R_ACC=0X11
DO
IND=R_ACC
F0=0
WHILE ++R_ACC!=0X16
P_LED=1
LOOP:
DELAY()
IF B_DIR==0 ; <<
IF P_LED.7==1
B_DIR=1
P_LED>>=1+_0
ELSE
P_LED<<=1+_1
ENDIF
ELSE
IF P_LED.1==0
B_DIR=0
P_LED<<=1+_1
ELSE
P_LED>>=1+_0
ENDIF
ENDIF
GOTO LOOP
DELAY()
R_ACC=0
R_ACC2=0
DO
DO
WHILE --R_ACC!=0
WHILE --R_ACC2!=0
RETURN
程式:EXP_07.ELC
;霹靂燈,共用八個LED,有一個在跑
F0 == 0
RTCC == 1
PC == 2
STATUS == 3
IND == 4
P5 == 5
P6 == 6
P7 == 7
C_WDT == 0XE
R_ACC == 0X10 ;SHARE BUF
R_ACC2 == 0X11 ;SHARE BUF
R_BIT == 0X12
;DEFINE BIT
#DEFINE CY STATUS.0
#DEFINE Z STATUS.2
#DEFINE B_DIR R_BIT.0
;DEFINE PORT
P_LED == 0X6
;PROGRAM START
ORG 0
MAIN()
!C_WDT=0
!OPTION=0B111 ;main program
P5=0
P6=0
!P5=0XFF
!P6=0
R_ACC=0X11
DO
IND=R_ACC
F0=0
WHILE ++R_ACC!=0X16
P_LED=1
LOOP:
DELAY()
IF B_DIR==0
IF P_LED.7==1
B_DIR=1
P_LED>>=1
ELSE
P_LED<<=1
ENDIF
ELSE
IF P_LED.0==1
B_DIR=0
P_LED<<=1
ELSE
P_LED>>=1
ENDIF
ENDIF
GOTO LOOP
DELAY()
R_ACC=0
R_ACC2=0
DO
DO
WHILE --R_ACC!=0
WHILE --R_ACC2!=0
RETURN
程式:EXP_08.ELC
;LED為霹靂燈,按下鍵後改變其方向
F0 == 0
RTCC == 1
PC == 2
STATUS == 3
IND == 4
P5 == 5
P6 == 6
P7 == 7
C_WDT == 0XE
R_ACC == 0X10 ;SHARE BUF
R_ACC2 == 0X11 ;SHARE BUF
R_BIT == 0X12
;DEFINE BIT
#DEFINE CY STATUS.0
#DEFINE Z STATUS.2
#DEFINE B_DIR R_BIT.0
#DEFINE B_KEY R_BIT.1
;DEFINE PORT
P_LED == 0X6
#DEFINE P_KEY 0X5.2
;PROGRAM START
ORG 0
MAIN()
!C_WDT=0
!OPTION=0B111 ;main program
P5=0
P6=0
!P5=0XFF
!P6=0
R_ACC=0X11
DO
IND=R_ACC
F0=0
WHILE ++R_ACC!=0X16
P_LED=1
LOOP:
DELAY()
IF P_KEY==1
IF B_KEY==0
B_KEY=1
IF B_DIR==0
B_DIR=1
ELSE
B_DIR=0
ENDIF
ENDIF
ELSE
B_KEY=0
ENDIF
IF B_DIR==0
P_LED<<=1
ELSE
P_LED>>=1
ENDIF
GOTO LOOP
DELAY()
R_ACC=0
R_ACC2=0
DO
DO
WHILE --R_ACC!=0
WHILE --R_ACC2!=0
RETURN
程式:EXP_09.ELC
;平常八個LED為霹靂燈,按下KEY後全部閃動五下
F0 == 0
RTCC == 1
PC == 2
STATUS == 3
IND == 4
P5 == 5
P6 == 6
P7 == 7
C_WDT == 0XE
R_ACC == 0X10 ;SHARE BUF
R_ACC2 == 0X11 ;SHARE BUF
R_BIT == 0X12
R_CTR == 0X13
R_LED_BUF == 0X14
;DEFINE BIT
#DEFINE CY STATUS.0
#DEFINE Z STATUS.2
#DEFINE B_KEY R_BIT.1
#DEFINE B_PRESS R_BIT.2
;DEFINE PORT
P_LED == 0X6
#DEFINE P_KEY 0X5.2
;PROGRAM START
ORG 0
MAIN()
!C_WDT=0
!OPTION=0B111 ;main program
P5=0
P6=0
!P5=0XFF
!P6=0
R_ACC=0X11
DO
IND=R_ACC
F0=0
WHILE ++R_ACC!=0X16
P_LED=1
LOOP:
DELAY()
IF P_KEY==1
IF B_KEY==0
B_KEY=1
IF B_PRESS==0
B_PRESS=1
R_LED_BUF=P_LED
R_CTR=0
P_LED=0
ENDIF
ENDIF
ELSE
B_KEY=0
ENDIF
IF B_PRESS==0
P_LED<<=1
ELSE
P_LED=~P_LED
IF ++R_CTR>=10
B_PRESS=0
P_LED=R_LED_BUF
ENDIF
ENDIF
GOTO LOOP
DELAY()
R_ACC=0
R_ACC2=0
DO
DO
WHILE --R_ACC!=0
WHILE --R_ACC2!=0
RETURN
19.其它
19.1若有關於本軟體之使用上之問題,或發現本軟體之BUG,歡迎以下列方式處理之,軟體之更新可經由E-MAIL方式傳遞,請註明使用晶片及目前軟體版本,當軟體有更新時,即可馬上獲得.若無E-MAIL時,則以郵寄處理,酌收手續費100元.
E-MAIL:ft8162@mail1.catv.com.tw
或 傳真:04-2211825(請註明回傳傳真電話,姓名)
19.1.1 若為晶片之問題,如晶片之買賣、使用...等,請以下列方式處理
E-MAIL:
js100@ms2.hinet.net <-EMC代理商
robbie@ms6.hinet.net <-UMC代理商
HOME-PAGE:
www.emc.com.tw/sa2 <- EMC
19.2 簡易語言之訂購
目前已推出PIC版與EMC版,在未來,會繼續推出其它廠牌單晶片之簡易語言,訂購方式如下:(劃撥完後,請將劃撥單之收據及寫上您的大名、住址(限國內)、電話、定購單晶片種類,傳真至04-2211825,之後將在二至三天內,便可收到此簡易語言(掛號處理)).
郵局劃撥帳號:22131498號,戶名:蔡有仁
19.3 簡易語系列晶片
項次 單晶片種類 價格(價格若有變動,不另行通知)
1 PIC 16XX NT:3500元
2 EMC 8BIT 同上
3 HOLTEK 8 BIT ..
4 SYNTEK 8 BIT ..
5 ZILOG 8 BIT ..
6 MYSON 4 BIT ..
7 UMC 4BIT ..