可編程并行輸入/輸出接口芯片 8255A
-1:結構
8255A為40引腳、雙列直插封裝。
內部結構由數據端口、組控制電路、數據總線緩沖器、讀/寫控制邏輯四部分組成。
數據總線緩沖器:三態8位雙向緩沖器,D7-D0同系統數據總線相連。CPU通過執行輸入/輸出指令來實現對緩沖器發送或接收數據,傳送控制字和狀態字。
讀寫控制邏輯: 管理數據信息、控制字和狀態字的傳送,接收來自CPU地址總線和控制總線的有關信號,向8255A的A、B兩組控制部件發送命令
A組和B組控制電路:3個端口分成兩組來管理。A口及C口高4位為A組,B口及C口低4位為B組。兩組分別設有控制電路,每個控制組都接收來自讀/寫控制邏輯的“命令”,接收來自內部數據總線的“控制字”,并向與其相連的端口發出適當的控制信號。
數據端口:
3個8位數據端口:端口A、端口B和端口C
A1 A0 選擇端口
0 0 ???A口(數據口)
0 1 ???B口(數據口)
1 0????C口(數據口)
1 1 ???控制口
-2控制字
8255A有兩種控制字。一個是方式選擇控制字,另一個是對C口進行置位或復位的控制字。
-3 : 8255A的工作方式
方式0:基本的 輸入/輸出方式。 ?適用A、B、C口。
方式1:選通的 輸入/輸出方式。 ?適用A、B口。
方式2:雙向選通輸入/輸出方式。適用A口。
在方式0下,C口的高4位和低4位以及A口、B口都可以獨立地設置為基本的輸入口或輸出口。4個口的輸入/輸出可以有16種組合方式
方式1輸入的邏輯功能結構
接口介紹:
STB-bar:輸入的選通信號,低電平有效。由外設提供?,為低電平時,把輸入的數據送入A端口或B端口的數據鎖存器.
IBF?:輸入緩沖器滿信號?,?高電平有效。由8255A輸出?,有效時,用以通知外部設備輸入的數據已寫入緩沖器.
INTRx:中斷請求信號,高電平有效。當STB-bar、IBF和INTE都為高電平時,表明數據鎖存器內已寫入了數據,使INTR成為高電平輸出。 (我滿了,你沒有輸入了,我允許讀出了)
CPU響應中斷執行IN指令后,在控制下從8255A中讀取數據時,RD的下降沿使INTR復位,RD的上升沿又使IBF復位,使外設知道可以進行下一字節輸入了。
INTE:中斷允許信號。
A端口用PC4位的置位/復位控制,B端口用PC2位的置位/復位控制。
只有當PC4或PC2置“1”時,才允許對應的端口送出中斷請求。
方式1輸出的邏輯功能結構
OBF-bar:輸出緩沖器滿信號;低電平有效。由8255A輸出,當其有效時,表示CPU已經將數據輸出到指定的端口,通知外設可以將數據取走。
ACK-bar:響應信號,低電平有效。由外設送來,有效時表示8255A的數據已經被外設所接收。
INTR:中斷請求信號,高電平有效。當外設接收了由CPU送給8255A的數據后,8255A就用INTR端向CPU發出中斷請求,請求CPU再輸出后面的數據。
INTR是當OBF、ACK和INTE都為高電平時,才能被置成高電平。由的WR下降沿清除.
INTE:中斷允許信號。
A口的INTE由PC6置/復位,
B口的INTE由PC2置/復位。
方式2的邏輯功能結構:
INTE2是與輸入相關的中斷允許,由對PC4的置位/復位控制.
INTEl是與輸出相關的中斷允許,由對PC6的置位/復位控制.?
5個聯絡信號與在方式1中的含義基本相同,因為是雙向傳送,所以INTRA在輸入或輸出
時都可以產生。
-4:例 7.1.1 8255A 方式 0 應用:
8255A 產生波形接口電路。
利用 8255A 在方式 0 下工作,使其在PC 0.PC 3引腳產生如圖 所示的波形,試編寫相應程序段。
設8255A 各端口地址分別設為60H?.61H.62H和63H,波形延時時間可調用延時 1ms 子程序(D1ms)實現
PC0,PC3對應了C的低4位(,也就是控制字的最后一個)
先看看控制字:輸出為0,
- | (00)(0)(0) | (0)(0) | (0)
傳輸的數據的順序是 01H->09H->00H->08H????????????????
START:? ? MOV AL,80H ?;送各口方式0,C輸出輸出控制字
????????????????OUT 63H,AL
?A1:? ? ? ? ? ?MOV AL,01H
????????????????OUT 62H,AL
????????????????CALL D1ms
????????????????MOV AL,09H
????????????????OUT 62H,AL
????????????????CALL Dlms
????????????????MOV AL,00H
????????????????OUT 62H,AL
????????????????CALL D1ms
????????????????MOV AL,08H
????????????????OUT 62H,AL
????????????????CALL D1ms
????????????????JMP A1
8253A 計數器/定時器
-1基本功能:
3個獨立的16位計數器,可以進行3個16位的獨立運算
每一個計數器具有六種工作方式
可以進行2/10進制計數,
計算頻率0~2Mhz
可以作為計數器or定時器
-2結構:
A1 A0 選擇端口
0 0 計時器0(數據口0)
0 1 計時器1(數據口1)
1 0 計時器2(數據口2)
1 1 控制口
-3:初值計算:
計數方式:計數值=?要求的計數次數
定時方式:計數值=?OUT時間÷CLK周期
計數值讀寫格式:
只低,高八位清0
只高,低八位清0
先低后高
計數值讀出的方式:直接讀 or 鎖存讀
-4:控制字:
-5:六種工作方式:
-6:啟動方式:
軟:CPU寫入計數值
硬:GATE上跳沿
計數值的極限值:
-7例題:
例 7.2.1 8253 的初始化設計。
? 設某8253通道1工作于方式0,按BCD方式計數,計數初值為400。計數器0、計數器1、計數器2和控制寄存器的端口地址依次為80H-83H,試編寫8253的初始化程序
1,先看看控制字:
(01)(11)(000)(1)
通道1,xx,0模式,BCD模式? ,
這里的xx因為我們需要送400,12位,但是一次只能送8位,所以需要使用先低后高的11讀寫格式
2,再看計數值:使用BCD碼,也就是0400H,送入計數器1的數據端口,地址是81H,先低后高,先送低位00H,后送高位04H
3,初始化程序
MOV AL,71H ;控制字
OUT 83H,AL? ?;送達控制字
MOV AL,00H ;低8位計數值
OUT 81H,AL
MOV AL,04H ;高8位計數值
OUT 81H,AL
可編程串行通信接口芯片 8251A
-1工作方式
兩種基本的通信方式:并行,串行
串行通常在兩個設備之間傳送
按照通信的線路可以分為3類:單工通信,半雙工,全雙工
-2功能:
(1)同步下波特率:0~64K. ?異步下波特率0 ~ 19.2K
(2)同步模式下,可以用5,6,7,8來代表字符,并且內部可以自動檢測同步字符,實現同步(還可以增加同步下的奇偶校驗)
(3)異步模式下,可以用5,6,7,8位代表字符,1位奇偶校驗,每個字符設置1,1.5,2個停止位
(4)所有的輸入輸出電路都與TTL電平兼容。
(5)全雙工雙緩沖的接收/發送器。
-3內部結構
數據總線緩沖器:
三態雙向8位緩沖器,它是8251A與微機系統數據總線的接口,數據、控制命令及狀態信息均通過此緩沖器傳送。
內容:命令寄存器 ,狀態寄存器 .方式寄存器 ,兩個同步字符寄存器 ,數據輸入緩沖器 ,數據輸出緩沖器
發送緩沖器:
接收CPU送來的并行數據,按照規定的數據格式變成串行數據流后,由TXD輸出線送出。
TXRDY:發送器準備好,高電平有效。有效時,表示發送器已準備好接收CPU送來的數據。當CPU向8251A寫入一個數據后,TXRDY自動復位。當8251A允許發送,且數據輸出緩沖器為空時,此信號有效。在用中斷方式時,此信號作為中斷請求信號。
TXD:發送數據線
TXEMPTY:發送移位器空,高電平有效。有效時,表示發送器中的移位寄存器已經變空。8251A從CPU接收待發的數據后,自動復位。
TXC:發送時鐘,由它控制8251A發送數據的速度。在異步方式下,TXC的頻率可以是波特率的1倍、16倍或64倍,可由程序設定。在同步方式下,TXC的頻率與發送數據波特率相同。
發送方式
異步:發送器為每個字符加上一個起始位,并按照規定加上奇偶校驗位以及1個、1.5個或者2個停止位。然后在發送時鐘TXC的作用下,由TXD腳逐位地串行發送出去。
同步:發送緩沖器在準備發送的數據前面先插入由初始化程序設定的一個或兩個同步字符,在數據中插入奇偶校驗位。然后在發送時鐘TXC的作用下,將數據逐位地由TXD引腳發送出去。
接收緩沖器:
接收在RXD腳上輸入的串行數據,并按規定的格式把串行數據轉換為并行數據,存放在數據總線緩沖器中的數據輸入緩沖器中。
SYNDET:同步檢測。只用于同步方式。內同步時,作為輸出,如果8251A檢測到了同步字符,則輸出高電平。外同步時,作為輸入,這個輸入端上的一個正跳變,使8251A在RXC的下一個下降沿時開始裝配字符。
RXC:接受時鐘
RXD:接收數據線
RXRDY:接收數據準備好,高電平有效。在允許接收的條件下,當8251A已經從它的串行輸入端接收了一個字符,并完成了格式變換,此信號有效,通知CPU讀取數據。當CPU從8251A讀取一個字符后,RXRDY信號自動復位。在中斷方式時可作為中斷請求信號。
異步接收方式:在“允許接收”條件下,接收緩沖器監視RXD線。發現起始位后,開始采樣并進行字符裝配,裝配一個后直接送到數據輸入緩沖器,同時發出RXRDY有效信號。
同步接收方式:先搜索同步字符。匹配同步字符后,SYNDET引腳變為高電平。
外同步方式:SYNDET端出現高電平,8251A便認為已經完成同步。實現同步之后,對RXD線采樣,把收到的數據送入移位寄存器中。裝配字符,然后送入數據輸入緩沖器,并且在RXRDY引腳上發出有效信號
讀寫控制邏輯電路:
CLK:時鐘,產生8251A的內部時序。同步方式時,CLK頻率要大于RXC和TXC頻率的30倍。異步方式時,此頻率要大于RXC和TXC頻率的4.5倍。
調制解調控制電路
DTR-bar:數據終端準備好,輸出,低電平有效。由命令字的D1置“1”變為有效,用以表示8251A準備就緒。
RTS-bar:請求發送,輸出,低電平有效。用于通知調制解調器,8251A要求發送。由命令字的D5位置“1”來使其有效。
DSR-bar:數據裝置準備好,輸入,低電平有效。表示調制解調器已經準備好。CPU通過讀狀態寄存器的D7位檢測這個信號。
CTS-bar:請求發送清除,也稱為允許發送,輸入,低電平有效,是調制解調器對8251A的信號的響應,當其有效時8251A方可發送數據。
(1)調制解調控制電路用來簡化8251A和調制解調器的連接。
(2)在進行遠程通信時,要用調制器將串行接口送出的數字信號變為模擬信號,再發送出去;接收端則要用解調器將模擬信號變為數字信號。
(3)在全雙工通信情況下,每個收發端都要連接調制解調器。DTR:數據終端準備好,輸出,低電平有效。由命令字的D1置“1”變為有效,用以表示8251A準備就緒。
-4:控制字:方式選擇/操作命令
方式選擇控制字在8251A復位之后送入,
操作命令控制字在方式選擇控制字之后的任何時間均可送入
方式選擇:方式選擇控制字用來選擇工作方式,確定數據位長度、是否要奇偶校驗、停止位的位數或同步字符的個數等。
命令控制字:命令控制字控制8251A的發送、接收、內部復位等的實際操作。
CPU可以任意時候通過in將8251A內部狀態寄存器的內容讀入來判斷8251A的工作狀態
題目
下列幾種芯片中能接管總線、控制I/O接口與存儲器直接進行數據傳送的是( ??)。A
A. 8237A B. 8259A ??C. 8255A D.?8253A
選用如下圖給出的元器件設計一個恒溫箱溫度采集控制系統。該系統有兩個狀態:設置狀態和控制狀態。在設置狀態時,通過鍵盤可以修改恒溫箱的設定溫度;在控制狀態時,用開關量輸出進行簡單控制。檢測溫度與設定溫度進行比較,當檢測溫度小于設定溫度時,控制繼電器加熱;當檢測溫度大于設定溫度時,關閉加熱。當有按鍵時,發出1kHz聲音,用于按鍵提示。
系統有兩位七段數碼管顯示溫度值(0~99℃)。在設置狀態時,系統顯示設定溫度;在控制狀態時,系統顯示當前檢測溫度。系統通過4x4鍵盤輸入設定溫度值和啟動控制,鍵盤有0~9鍵、Setting鍵和Control鍵共12個鍵可用。
(1)畫出系統的硬件連接原理圖,并標明分配給各元器件的端口地址。
(
設置狀態,通過鍵盤來輸入,采用矩陣+行掃描 (c)
顯示,使用2個7段七段數碼管 (ab)
8255連接CPU,兩個數碼管,一個鍵盤輸入(4位) ,一個輸入c低,3個輸出abc高 ,10001000
CPU使用8086即可
)
(2)寫出“0”對應的七段數碼管譯碼值;編寫8255、8253初始化程序;
(3)編寫AD轉換子程序(adc)、顯示子程序(display)、按鍵識別子程序(key)和主程序(main)。
(1)硬件原理圖如下
(2)寫出“0”對應的七段數碼管譯碼值;編寫8255、8253初始化程序;
“0”對應的七段數碼管譯碼值是:0C0H
;8255初始化
init_8255 proc near
????mov dx, PORT_CTR_8255
????mov al, 10001000b ?;初始化8255控制字
????out dx, al
????ret
init_8255 endp
;8253_計數器0初始化---20ms中斷請求
init_8253 proc near
????mov dx, PORT_CTR_8253
????mov al, 00110100b ?;初始化8253控制字 : 計數器選擇,? 讀寫格式,? 工作方式? BCD/B
????out dx, al
????mov dx, PORT_COUNTER0_8253
????mov ax, 20000 ???;計數常數 ?; 20ms/(1/1Mhz) =20000
????out dx, al ;寫低8位
????mov al, ah
????out dx, al ;寫高8位
????ret
init_8253 endp
;開始發聲,8253計數器1,方式3, 1kHz方波----
startBeep proc near
????mov dx, PORT_CTR_8253
????mov al, 01110110b ; 初始化8253控制字,計數1,r/w低8位 ,高8位,方式3,二進制計數
????out dx, al
????mov dx, PORT_COUNTER1_8253
????mov ax, 1000 ; 計數常數 ?; 1mhz/1khz =1000
????out dx, al ; 寫低8位
????mov al, ah ; 寫8位
????out dx, al
????ret
startBeep endp
;----5.2停止發聲,方式0----
stopBeep proc near
????mov dx, PORT_CTR_8253
????mov al, 01110000b ; 初始化8253控制字,計數1,方式0
????out dx, al
????ret
stopBeep endp
;----5.3發聲100ms----
beep_200ms proc near
????push dx
????call startBeep
????delay 0ffh
????call stopBeep
????pop dx
????ret
beep_200ms endp
(3)編寫AD轉換子程序(adc)、顯示子程序(display)、按鍵識別子程序(key)和主程序(main)。
Adc proc near
???; 啟動AD轉換
????mov dx, PORT_START_0809 ??
????mov al, 0
????out dx, al ?;選擇通道0
????mov is_adc_started, 1; 下次是查詢狀態
??sample_ch0:
???; 查詢轉換結束引腳eoc,非阻塞方式
????mov dx, PORT_EOC_0809
????in al, dx
????test al, 00000001b ;eoc引腳為高電平?
????jz exit_isr? ? ?????;eoc變高到此,輸入adc轉換結束數值
????mov dx, PORT_DATA_0809
????in al, dx ?
????mov [sample_ch0_val], al; 保存AIN0采集數字量
????mov is_adc_started, 0 ; 下次是啟動AD狀態
????call calc_ad2tmp; 計算當前溫度值
??exit_isr:?
ret?
Adc endp
display proc far ??
????push ax
????push bx
????push cx
????mov bx, offset led_table
????cmp is_in_control_state, 1
????je ?get_cur_tmp_val
????mov cl, setting_tmp_val
????jmp start_display
?get_cur_tmp_val: ??
????mov cl, sample_tmp_val ???
?start_display: ?
mov al, 0
to_w10: ???
????cmp cl, 10
????jb ?display_w10
????inc al
sub cl, 10
jmp to_w10
???…
????cmp is_on_heatting_state, 1; 在加熱時
????je on_heatting
????and al, 01111111b
????jmp out_w1
??on_heatting:
????or al, 10000000b
??out_w1: ?
????mov dx, PORT_B_8255
????out dx, al ;顯示個位
????pop cx
????pop bx
????pop ax
????ret
display endp
key_identify proc near ????
????;(1)判斷是否有鍵按下
????mov dx, PORT_C_8255
????mov al,0
????out dx, al; PC3~0行輸出全0
????nop
????in al, dx ;讀入列值PC7~4
????and al, 11110000b
????cmp al, 11110000b
????jne re_confident
????mov is_new_key, 0; ?無新鍵值
????jmp error_exit
????;(2)有鍵按下,軟延時,再次判斷
??re_confident: ?
????delay 0ffh
????in al, dx ;讀入列值PC7~4
????and al, 11110000b
????cmp al, 11110000b
????jne has_key
????mov is_new_key, 0; ?無新鍵值
????jmp error_exit
????;(3)識別按鍵。確實有鍵按下,開始掃描,
?has_key:
????mov ah, 11111110b
????mov cx,4
??scan_next_row:
????mov al, ah
????out dx, al
????nop
????in al, dx
????and al, 11110000b
????cmp al, 11110000b
????jne find_key ; 行值ah, 列值al
????rol ah, 1
????loop scan_next_row
????jmp error_exit
?find_key:
????and ah, 00001111b
????mov cl,4
????shr al, cl
????; 計算鍵位值,行值ah, 列值al
????;計算行計數值
???…
????mov ah, bl ; 保存行計數值ah
????;計算列計數值
????mov bl, -1 ;計數0位置
????mov cx, 4
??next_column:
????inc bl; 列號計數
????shr al, 1
????jnc find_column
????loop next_column
????mov is_new_key, 0; ?無新鍵值
????jmp error_exit ?
?find_column:
????mov al, bl;保存列計數值al
????shl ah, 1
????shl ah, 1; x4
????add al, ah ;al鍵位置值
????mov cur_key, al; ?保存當前鍵值
????mov is_new_key, 1; ?***有新鍵值
????call beep_200ms;發聲
???;(4)判斷是否鍵釋放,行輸出全0
no_release_wait:
mov al, 0
????out dx, al ; PC7~4列輸入,PC3~0 行輸出
????nop
????in ?al, dx; 讀入行值 ????
????and al, 11110000b
????cmp al, 11110000b
????jne ?no_release_wait ???
????delay 0ffh ?;鍵釋放,軟延時 ???
??error_exit: ?
????ret
key_identify endp
main: ??
????;----(0)初始化
????call init_vct_table ;中斷時用
call init_8255 ?;8255A初始化;!!!初始化8255時,端口數據消失
????call init_8253 ;中斷時不用
call init_8259 ;仿真時不用
????call display
????; --->轉到兩個狀態
?main_loop: ?????
????cmp is_in_control_state, 1
????… ???
??;----(1)設置狀態---------------
?loop_in_setting_state:
????call key_identify;識別按鍵
????cmp is_new_key, 1
????jne loop_in_setting_state
????cmp cur_key, 0Bh; 0Bh,進入控制狀態
????je change2control_state
????…
????jmp main_loop
????
?;----(2)控制狀態-----------
?loop_in_control_state: ??
????call key_identify
????cmp cur_key, 0AH; 0AH,設置按鍵 ???
????je ?change2setting_state; ?轉到設置狀態 ???
???…
????call display
????jmp main_loop ???
?ret
選擇使用如下元器件,設計一個多路傳感器電壓采集顯示系統。
設計要求:
(1)由兩位共陽極七段數碼管組成靜態顯示器,由八個按鍵組成線性鍵盤,8通道的ADC連接8個傳感器(由可變電阻代替),一路DAC的輸出連接一個電壓表, 并由8259和8253組成定時中斷請求和按鍵提示音。
(2)每20毫秒由8253產生一次中斷請求。設8253時鐘CLK等于1MHZ,8253的OUT0連接到8259的IR2端,已知寫入8259的ICW2是08H,每次中斷時,中斷服務程序對ADC的8個通道傳感器電壓值采集一遍,中斷服務程序函數名稱為isr_20ms_adc。
(3)當有按鍵按下時,發出1kHz提示聲音,兩位七段數碼管顯示與按鍵對應的ADC通道電壓值(保留小數點后1位,單位為V),K0鍵對應第一個ADC通道,...,K7對應第8個ADC通道,并用DAC0832輸出這個通道傳感器電壓的值,用電壓表可以測量。
(4)當無按鍵按下時, 不發提示音,用兩位七段數碼管顯示八個傳感器平均電壓值(電壓范圍為0.0V~5.0V,保留小數點后1位數,單位為V),并用DAC0832輸出八個傳感器電壓的平均值,用電壓表可以測量。
試完成如下設計:
1. 畫出與8086連接的硬件原理圖。
2. 編寫8255、8253和中斷向量表的初始化程序;寫出七段數碼管段碼譯碼表;并編寫多路傳感器電壓采集顯示系統的程序。
答:
(1)
(2)
; 由MASM32編譯, 并開始使用.IF .REPEAT .WHILE .UNTIL 等宏, 可以不用低層的分支結構,
; 結構化更好。
; Author: hyp@jlu.edu.cn , QQ:hyper/790516
;----0.主程序-----------------------------------------------------------------
main proc far
????; (1)初始化
????call init_vct_table ;中斷向量初始化
????call init_8255 ?????;8255A初始化
????call init_8253 ?????;8253初始化
????call init_8259 ?????; 8259初始化
????enable_isr; 開中斷 ???
????; (2)循環
????.WHILE 1
????????call key_identify ??????;判斷和識別按鍵
????????.IF key_is_pressed == 0 ;無鍵按下時
????????????call display_AV_Vx ?;顯示8個通道平均電壓
????????.ELSE ??????????????????;有鍵按下時
????????????call display_CH_Vx ?;顯示當前按鍵對應Kn通道電壓
????????.ENDIF
????.ENDW
????ret
main endp
;1.中斷向量表初始化
init_vct_table proc near
????;mov bx, 4*12h ; n = 12H, IR2有中斷請求輸入, ICW2=10H
????mov bx, 4*2 ???; n = 2, NMI非屏蔽中斷
????mov ax, 0
????mov es, ax
????mov ax, offset isr_20ms_adc
????mov es:[bx], ax
????mov ax, seg isr_20ms_adc
????mov es:[bx+2], ax
????ret
init_vct_table endp
;-----------------------------------------------------------------------------
;2.8255初始化
init_8255 proc near
????out_port PORT_CTR_8255, 10001001b ?;初始化8255控制字
????ret
init_8255 endp
;-----------------------------------------------------------------------------
;3.8253_計數器0初始化---20ms中斷請求
init_8253 proc near
????out_port PORT_COUNTER_CTR, 00110100b ?;初始化8253控制字,計數0,r/w低8位 ,高8位,方式2,二進制計數
????mov ax, 20000 ;計數常數 ?; 20ms/(1/1Mhz) =20000, ; 40ms/(1/1Mhz) =40000
????out_port PORT_COUNTER0, al ;寫低8位
????out_port PORT_COUNTER0, ah ;寫高8位
????ret
init_8253 endp
;-----------------------------------------------------------------------------
;4.8259初始化
init_8259 proc near ????
????out_port PORT_8259_0, 00010010b ?;初始化8259控制ICW1
????out_port PORT_8259_1, 08H; ICW2
????out_port PORT_8259_1, 01H; ICW4
????ret
init_8259 endp
;-----------------------------------------------------------------------------
;5.發聲xxms----
beep_start proc near
????push ax
????out_port PORT_COUNTER_CTR, 01110110b ; 開始發聲:初始化8253控制字,計數1,r/w低8位 ,高8位,方式3,二進制計數
????mov ax, 1000 ; 計數常數 ?; 1mhz/1khz =1000
????out_port PORT_COUNTER1, al ; 寫低8位
????out_port PORT_COUNTER1, ah ; 寫8位
????pop ax
????ret
beep_start endp
beep_stop proc near
????push ax
????out_port PORT_COUNTER_CTR, 01110000b ; 停止發聲:初始化8253控制字,計數1,方式0,
????pop ax
????ret
beep_stop endp
;6.中斷服務程序--- 雙狀態,非阻塞方式
; 進兩次采集一次AD值,40ms采集一次, 循環采集8個通道AD值,并計算8個Vx_x10電壓值
isr_20ms_adc proc far ??
????.IF ( I_Flag == 1)
????????push ax
????????push bx
????????push cx
????????push dx
????????push si
????????pushf
????????.IF is_adc_started == 0 ; 沒有啟動,則啟動
????????????out_port PORT_ADC_START, cur_sensor_channel ;啟動當前通道
????????????mov is_adc_started, 1; 標志已經啟動
????????.ELSE
???????????; 查詢轉換結束引腳eoc,非阻塞
????????????in_port PORT_ADC_EOC ; 輸入值在al中
????????????test al, 00000001b ??;eoc引腳為高電平?
????????????.IF !zero? ?; AD轉換結束?
????????????????in_port PORT_ADC_DATA ; 輸入值在al中 ???
????????????????mov si, offset sensor_Nx
????????????????mov bh, 0
????????????????mov bl, cur_sensor_channel
????????????????add si, bx
????????????????mov [si], al ; 保存當前通道ADC數字量 ?????????????
????????????????;計算Vx_x100電壓,并保存。sensor_Vx_x100 = 100*5*Nx/256
????????????????mov si, offset sensor_Vx_x100
????????????????shl bx, 1 ; x2
????????????????add si, bx
????????????????mov ah, 0
????????????????mov cx, 500
????????????????mul cx ; dxax = ax *cx ????????????????
????????????????mov cx, 256
????????????????div cx ; ax = dxax/cx
????????????????mov [si], ax
????????????????; 下次采集下一個通道
????????????????inc cur_sensor_channel ????????????????
????????????????.IF cur_sensor_channel == 8
????????????????????mov cur_sensor_channel, 0
????????????????.ENDIF
????????????????mov is_adc_started, 0 ; 下次是啟動AD狀態
????????????.ENDIF
????????.ENDIF
????????popf
????????pop si
????????pop dx
????????pop cx
????????pop bx
????????pop ax ?
????.ENDIF
????iret
isr_20ms_adc endp
;-----------------------------------------------------------------------------
;7.識別鍵盤---8個線性按鍵,非阻塞。出口:保存按鍵位置值到當前按鍵變量cur_key
key_identify proc near ??
????in_port PORT_C_8255 ; ;讀入列值PC7~0
????;(1)判斷是否有鍵按下
????.IF al == 11111111b
????????mov key_is_pressed, 0 ;無按鍵
????????call beep_stop ???????;停止發聲
????.ELSE
????;(2)有鍵按下,軟延時,再次判斷
????????;delay 0ffh
????????in_port PORT_C_8255 ;讀入列值PC7~0
????????.IF al == 11111111b ;再次判斷
????????????mov key_is_pressed, 0 ;無按鍵,是干擾
????????????call beep_stop ???????;停止發聲
????????;(3)確實有鍵按下,識別具體按鍵。
????????.ELSE
????????????mov ch, 8 ;共8個按鍵
????????????mov cl, 0 ;按鍵序號
????????????.WHILE ch != 0
????????????????shr al, 1
????????????????.IF carry? ;C=1?
????????????????????inc cl
????????????????.ELSE
????????????????????.BREAK ;C=0?
????????????????.ENDIF
????????????????dec ch
????????????.ENDW
????????????mov cur_key, cl ;保存鍵序號值到當前按鍵變量
????????????mov key_is_pressed, 1 ;有按鍵
????????????call beep_start ;發聲
????????.ENDIF
????.ENDIF
????ret
key_identify endp
;-----------------------------------------------------------------------------
;8.Kn按鍵按下時,顯示ADC n通道的電壓值,并輸出這個電壓值到DAC
display_CH_Vx proc near
????mov si, offset sensor_Vx_x100
????mov bh, 0
????mov bl, cur_key
????shl bx, 1 ; x2
????add si, bx
????disable_isr ?;關中斷
????mov ax, [si] ;取某通道的sensor_Vx_x100
????enable_isr ??;開中斷
????;計算百位和十位數電壓數值
????mov bx, offset led_table
????mov cl, 100
????div cl ; ahal = ax/cl
????xlat ???;al <-- [bx + al]
????and al,01111111b ;加小數點
????out_port PORT_A_8255, al ;顯示帶小數點的百位數
????mov al, ah
????mov ah, 0
????mov cl, 10
????div cl ; ahal = ax/cl
????xlat ???;al <-- [bx + al]
????out_port PORT_B_8255, al ;顯示十位數
????; DAC輸出當前通道的電壓
????mov si, offset sensor_Nx
????mov bh, 0
????mov bl, cur_key
????add si, bx
????disable_isr ?;關中斷
????mov al, [si] ;取當前通道Nx值
????enable_isr ??;開中斷
????out_port PORT_DAC_DATA, al
????ret
display_CH_Vx endp
;-----------------------------------------------------------------------------
;9.顯示8個通道平均電壓
display_AV_Vx proc near
????; 計算8個通道的平均Nx值
????mov bx, offset sensor_Nx
????mov cl, 8
????mov ax, 0
????mov dx, 0
????clc
????.WHILE (cl != 0)
????????disable_isr ?;關中斷
????????mov dl, [bx]
????????enable_isr ??;開中斷
????????adc ax, dx
????????inc bx
????????dec cl
????.ENDW
????mov cl, 8
????div cl; al = ax/cl
????mov sensor_Nx_AV, al
????out_port PORT_DAC_DATA, al; DAC輸出平均電壓
????; Vx_x100 = 500*Nx/256
????mov ah, 0
????mov cx, 500
????mul cx ; dxax = ax*cx
????mov cx, 256
????div cx ; ax = dxax/cx, sensor_Vx_AV_x100
????; 計算百位和十位數電壓數值
????mov cl, 100
????div cl ; ah(余)al(商) = ax/cl
????mov bx, offset led_table
????xlat ???;al <-- [bx + al]
????and al,01111111b;加小數點
????out_port PORT_A_8255, al ;顯示百位
????mov al, ah ; ah(余)
????mov ah, 0
????mov cl, 10
????div cl ; ahal=ax/cl
????xlat ???;al <-- [bx + al]
????out_port PORT_B_8255, al ;顯示十位數
????ret
display_AV_Vx endp
;-----------------------------------------------------------------------------
End
五. 綜合設計題(15分)
一般樂器需要保存在一定的濕度范圍內,試設計一個濕度閉環采集控制系統。
系統由兩位七段數碼管、4x4 按鍵、濕度檢測和輸出控制加濕器四部分組成。顯示濕度范圍為0~99%;鍵盤有0~9鍵、設置鍵和控制工作鍵共12個鍵可用。
該系統有兩個狀態:目標濕度設置狀態和控制狀態。由鍵盤可輸入設定的目標濕度值和啟動控制工作。
- 在設置狀態時,可以修改設定的目標濕度值, 顯示并保存設定的濕度值;
- 在控制狀態時,顯示采集的當前濕度值,采集的當前濕度與設定濕度進行比較: ?
- 當檢測濕度小于設定目標濕度 - 10% 時,控制強加濕(2V輸出電壓);
- 當檢測濕度大于設定目標濕度 - 10%,并且檢測濕度小于設定目標濕度 + 10% 時,控制中等加濕(1V輸出電壓);
- 當檢測濕度大于設定目標濕度 + 10%時,關閉加濕(0V輸出電壓)。
要求:
(1) 畫出系統硬件連接圖(7分)。
????利用一片8255連接兩位共陽極七段數碼管,以靜態方式顯示;鍵盤以行列反轉方式工作。濕度采集采用ADC0809; 輸出控制加濕器采用DAC0832。當有按鍵時,用8253發出1kHz聲音,用于按鍵提示。 ?
(2)編寫8255、8253初始化程序。編寫靜態顯示子程序(display)、按鍵識別子程序(key)、濕度采集子程序(adc)、控制加濕子程序(dac)和主程序(main)。(8分)選擇使用以下參考資料:
8255A編程字:
從方式名稱、啟動方法、計數值有效期限角度,說明8253的方式1與方式2的工作特點。
方式1是可編程發單穩態方式,由硬件啟動,計數值多次有效,計數過程中輸出保持為低,直到計數到0,OUT向高電平跳變。
方式2是脈沖發生器,有硬件和軟件兩種啟動方式,計數值重復有效,OUT可以產生一個連續的波形。開始計數后當減到1時輸出將變低一個時鐘的寬度,然后恢復為高電平又重新計數。
(對比這個去記憶:
)
為什么對8253A寫入計數值0是最大的計數值?在二進制計數方式下計數值相當于多少?如果8253A的時鐘CLK頻率為1.193MHz,工作在周期工作方式時,計算最大可以產生每秒多少次的周期信號(保留一位小數)?
因為8253A的OUT引腳是的計數器從1減少到0是有變化,設置計數值為0時,第一時鐘到來時數值減1后變為65535,OUT引腳并不變化,則設置計數值為0則比65535還多一個,相當于65536.
取最大計數值65536, 則時鐘為1.193MHz時, 在周期工作方式時,周期 = 1.193MHz/65536 = 18.2Hz? ?(1/一個計數*T)
-用8253A產生5ms的周期信號,做為8259A中斷請求輸入,CLK=1MHz,分析8253A計數器需采用哪種工作方式,計數初值是多少。
方式 3(方波發生器)比較合適。方式 3 能持續輸出周期性的方波信號,且輸出信號的頻率和周期容易通過設置計數初值來控制,滿足產生周期信號的需求
周期 T = 1/CLK = 1μs。要產生 5ms 的周期信號,根據公式計數值 = 要求的定時時間 ÷CLK 周期,計數初值 N = 5ms÷1μs = 5000
方式2(脈沖頻率發生器)也可以
- 已知?
CLK=1MHz
,時鐘周期為?1μs
,目標周期為?5ms=5000μs
。 - 計數初值?
N = 目標周期 / CLK周期 = 5000μs / 1μs = 5000
說明8253的方式2與方式3的工作特點。
- 方式 2(脈沖頻率發生器方式):可軟、硬件啟動計數。計數過程中,輸出端平時為高電平,當計數值減到 1 時,輸出變為低電平,減至 0 后,輸出又變高,同時計數值重新裝入,開始新的計數周期,輸出連續的負脈沖,脈沖頻率為輸入時鐘頻率的 1/N(N 為計數初值)。
- 方式 3(方波發生器方式):同樣可軟、硬件啟動。當計數初值為偶數時,輸出高、低電平寬度相等的方波;為奇數時,高電平比低電平多一個時鐘周期。計數到 0 后自動重新裝入初值繼續計數,持續輸出方波
說明8253的方式1與方式5的工作特點。
- 方式 1(可編程單穩方式):由硬件(GATE 上跳沿)啟動計數,寫入控制字后 OUT 初態為高電平,GATE 觸發后,OUT 輸出 N 個 CLK 寬度的低電平脈沖(N 為計數初值),計數到 0 后,可再次由外部觸發啟動,計數初值下次有效,在 OUT 輸出低電平時,若 GATE 出現上升沿,計數器重新計數,OUT 低電平寬度變長。
- 方式 5(硬件觸發選通方式):也是硬件啟動(GATE 上跳沿),寫入控制字后 OUT 初態為高電平,GATE 觸發后開始計數,計數到 0 時,OUT 輸出一個 CLK 周期的負脈沖,之后恢復高電平,可再次由外部觸發啟動,計數過程中 GATE 上升沿會使計數器從初值重新計數 。
簡述8253的主要特點。(36十二,兼容計數定時)
- 有 3 個獨立的 16 位計數器,可進行 3 個 16 位的獨立計數。
- 每個計數器有六種工作方式,通過編程設置。
- 能進行二進制或十進制(BCD 碼)減法計數 。
- 計數頻率范圍為 0 - 2MHz。
- 既可以作計數器,對外部事件計數;也可以作定時器,根據輸入時鐘頻率和設定的計數初值產生定時信號。
- 所有的輸入輸出都與 TTL 電平兼容。
8253有幾個通道?各采用幾種工作方式?簡述這些工作方式的特點。
- 8253 有 3 個通道,每個通道都可采用 6 種工作方式。
- 方式 0(計數結束中斷方式):軟件啟動計數,每設置一次初值只啟動一次計數過程。寫入控制字后 OUT 初態為低,計數過程中保持低電平,計數到 0 時 OUT 變為高電平,可用于產生中斷請求。GATE 為 1 時正常計數,為 0 時計數暫停。
- 方式 1(可編程單穩方式):硬件(GATE 上升沿)啟動,寫入控制字后 OUT 初態為高,GATE 觸發后 OUT 輸出低電平脈沖,寬度由計數初值決定,可重復觸發,計數初值下次有效。
- 方式 2(脈沖頻率發生器方式):軟、硬件均可啟動,輸出連續負脈沖,頻率為輸入時鐘的 1/N,計數值減到 1 時 OUT 變低,減到 0 時恢復高并重新裝入計數值。
- 方式 3(方波發生器方式):軟、硬件啟動,根據計數初值奇偶輸出不同占空比方波,計數到 0 后自動重裝初值繼續計數。
- 方式 4(軟件觸發選通方式):軟件啟動(裝入初值且 GATE 為高時),計數到 0 時 OUT 輸出一個 CLK 周期的低電平脈沖。
- 方式 5(硬件觸發選通方式):硬件(GATE 上升沿)啟動,計數到 0 時 OUT 輸出一個 CLK 周期的負脈沖,可重復觸發。
8253有幾種讀操作方式?簡述之。
4種(鎖存不算就是3種)
?
- 直接讀/寫low:只讀寫低 8 位,高 8 位清 0;
- 直接讀/寫high或只讀寫高 8 位,低 8 位清 0 。這種方式簡單,但可能丟失數據精度。
- 鎖存讀:計數值鎖存
- 先低 8 位,后高 8 位:先讀取低 8 位,再讀取高 8 位,適用于需要完整獲取 16 位計數值的情況,確保數據的完整性 。
在8253計數器的六種工作方式中,方式2和方式3各輸出何種波形,它們有何特點。
- 方式 2 輸出波形及特點:輸出連續的負脈沖。特點是可軟、硬件啟動,計數值減到 1 時 OUT 變低,減到 0 時恢復高并重新裝入計數值,脈沖頻率為輸入時鐘頻率的 1/N。
- 方式 3 輸出波形及特點:根據計數初值奇偶輸出不同占空比的方波。初值為偶數時,高、低電平寬度相等;初值為奇數時,高電平比低電平多一個時鐘周期,可軟、硬件啟動,計數到 0 后自動重裝初值持續輸出方波。
某系統中有一片8253,其計數器0至控制口地址依次為40H-43H,請按如下要求編程:
8253的控制字:選擇 ,讀寫, 工作, 計數
(1)通道0:方式3,CLK0=2MHz,要求在0UT0輸出1KHz方波。
00 11 011 0 ==> 36H,? 2M/1k=2000
MOV AL, 36H ;控制字
OUT 43H, AL ;寫入控制口
MOV AX, 2000 ;計數初值
MOV AL, AL ;高8位
OUT 40H, AL ;寫入di8位
MOV AL, AH ;低8位
OUT 40H, AL ;寫入高8位
(2)通道l:方式2,CLK1=1MHz,要求OUT1輸出1KHz脈沖波。
01 11 010 0 ===>74H,?
MOV AL, 74H ;控制字
OUT 43H, AL ;寫入控制口
MOV AX, 1000 ;計數初值
MOV AL, AL ;低8位
OUT 41H, AL ;寫入8位
MOV AL, AH ;低8位
OUT 41H, AL ;寫入8位
(3)通道2:方式4,CLK2=OUT1,計數值為1000,計數到0時輸出一個控制脈沖。
10 11 100 0 ==> B8H?
MOV AL, B8H ;控制字
OUT 43H, AL ;寫入控制口
MOV AX, 1000 ;計數初值
MOV AL, AL ;8位
OUT 42H, AL ;寫入8位
MOV AL, AH ;8位
OUT 42H, AL ;寫入8位
某系統采用一片8253產生周期為2ms、個數為10的脈沖序列,已知有一個時鐘源,頻率為2MHz。要求:
(1)畫出硬件接口電路圖,并確定8253的端口地址。
(2)編寫相應程序。
假設 80H~83H
2MHz==>0.5us ==>N=?4000
假設計數器0,讀寫11,工作方式2,2進制? ?==>00 11 010 0
MOV AL, 34H ;控制字
OUT 83H, AL ;寫入控制口
MOV AX, 4000 ;計數初值
MOV AL, AL ;di8位
OUT 82H, AL ;寫入di8位
MOV AL, AH ;gao8位
OUT 81H, AL ;寫入gao8位
畫出8255工作于方式1輸入的波形,并說明其工作過程。
- 方式 0(計數結束中斷方式):軟件啟動計數,每設置一次初值只啟動一次計數過程。寫入控制字后 OUT 初態為低,計數過程中保持低電平,計數到 0 時 OUT 變為高電平,可用于產生中斷請求。GATE 為 1 時正常計數,為 0 時計數暫停。
- 方式 1(可編程單穩方式):硬件(GATE 上升沿)啟動,寫入控制字后 OUT 初態為高,GATE 觸發后 OUT 輸出低電平脈沖,寬度由計數初值決定,可重復觸發,計數初值下次有效。
- 方式 2(脈沖頻率發生器方式):軟、硬件均可啟動,輸出連續負脈沖,頻率為輸入時鐘的 1/N,計數值減到 1 時 OUT 變低,減到 0 時恢復高并重新裝入計數值。
- 方式 3(方波發生器方式):軟、硬件啟動,根據計數初值奇偶輸出不同占空比方波,計數到 0 后自動重裝初值繼續計數。
- 方式 4(軟件觸發選通方式):軟件啟動(裝入初值1個周期,且 GATE 為高時),計數到 0 時 OUT 輸出一個 CLK 周期的低電平脈沖。
- 方式 5(硬件觸發選通方式):硬件(GATE 上升沿)啟動,計數到 0 時 OUT 輸出一個 CLK 周期的負脈沖,可重復觸發。
并行接口芯片8255A的A口-控制口的端口地址依次為60H-63H。編一段程序使從PC5輸出一個負脈沖。另外,若脈沖寬度不夠,應如何解決。
先選擇方式,然后對c操作,0 00 0 1 0 0 0
這里是PC4的單獨的控制字,0xxx{101} 0,
MOV AL, 00001000B ;方式選擇控制字,PC5輸出
OUT 63H, AL ;寫入控制口
MOV AL, 00001010B ;對PC5置位
OUT 62H, AL ;使PC5輸出高電平
NOP ;可插入適當延時
MOV AL, 00001001B ;對PC5復位
OUT 62H, AL ;使PC5輸出低電平,形成負脈沖
- 若脈沖寬度不夠的解決方法:可以在置位和復位 PC5 的指令之間插入更多的 NOP 指令或調用延時子程序,增加延時時間,從而增加負脈沖的寬度。
當串行通信的波特率是2400波特時,數據位時間周期是多少?
數據位時間周期 = 1 / 波特率 = 1 / 2400 s ≈ 0.417ms。
簡述異步通信和同步通信的主要區別。
發送時:
異步:發送器為每個字符加上一個起始位,并按照規定加上奇偶校驗位以及1個、1.5個或者2個停止位。然后在時鐘TXC的作用下,由TXD腳逐位地串行發送出去。
同步:發送緩沖器在準備發送的數據前面先插入由初始化程序設定的一個或兩個同步字符,在數據中插入奇偶校驗位。然后在發送時鐘TXC的作用下,將數據逐位地由TXD引腳發送出去。
接收時:
異步接收方式:在“允許接收”條件下,接收緩沖器監視RXD線。發現起始位后,開始采樣并進行字符裝配,裝配一個后直接送到數據輸入緩沖器,同時發出RXRDY有效信號。
同步接收方式:先搜索同步字符。匹配同步字符后,SYNDET引腳變為高電平
簡述8251A初始化的一般步驟。
送入方式控制字==>檢查是不是異步,
不是==>輸出第一個同步字符,檢查是不是但同步字符,不是就輸出第二個同步字符
輸出命令控制字,檢查需要是否需要復位,不需要就傳送數據,否則回到開頭,
最后檢查是不是完成,沒有完成就回到上面等待繼續送數據,否則回到上面發送命令控制字
串行異步通信字符格式中的停止位和空閑位有什么不同?
- 停止位:是每個字符傳輸結束時發送的高電平信號,用于表示一個字符的結束,其位數可以是 1 位、1.5 位或 2 位,是字符格式的固定組成部分。
- 空閑位:在沒有數據傳輸時,通信線路上保持的高電平狀態,它不屬于任何一個字符的格式部分,只是表示線路處于空閑狀態。
在串行異步通信中,為什么接收時時鐘頻率一般是波特率的16倍頻?
接收端需要對接收數據進行采樣來判斷 數據位。使用 16 倍波特率的時鐘,接收端可以在每位數據的中間位置進行多次采樣(一般為 16 次采樣中的第 7、8、9 次),這樣能更準確地判斷數據位的電平狀態,有效減少因噪聲或線路干擾導致的誤判,提高數據接收的準確性 。
8251A可檢測到幾種接收數據錯誤,詳細說明。
-接收數據位奇偶校驗不對,則標志有奇偶錯誤,在狀態寄存器中PE會置1;
-CPU還沒在把上一個接收的數據取走,下一個數據已經到來,則產生溢出錯誤,在狀態寄存器中OE會置1;
-當沒在檢測到停止位時,產生幀錯誤,狀態寄存器中的FE會置1。
在8251A異步方式時,接收時鐘RxC和發送時鐘TxC都等于115200Hz,波特率因子為1,通信格式為115200、8、N、1,即波特率為115200、8個數據位、無奇偶校驗位和一個停止位。計算每秒可以傳送多少字節? 并畫出傳送字符‘B’的幀格式。
115200/10 = 11520字節/s
8255A:
8253A:
8251A
若要用8253A產生20ms周期的信號,做為8259A中斷請求輸入,其中8253A的時鐘CLK頻率為1MHz,問8253A計數器需要工作在哪兩個工作方式之一?并計算出8253A的計數初值是多少?
方式2(脈沖頻率發生器方式),方式3(方波發生器方式)
1MHz==>1/1*10^6/s
次數= CLK頻率/目標頻率?===>20000
8251A工作于異步通信方式,通信格式為9600、8、N、1,即波特率為9600、8個數據位、無奇偶校驗位和一個停止位。計算每秒可以傳送多少字節? 并畫出傳送字符‘A’的幀格式。要求寫出計算過程。
10=8+1+1+0
9600/10=960字節/s
‘A’=41H=01000001b
8251異步通信工作時,接收時鐘Rxc和發送時鐘Txc都等于19200Hz,波特率因子為16,異步通信格式為:一個起始位、8個數據位、無奇偶位、一個停止位。計算每秒鐘最多能傳送多少個字節?傳送一個字節最少大約需要多少毫秒?
19200/10*16===>30720
一個字節需要 10位 ==?625ms
注意脈沖從右往左