|
EM78 系列八位微控器是利用 (1)“call",(2) 改變PC (或“tbl"),(3)“retl k" 三個步驟來查表的。其中“retl k" 是將常數 k 的值傳至工作寄存器 "A" 中。 步驟 (2) 中若利用“ MOV 0x2,a",或“add 0x2,a" 等等指令來改變PC,則因為此等指令會將 PC (R2) 的位 8、9 清除 (在 EM78056 只清除位 8),所以查表的內容只能放在程序每個 PAGE 的較低的 256 個位址。步驟 (2) 中若利用“tbl" 指令來改變PC,則因為此指令不會將PC (R2) 的位 8、9 清除,而保留“tbl" 所在位址的位 8、9,所以查表的內容可以放在程序每個 PAGE 中的任何位址。 例:查表 table add 0x02,a ;將相對位置加入 PC 而改變了PC retl @0x19 ;傳回常數內容 19h 至 "A" retl @0x74 ;傳回常數內容 74h 至 "A" retl @0x2e ;傳回常數內容 2eh 至 "A" retl @0x54 ;傳回常數內容 54h 至 "A" retl @0x4b ;傳回常數內容 4bh 至 "A" inc 0x18 mov a,0x18 ;欲查的內容的相對位置放在"A" call table ;查表 mov 0x10,a ;查表得到的內容移至 R10 中 1. 程序跳 PAGE 的用法: EM78 系列八位微控器將其 Program Memory (ROM) 分成數個 PAGE,每個 PAGE 的長度是 1K (EM78056 除外)。R3 寄存器的位 5 (6) 是 "PAGE 選擇位",當執行 "jmp" 或 "call" 指令時,"PAGE 選擇位" 會被載入 Program Counter 的位 10 (11),因此當程序超過 1K (EM78056 為 0.5K)時,執行 "jmp" 或"call" 指令時,"PAGE 選擇位" 正確的設定是非常重要的。下面將以 EM78256 為例來說明跳 PAGE 的方法。 例 例:從PAGE 1 跳轉到PAGE 0 ; PAGE 0, begin at 000h 049 add 0x11,a 051 mov 0x05,a ;port5<-- 0x55 052 bs 0x03,5 ;select PAGE 1 053 jmp lab1 ;PAGE jump 054 ; PAGE 1, begin at 400h 447 448 mov a,@0x3f 449 xor 0x12,a 450 Lab1 bc 0x06,3 451 mov a,0x05 說明: 052: 將 R3 寄存器的位 5 設為 "1" (選擇 PAGE 1)。 053: Lab1 會被編譯 為 "50",程序跳轉至 PAGE 1 中 "Lab1" (450) 的位址。 注意: 此例中 "052" 和 "053" 是用來跳 PAGE 的,假如沒有 "052" 這行指令,則程序將跳轉至"050" 的位址 (在 PAGE 0中),如此將沒有達到預期的目的。 2. 不同 PAGE 子程序呼叫的方法: 如第 1 項所述,當程序超過 1K 時,執行 "call" 指令時,"PAGE 選擇位" 的設定就必須加以考慮。下面將以 EM78256 為例來說明呼叫不同 PAGE 子程序的方法。 例: 從PAGE 0調用PAGE 1中的子程序 ; PAGE 0, begin at 000h 049 add 0x11,a 050 mov a,@0x55 051 mov 0x05,a ;port5<-- 0x55 052 bs 0x03,5 ;select PAGE 1 053 call Lab2 ;PAGE jump 054 bc 0x03,5 ;restore 055 jbs 0x15,2 056 ; PAGE 1, begin at 400h 417 418 mov a,@0x3f 419 xor 0x12,a 450 Lab2 bc 0x06,3 451 mov a,0x05 45f ret 說明: 052: 將 R3 寄存器的位 5設為 "1" (選擇 PAGE 1)。 053: Lab2 將會被編譯為 "50",呼叫 PAGE 1 中 "Lab2" 子程序。 054: 將 R3 寄存器的位5 還原為 "0"。 注意: 此例中 "052" 和 "053" 是用來呼叫 PAGE 1 中 "Lab2" 的子程序,假如果沒有 "052" 這行指令,則程序將呼叫 "050" 的位址 (在 PAGE 0中),而非 "450" 的位址 (在 PAGE 1中),如此將發生錯誤。 "BS","BC" 等指令會先有 "讀" 再 "寫" 的動作,例如 "bc 0x06,3" 指令是將整個 Port 6 (8 pin) 讀進 CPU,執行位運算后再寫至 Port 6 上。假如 Port 6 有一些 pin 是雙向 I/O pin (如 P65) 時,假設當執行 "bc 0x06,3" 時P65 是輸入 pin,則 P65 pin 上的內容會被讀入再寫至 Latch 上,覆蓋原先 Latch 上的內容。因此只要 P65 一直是輸入 pin 將不會有問題,一旦 P65 切換為輸出,則 Latch 上的內容將是不可預知的。 若仔細研究EM78系列八位微控器的I/O Port構造,就可發現在做"讀"I/O Port的動作時(如"mov a,0x06"),所讀入內容有兩個路徑來源,一是I/O pin上的內容,另一是輸出Latch上的內容,而由I/O控制寄存器決定此讀入的路徑。 例如I/O pin設計為輸入pin時(對應的I/O控制寄存器為"1"),對I/O Port做"讀"的動作時,是讀到pin上的內容。若I/O pin設計為輸出pin時(對應的I/O控制寄存器為"0"),對I/O Port做"讀"的動作時,是讀到輸出Latch上的內容。 WDT是微控器內部RC自振的計時器,其超時溢位(Time-out)的基本周期約18ms,WDT有與TCC共用的倍除器,使得超時溢位(Time-out)的最大周期可至約2.2sec。WDT計時的使能或禁止是可隨時由指令控制的(控制位在IOCE寄存器)。當WDT使能時,其超時溢位將使微控器發生RESET(或喚醒),"wdtc"指令是用來清除WDT,令WDT再從頭計時,因此適當的使用"wdtc"指令,可使WDT不會發生RESET。當WDT被禁止時,WDT不會使微控器RESET或喚醒。要特別注意的是,Power-on之後WDT是使能的,如果該應用中並沒有使用WDT,必須在程序的前頭用指令將WDT計時禁止。EM78156/256/456就是依上述所設計。 在EM78247/447/248/448/056/P156除了上述的設計外,另有一Code Option決定使能或禁止WDT,其功能如下: 1. 假如應用中有使用WDT,WDT必須以Code Option使能,則在程序中隨時可以用指令使能或禁止WDT計時。注意:Power-on之後WDT是使能的。 2. 假如應用中並沒有使用WDT,WDT可以以Code Option禁止,則WDT是永遠被禁止的,如此可省去須在程序的前頭用指令將WDT計時禁止的麻煩。 用戶可以單獨設定任一支I/O腳為輸出模式(Output Mode),或是輸入模式(Input Mode)。只要將每個I/O的設定寫入累加器(A)中,再將累加器的內容寫到I/O控制寄存器中,設定就算完成了。 例1:將PORT6設定為OUTPUT PORT。 PORT6 == 6 ;定義。 MOV A, @0X00 ;設定A = 0。 IOW PORT6, A ;將PORT6設定為輸出模式。 例2:將PORT6的低四位設成INPUT PORT;高四位設定為OUTPUT PORT。 PORT6 == 6 ;定義。 MOV A, @0X0F ;設定A= 0X0F,高四位為 IOW PORT6, A ;OUTPUT PORT,低四位為 ;INPUT PORT。 檢查寄存器的內容有很多種方法,可以用AND的功能,或SUB的功能…等。在做完AND或SUB的功能之后,可以檢驗狀態標志(STATUS FLAG),然后寫一個判斷式,針對狀態標志的結果, 處理個別的情形。 例:判斷寄存器0X20內含值是否為0。 CHECK: MOV A, @0XFF ;設定A = 0XFF。 AND A, 0X20 ;寄存器0X20,和A中的值做and JBS 0X03, 2 ;若是寄存器0x20為0,則寄存 JMP CHECK ;器0X03的bit2位為1。 ;若是寄存器0X20不為零則產生循環。 1.FOR LOOP的設計: 如果用戶想讓同一段程序執行N次,用戶可以利用一個寄存器為計數器,在程序執行前,先將計數寄存器設為N,然后每執行一次,計數器就減一,再跳為原區段執行,直到計數器被減至零。 例:設計一個FOR LOOP循環,讓循環連續執行10次。 MOV A, @0X0A ;設A = 0X0A。 MOV 0X10, A ;設定計數值。計數寄存器 LOOP: ;為0X10。 ; ; ; DJZ 0X10 ;遞減計數寄存器,若計數 JMP LOOP ;值為0,則跳出循環。 2.IF…THEN… 程序設計: IF…THEN…的說法就是,如果…就做…。用戶可以利用檢查兩個數值是否相等,例如”IF X = Y THEN GOTO ELSE” 的格式,來完成這種功能。 l 例:判斷兩個寄存器(0X20, 0X21)的數值是否相等,如果相等,就將標志寄存器設為1。 BUFFER1 == 0X20 ;定義。 BUFFER2 == 0X21 FLAG == 0X22 MOV A, BUFFER ;將BUFFER1的值存入A中。 XOR A, BUFFER2 ;將A的值和BUFFER2的值做xor JBC 0X03, 2 ;IF BUFFER1 = BUFFER2 JMP FLAG_1 ;THEN JMP FLAG_0 ;ELSE FLAG_0: MOV A, @0 MOV FLAG, A ;設定FLAG為0。 JMP PROCESS FLAG_1: MOV A, @1 MOV FLAG, A ;設定FLAG為1。 JMP PROCESS PROCESS: 在一個沒有規則性的內容轉換中,查表程序是相當有用的,用戶可以使用查表程序很快速的得到相關內容的轉換。 例:設計一個程序,將如下圖所示中的PORT5讀到的一個數值,將輸入內容做轉換,然后輸出到PORT6的7段顯示器上。 上圖中開關關閉,I/O引腳可以得到一個低電位,若是開關開啟則I/O引腳可以得到一個高電位。 圖 5.2 數碼管八段說明 7段顯示器的接線圖如上,我們要編一個表做為讀入內容以及輸出內容的對映。 7段顯示器各腳位電位狀態 | PORT6輸出 | PORT5輸入 | H | G | F | E | D | C | B | A | 16進位數值 | 10進位數值 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0X3F | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0X06 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0X5B | 2 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0X4F | 3 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0X66 | 4 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0X6D | 5 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0X7D | 6 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0X07 | 7 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0X7F | 8 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0X6F | 9 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0X77 | 10 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0X7C | 11 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0X58 | 12 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 0X5E | 13 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0X79 | 14 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0X71 | 15 |
程序清單如下: PC == 0X02 ;定義。 PORT5 == 5 PORT6 == 6 ORG 0X10 ;設定程序起始位址。 IOW PORT6 ;設定PORT6為Output口。 MOV A, @0XFF IOW PORT5 ;設定PORT5為Input口。 JMP START ;跳轉到主程序中。 TABLE:;輸入及輸出對映表。 ADD PC, A RETL @0X3F RETL @0X06 RETL @0X5B RETL @0X4F RETL @0X66 RETL @0X6D RETL @0X7D RETL @0X07 RETL @0X7F RETL @0X6F RETL @0X77 RETL @0X7C RETL @0X58 RETL @0X5E RETL @0X79 RETL @0X71 START: MOV A, PORT5 AND A, @0X0F CALL TABLE MOV PORT6, A JMP START 在EM78X56系列的IC中有三種中斷信號,分別是: TCC溢位中斷。 PORT6 Change 中斷。 外部信號中斷。 在說明中斷使用方式之前,用戶要了解中斷寄存器,及與中斷息息相關的控制寄存器( Control Register),另外在芯片中預除器( Prescalar )的使用方法,用戶也需要住意。 中斷信號顯示寄存器0X0F各位安排如下: | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0 | 中斷信號 | - | - | - | - | - | 外部中斷標志 | PORT6 Change | TCC 溢位標志。 |
寄存器0X0F使用到的有BIT0 ~ BIT2。BIT0在TCC計時器計數溢位時就會被設定,用戶可以根據0X0F的BIT0被設定而判定TCC計數溢位。跟TCC配合的還有另一個寄存器---控制寄存器(Control Register,簡稱CONT)。控制寄存器0X0F各位安排如下: | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0 | 控制信號 | - | INT | TS | TE | PAB | PSR2 | PSR1 | PSR0 |
各位的代表意義如下: □ PSR2 ~ PSR0:TCC/WDT 預除器設定。 PSR2 | PSR1 | PSR0 | TCC 比例 | WDT 比例 | 0 | 0 | 0 | 1:2 | 1:1 | 0 | 0 | 1 | 1:4 | 1:2 | 0 | 1 | 0 | 1:8 | 1:4 | 0 | 1 | 1 | 1:16 | 1:8 | 1 | 0 | 0 | 1:32 | 1:16 | 1 | 0 | 1 | 1:64 | 1:32 | 1 | 1 | 0 | 1:128 | 1:64 | 1 | 1 | 1 | 1:256 | 1:128 |
FIGURE3.5 PS0 ~ PS2的設定值與預除器和TCC及WDT的比例關係。 □ Bit3預除器配置: 0:TCC 1:WDT □ Bit4 TCC遞增時機: 0:外部信號,觸發邊沿為正沿觸發。 1:外部信號,觸發邊沿為負沿觸發。 □ Bit5 TCC信號來源: 0:內部指令周期觸發。 1:外部引腳(第三腳)觸發。 □ Bit6 INT使能標志: 0:禁止所有中斷產生。 1:使能中斷信號。 □ Bit7 無使用。 三種中斷產生都有其先前的設定值,接下來會以示例說明。 l 例:寫一個程序,將寄存器0X20當做計數器,每當TCC中斷產生,就自動加1。 MOV A, @0X0 ;設定 A = 0。 IOW 0X0E ;關閉Watch Dog。 ORG 6 ;設定接下來的程序位址。 CLR 0X20 ;清除寄存器0X20。 JMP TCC_PRO ;跳轉到TCC_PRO。 INT_PRO: DISI ;關閉各項中斷功能。 CLR 0X0F ;清除中斷寄存器。 INC 0X20 ;計數器加1。 RETI ;返回主程序,並使能中斷。 TCC_PRO: CLR 0X0F ;清除中斷寄存器。 MOV A, @0X01 ;設定 A = 1。 IOW 0X0F ;使能TCC溢位中斷產生。 MOV A, 0X40 ;設定 A = 0X40。 CONTW ;將A的值寫入控制寄存器。 ENI ;使能中斷。 TCC_WAIT: NOP ;等待TCC計數器計數溢位。 NOP ;等待TCC計數器計數溢位。 JMP TCC_WAIT ;等待TCC計數器計數溢位。 TCC中斷產生有幾個設計的重點: 1. 關閉看門狗計時器(Watch Dog Timer)。 2. 設定控制寄存器(包括預除器、TCC信號來源、觸發時機…)。 3. 使能中斷(下ENI指令)。 4. 使能TCC中斷(設定中斷控制寄存器的bit0為1)。 5. 中斷服務位址為0X08。 6. 進入中斷服務程序首先要將中斷禁止,否則會產生重復中斷。 7. 中斷寄存器0X0F,在進入中斷服務程序時可以提供用戶判斷為何種中斷,判斷完成之后用戶必須自行清除。 8. 由中斷服務程序返回主程序應使用指令RETI。 l 例:寫一個程序,將寄存器0X20當做計數器,每當PORT6 Change中斷產生,就自動加1。 PORT6 == 6 ;定義。 DISI ;中斷禁止。 ORG 6 ;設定下一個位址為0X06。 CLR 0X20 ;清除計數寄存器。 JMP PORT6_CH ;跳轉到主程序。 DISI INT_PRO: ;0X08為中斷服務程序起始。 NOP CLR 0X0F ;清除中斷標志寄存器。 INC 0X20 ;計數器遞增。 MOV PORT6, PORT6 ;將PORT6的值存入正反器。 RETI ;回主程序。 PORT6_CH: CLR 0X0F ;清除中斷標志寄存器。 MOV A, @0XFF ;設定 A = 0XFF。 IOW PORT6 ;將PORT6設成輸入口。 MOV PORT6, PORT6 ;將PORT6的值存入正反器。 ENI ;使能中斷。 MOV A, @0X02 ;設定 A = 0X02。 IOW 0X0F ;使能PORT6 Change中 WAIT_INT: WDTC ;清除Watch Dog Timer。 NOP ;等待PORT6 Change。 NOP ;等待PORT6 Change。 JMP WAIT_INT ;循環。 使用PORT6 Change中斷有下列幾個步驟。 1. 關閉看門狗計時器(Watch Dog Timer),若看門狗計時器未關閉,用戶要定時下WDTC的指令。 2. 清除中斷寄存器。 3. 設定PORT6為輸出口。 4. 將PORT6的值存入觸發器中(這很重要)。 5. 使能中斷(下ENI的指令)。 6. 使能PORT6 Change中斷(設定中斷控制寄存器的bit1為1)。 7. 中斷服務程序的啟始位址在0X08。 8. 進入中斷服務程序首先要將中斷禁止,否則會產生嵌套中斷。 9. 中斷寄存器0X0F,在進入中斷服務程序時可以提供用戶判斷為何種中斷,判斷完成之后用戶必須自行清除。 10. 由中斷服務程序返回主程序應使用指令RETI。 l 例:寫一個程序,將寄存器0X20當做計數器,每當外部中斷產生,就自動加1。 所謂的外部中斷就是利用IC外部引腳,針對單片機外部的信號做為信號源來產生中斷。EM78系列的外部中斷引腳是第4腳,是和PORT6位0合用,所以再使用前要先設定PORT6 , BIT0是要單純用做I/O引腳,或是中斷輸入引腳。 ORG 6 ;設定啟始位址為0X06。 CLR 0X20 ;清除計數器。 JMP EXT_PRO ;跳轉到主程序。 INT_EXT: DISI ;中斷禁止。 CLR 0X0F ;清除中斷標志。 INC 0X20 ;遞增計數寄存器。 RETI ;返回主程序。 EXT_PRO: CLR 0X0F ;清除中斷標志。 MOV A, @0X04 ;A = 0X04。 IOW 0X0F ;使能外部中斷信號產生。 MOV A, @0X40 ;A = 0X40。 IOW 0X0E ;設定PORT6, BIT0為中斷輸入腳 ENI ;返回主程序。 EXT_WAIT: NOP ;等待外部中斷輸入。 NOP ;等待外部中斷輸入。 JMP EX_WAIT ;循環。 外部中斷顯然比較容易了解。所需注意的項目有: 1. 禁止中斷。 2. 設定中斷服務程序的地址在0X08。 3. 清除中斷標志寄存器。 4. 使能外部中斷信號產生(設定中斷控制寄存器為0X04)。 5. 將PORT6, BIT0設定成外部中斷引腳(設定控制寄存器0X0E, BIT6為1)。 6. 使能中斷信號(ENI)。 7. 用戶在進入中斷服務程序(0X08)時,首先要記得禁止中斷(DISI)。 8. 可以由中斷標志寄存器判斷中段的信號為何產生,判斷完之后應自行清除中斷標志。 9. 返回主程序時用指令RETI。 以上三支中斷程序的寫法都是利用無窮循環,所以用戶想要看到結果只有結束程序,然后查看計數寄存器(0X20)的計數狀況。 在許多程序設計的場合,我們時常會利用到時間延遲子程序,接下來就介紹一個可以控制延遲時間的延遲子程序。 開下面是利用發工具E8-ICE來演示的一個精確的控制延遲時間的程序,選擇使用石英振蕩器,可以精確的算準延遲時間,時間可以到nanosecond(十億分之一秒),很神奇。 LP_CNT0 == 0X20 ;定義。 LP_CNT1 == 0X21 MOV A, @2 ;A = 2。 MOV LP_CNT0, A ;設定延遲寄存器0(LP_CNT0)=2 CALL P0_DLY ;呼叫時間延遲子程序。 P0_DLY: NOP ;調節延遲時間。 MOV A, @200 ;設定 A = 200。 MOV LP_CNT1, A ;設定寄存器LP_CNT1 = 200。 P0_LP: NOP ;調節延遲時間。 NOP ;調節延遲時間。 NOP ;調節延遲時間。 DJZ LP_CNT1 ;遞減LP_CNT1,為0就跳過下一行 JMP P0_LP ;循環。 DJZ LP_CNT0 ;遞減LP_CNT0,為0就跳過下一行 JMP P0_DLY ;循環。 RET ;返回主程序。 假設用戶所使用的開發工具是E8-ICE,而且所采用的振蕩器為石英振蕩(4M Hz),並選擇指令執行周期為1 Cycle, 2 Clock。這時每執行一個指令的時間為0.5 uS. 用戶可以看出在程序中用了兩個寄存器來計數(LP_CNT0、LPCNT1),另外也使用了兩個循環(P0_DLY、P0_LP),其中在P0_LP中有5個指令,所以在P0_LP這個循環中,執行了有1000個指令。 5X 200= 1000 P0_LP循環總共執行指令數目。 5 + 1000 = 1005 P0_DLY循環總共執行指令數目。 1005 X 2 = 2010 2010 + 1 + 1 = 2012 延遲程序總共執行指令數目 在整個P0_DLY循環中就有2012個指令,每個指令的執行時間為0.5 us。 2012 (instructions) x 0.5 (us/instruction) = 1.006 ms 所以用戶可以精確的計算出延遲的時間,用戶可以在LP_CNT0設定不同的值,如此可以有各種不同的延遲時間。 l 例:設計一個延遲時間為2ms的程序。 只要在上述程序中在呼叫P0_DEL延遲子程序之前,將LP_CNT0設成4就可以了。 MOV A, @4 MOV LP_CNT0, A CALL P0_DLY 其余不變。 1005 X 4 = 4020。 4020 + 1 + 1 = 4022。 4022 (instructions) X 0.5 (us) = 2.011 ms PORT5輸出動作的控制,而且外部接有一推動STEP MOTOR的電路。寫一程序驅動STEP MOTOR。 在寫程序之前,先介紹STEP MOTOR的動作原理。 圖5.3 PORT5步進馬達控制圖。 P50 0 0 1 1 P51 1 1 0 0 P52 1 0 0 1 P53 0 1 1 0 圖5.4 PORT5步進馬達控制時序圖。 圖5.3中可以看出,PORT5接到STEP MOTOR的對應引腳,圖5.4可以看出PORT5應該送出的信號。圖5.3中P50和P51的輸出必須反相,P52和P53的輸出必須反相,而P50和P52必須有相位差,假設P50和P52的相位差為90度,于是導出圖5.4 的時序圖。 圖5.4的時序圖中,可以看出有四個相位會一直循環,分別是: | Phase 0 | Phase 1 | Phase 2 | Phase 3 | P50 | 0 | 0 | 1 | 1 | P51 | 1 | 1 | 0 | 0 | P52 | 1 | 0 | 0 | 1 | P53 | 0 | 1 | 1 | 0 | Value | 0x06 | 0x0A | 0x09 | 0x05 |
上表中有四個基本相位數值。所以只要不停的送出這四個相位,STEP MOTOR就會不停的旋轉,送出的速度快,STEP MOTOR的轉速就快,但是要在STEP MOTOR的旋轉極限之內。 PORT5 == 5 ; 定義 ; 程序開始 MOV A, @0X0 ;將A設成0X0。 IOW PORT5 ;設定PORT5為輸出口。 AGAIN: MOV A, @0X06 ;設定A的值為0X06。 MOV PORT5, A ;將A的值輸出到PORT5。 MOV A, @0X0A ;設定A的值為0X0A。 MOV PORT5, A MOV A, @0X09 ;設定A = 0X09。 MOV PORT5, A MOV A, @0X05 ;設定A = 0X05。 MOV PORT5, A ;設定PORT5 = 5。 JMP AGAIN ;循環。 PORT6輸出動作的控制,而且外部接有一推動8個七段顯示器的電路。編寫一程序在8個七段顯示器上輪流顯示1,2,3,4,5,6,7,8。 下圖為控制電路的方塊圖。  由PORT6單獨控制8個七段顯示器,利用時間分割(time slice)的顯示方式,就可以同時讓多個七段顯示器同時顯示。上圖可以看出,若是要讓第一個七段顯示器顯示一個0的值,在PORT6輸出的內容值為0X00,前四個位控制要顯示的七段顯示器,后四個位控制顯示的數字。所以要選第0個七段顯示器,前四個位要為0;若要顯示的值為0,后四個位的值也是為0。 PORT6 == 6 ;定義PORT6 MOV A, @0 ;將A設成0。 IOW PORT6 ;設定PORT6為OUTPUT口 AGAIN: MOV A, @0X01 ;將A設成0X01 MOV PORT6, A ;輸出內容到PORT6。 MOV A, @0X12 ;將A設成0X12。 MOV PORT6, A ;輸出內容到PORT6。 MOV A, @0X23 MOV PORT6, A ;輸出內容到PORT6。 MOV A, @0X34 MOV PORT6, A ;輸出內容到PORT6。 MOV A, @0X45 MOV PORT6, A ;輸出內容到PORT6。 MOV A, @0X56 MOV PORT6, A ;輸出內容到PORT6。 MOV A, @0X67 MOV PORT6, A ;輸出內容到PORT6。 MOV A, @0X78 MOV PORT6, A ;輸出內容到PORT6。 JMP AGAIN PORT6的輸出接有一個數模轉換器(D/A convert)。寫一程序產生一個鋸此波。 本例的D/A Convert所采用的方式為R – 2R的方式,所使用的電阻為20K的同一品牌的排阻。因PORT6有8個位,所以在0V-VCC一共有256個階層。 PORT6 == 6;定義。 MOV A, @0 ;將A設成0。 IOW PORT6 ;將PORT6設成OUTPUT口。 MOV PORT6, A ;PORT6輸出內容為0。 AGAIN: INC PORT6 ;PORT6的值依序遞增1。 JMP AGAIN |