作者 : 鄭旭崇 一. 工作模式 標準的 8051 提供了一個全雙工的串列介面,也就是說傳送與接收在硬體上是分 開的,在傳送資料時,只要將一筆資料寫入 SBUF 即可.而當 8051 接收完一筆資料時 ,則會產生中斷,通知 CPU 來讀取,資料讀取只要執行讀取 SBUF 的指令即可. 串列埠共有四種工作模式.分別是 Mode 0,Mode 1,Mode 2, 和 Mode 3. 以下茲對這四種 Mode 做簡短的介紹. Mode 0: 同步模式. 串列資料由 RxD 傳送與接收,TxD 當作 Clock 輸出. 每筆資料 8 bit.(LSB first) 傳輸速度(baud rate)固定為工作頻率的一半. 通常配合移位暫存器(Shift Register),當做擴充並列 I/O 使用. Mode 1: 非同步模式. 串列資料由 RxD 接收,TxD 輸出. 每筆資料 10 bit.(LSB first) 一個 Start bit(0),八個 data bit,一個 stop bit. 傳輸速度(baud rate)可調整. 通常用於 RS-232,RS-485 的傳輸上,為最常用的一種模式. Mode 2: 非同步模式. 串列資料由 RxD 接收,TxD 輸出. 每筆資料 11 bit.(LSB first) 一個 Start bit(0),九個 data bit,一個 stop bit. 第九個 bit TB8 & RB8 可自行定義 傳輸速度(baud rate)固定為工作頻率的 1/32 或 1/64. 通常用於 RS-232,RS-485 的傳輸上,第九個 Data bit 常用來當同位元 偵測(parity). Mode 3: 非同步模式. 串列資料由 RxD 接收,TxD 輸出. 每筆資料 11 bit.(LSB first) 一個 Start bit(0),九個 data bit,(TB8 & RB8 可自行定義),一個 stop bit. 傳輸速度(baud rate)可調整. 通常用於 RS-232,RS-485 的傳輸上,第九個 Data bit 常用來當同位元 偵測(parity). 二. 串列埠的設定方法 一般常用的 RS-232/RS-485 通訊協定為: 沒有同位元,資料 = 8 bit,一個停止位元. 剛好就是 Model 1 的工作模式,所以以下的設定都是以 MOde 1 設計為主. 在使用串列埠之前,有幾個特殊功能暫存器(SFR)必須設定,分別是 SCON,TH1,TL1,IE,TMOD, SMOD.其中 SMOD 是位元定址,位於 PCON 的 bit 7. 設定串列埠參數流程如圖一所示.常用的 baud rate 如圖二所示.< 圖一 > 串列埠參數設定流程
<圖二>常用的 baud rate 表 程式範例: 2.1 使用組合語言 Initial_serial_port: MOV A,TMOD ;設定 Timer 1 to MODE #2 ANL A,#0FH ; ORL A,#20H ; MOV TMOD,A ; MOV SCON,#50H ;設定 Serial Mode 1 MOV TH1,#FDH ;TH1=TL1 = 256 - (freq / (32 * 12 * BAUD)) MOV TL1,#FDH ;BAUD RATE = 9600 ; 使用振盪頻率:11.059 MHz SETB TR1 ;啟動 Timer1 MOV PCON,#00H ;SMOD = 0 不使用倍頻 MOV IE,#90H ;允許 Serial port 中斷 RET 2.2 使用 C 語言 void InitComms(void) { // initialize communication port TMOD = (TMOD & 0x0F)|0x20; /* 設定 Timer 1 to MODE #2 */ SCON = 0x50; /* 設定 Serial Mode 1 */ TL1 = 0xfd; /* TH1=TL1 = 256 - (freq / (32 * 12 * BAUD)) */ TH1 = 0xfd; /* BAUD RATE = 9600 ; 使用振盪頻率:11.059 MHz */ TR1 = 1; /* 啟動 Timer1 */ PCON = 0x00; /* SMOD = 0 不使用倍頻 */ IE = 0x90; /* enable serial port interrupt */ } 三. 資料的傳送與接收 資料的傳送與接收,在使用上有中斷法與等待法兩種. 3.1 等待法 一般 8051 入門與進階的書籍,為了解說上的方便,皆採用等待法,什麼是等待法呢?就是當沒有 資料接收或傳送時,程式將癡癡的等待,直到接收完一個字元,或傳送完一個字元,才繼續做下一件事. 例如: START: JNB RI,START ;等待接收字元 CLR RI MOV A,SBUF ;.......... MOV SBUF,A JNB TI,$ ;等待傳送字元 CLR TI SJMP START 這種方式最簡單,但也是最沒有效率的.因為 CPU 大部分的時間都是在等待,如果軟體通訊協定稍 微複雜一點的話,這種方法鐵定是行不通的. 3.2 中斷法 中斷法要比等待法來的複雜許多,但是它的執行效率卻遠超過等待法.我們可以在程式中分配 記憶體給通訊埠當作資料貯列,每當 Serial Port 接收完一字元時,便產生中斷,再將 SBUF 值存 入資料貯列中,直到資料貯列滿了為止.傳送資料時,必須在主程式中執行將資料貯列寫入 SBUF 的 動作,當 Serial Port 傳送完一個字元時,會產生中斷,此時只要將資料貯列中的下一個字元,再寫 入 SBUF,直到資料貯列空了為止.當然傳送與接收的資料貯列與索引必須分開,才不會有衝突的現 象產生. 例如: void Serial_ISR() interrupt 4 using COMMS_REGBANK { if ( RI ) { if ( in_queue_index < 16 ) { serial_in_queue[in_queue_index++] = SBUF; } RI = 0; } if ( TI ) { TI = 0; if ( transmit_index < out_buf_index ) { SBUF = serial_out_buf[transmit_index++]; } else { out_buf_index = 0; } } }