关于SBUF读两次的问题
来源:互联网 发布:mac 解压rar 编辑:程序博客网 时间:2024/06/05 10:20
MCS51的Sbuf看起来读写都是一个地址,其实内部有发送SBUF和接受SBUF,写到T.SBUF,读出RBUF
全双工嘛
下面是台湾同胞的一篇教程
================================
8-1 串列傳輸
串列傳輸為CPU與周邊裝置或CPU與CPU間的資料傳輸方法之一,最簡單的串列傳輸只需兩條傳輸線,使用時的方式每次傳輸一個位元的資料,所以具有傳輸線少的優點,並且容易防止雜訊干擾,適合較遠距離的資料傳輸。然而,由於資料傳輸一次僅送一個位元,因此傳輸資料的速度慢是其缺點。
串列傳輸的結構雖然簡單,但也由於太簡略所以產生許多問題,必須藉由傳輸協定來解決。然而,一個完整的傳輸協定包括從硬體到軟體,相當複雜。其中最基本的一種非同步式串列介面(Universal Asynchronous Receiver Transmitter,簡稱UART)常被用於一般的串列傳輸應用中。
串列傳輸在傳送一個位元組時,必須要傳送8次,而UART的串列傳輸方式是在傳送8個位元資料之前加上一個起始位元,並在傳送8個位元資料之後加上一個停止位元,於是原先傳送一個位元組要傳送8次就增為10次。以下是UART串列傳輸的示意圖,傳輸時間順序由左至右:
等待接收資料 等待接收資料
起始位元
bit 0
bit 1
bit 2
bit 3
bit 4
bit 5
bit 6
bit 7
停止位元
在UART的傳輸結構中,起始位元固定為0,停止位元固定為1,所以接收端的動作是一直不斷的檢查傳輸線的狀態。當傳輸線上的信號一直為1就表示沒有資料傳送;當傳輸線上的信號由1變為0,即表示有資料將傳送,接收端就會開始準備接收8個位元資料,直到傳送完8個位元資料,傳送端最後會送出停止位元,並使傳輸線的信號保持為1,以等待下一次的資料傳輸。經由增加起始位元與停止位元方式,雖然會使串列傳輸效率更降低,但可解決位元資料傳輸的起始與停止之問題。另一串列傳輸協定為傳輸速度,通常以鮑率(Buat Rate),即每秒傳輸的位元數來衡量,一般UART常使用的鮑率有1200、2400、4800、9600及19200等。兩種裝置在進行串列傳輸時,必須決定以何種鮑率來進行資料傳輸,當兩種裝置使用同一鮑率才能確保資料傳輸正確無誤。
§ 8-2 UART的結構
8051單晶片的串列埠是一組全雙工的UART,即8051的UART可以在同一時間進行串列資料的傳送與接收。8051單晶片使用P3.0接腳做為串列傳輸的接收端(RXD),P3.1接腳做為串列傳輸的輸出端(TXD),並利用特殊功能暫存器(Special Function Register,簡稱SFR)中的串列埠緩衝器(Serial Port Buffer,簡稱SBUF)執行串列傳輸的工作。當串列傳輸工作設定完成之後,傳送端會存入一筆資料到SBUF中,並藉以引發資料傳送的動作;當串列傳輸工作設定完成之後,接收端會將接收資料放入SBUF中。但在8051單晶片的UART結構中,接收資料端與傳送資料端實際使用的暫存器並不是同一個,只不過它們均對應到相同的定址位址,因此在傳送或接收資料時,8051單晶片會自動選擇使用不同的暫存器,所以8051的串列埠可以同時進行資料的傳送與接收。
8051單晶片進行串列資料傳輸時,串列埠具有輸入緩衝的功能,即當串列埠接收到一筆資料後,會把資料存放至SBUF中,然後繼續接收資料,並在接收或等待接收下一筆資料的過程中處理SBUF中的資料。因此,串列埠可以持續不斷的接收資料,而不必在接收一筆資料後等待該資料完全處理完畢才進行下一筆資料的接收。但在第二筆資料被UART接收完畢前,第一筆資料須被處理完畢由程式讀入,否則會產生資料流失的問題。
§ 8-3 UART相關暫存器
在SFR記憶體中與UART相關的暫存器有兩個,分別為串列埠控制暫存器(Serial Port Control register,簡稱為SCON)及電源控制暫存器(Power Control register,簡稱為PCON)。以下為此二暫存器的結構圖:
SCON圖
PCON圖
§ 8-4 UART串列埠的四種工作模式
在SCON結構圖中可知SCON位元是由模式選擇位元,可規劃資料位元及旗標位元所組成。而PCON結構圖中可知只有SMOD位元與串列埠傳輸速度有關,其他位元則是用於省電模式的設定。
利用SCON的SM0及SM1可以來選擇四種工作模式:
1. 模式0:SM1=SM0=1
串列埠設定為模式0時,串列資料的傳送與接收都是利用RXD接腳進行,而TXD接腳則做為輸出移位脈波,此脈波的鮑率固定為8051單晶片的振盪頻率之1/12。當要從串列埠傳送資料時,只要執行一個資料寫入SBUF指令,則會引發資料傳送的動作;資料傳送完畢後,8051CPU會將SCON中的TI位元設定為1,通知串列中斷產生。當要從串列埠接收資料時,須先以軟體設定SCON中的REN位元,然後執行清除RI位元,串列埠就會依時序進行接收的工作,資料接收完畢後,8051CPU會將SCON中的位元設定為1,通知串列中斷產生。
模式0通常是用於I/O的擴充,而非用於串列通訊。只要將RXD及TXD接腳連接到一個並入串出(PISO)的IC,就可以擴充一個8位元的輸入埠;將RXD及TXD接腳連接到一個串入並出(SIPO)的IC,就可以擴充一個8位元的輸出埠。
2. 模式1:SM1=1、SM0=0
串列埠設定為模式1時,8051CPU每次傳送與接收的資料為10位元,這10位元分成下列3部分,分別為:
(1)起始位元:固定為0,佔用一個位元。
(2)資料位元:佔8個位元,依低位元至高位元傳輸順序。
(3)停止位元:固定為1,佔用一個位元。
模式1資料傳輸的鮑率是由Timer 1設定,其設定如下表:
常用的鮑率值
Timer 1
鮑率
振盪器頻率
SMOD
C/T
模式
載入值
模式0 (最大1M)
12M Hz
×
×
×
×
模式2 (最大375K)
12M Hz
1
×
×
×
模式1、3 (最大62.5K)
12M Hz
1
0
2
FFH
19200
11.0592M Hz
1
0
2
FDH
9600
11.0592M Hz
0
0
2
FDH
4800
11.0592M Hz
0
0
2
FAH
2400
11.0592M Hz
0
0
2
F4H
1200
11.0592M Hz
0
0
2
E8H
137.5
11.0592M Hz
0
0
2
1DH
110
6M Hz
0
0
2
72H
110
12M Hz
0
0
1
FEEBH
串列埠設定完畢後,8051CPU執行寫入資料到SBUF指令時,就會進行資料傳送的動作。當資料傳送完畢後,CPU會將SCON中的TI位元設定,通知串列中斷產生。而在資料接收時,當RXD接腳由1變為0時開始接收資料,CPU依序接收10bit資料;接收資料完畢後,CPU會測試RI、SM2及停止位元是否符合下列條件:
(1)RI位元清除為0
(2)SM2位元清除為0或所接收到的停止位元設定為1
當上列條件都符合時,8051CPU則將所接收到的8位元資料存入SBUF中,並將所接收到的停止位元存入SCON的RB8位元中,再將RI位元設定為1,通知串列中斷產生。若上列條件不符合時,則該次所接收的資料將會流失。
3. 模式2:SM1=0、SM0=1
串列模式設定為2時,8051CPU每次傳送與接收的資料為11位元,這11位元是由下列4部分所組成,分別為:
(1)起始位元:固定為0,佔用一個位元
(2)資料位元:佔8個位元,依低位元至高位元傳輸順序
(3)可規劃資料位元:佔用一個位元(TB8或RB8)
(4)停止位元:固定為1,佔用一個位元
模式2資料傳輸的鮑率是由SMOD決定,當SMOD=0時,鮑率為375K Hz;當SMOD=1時,鮑率為187.5K Hz。當傳送資料時,必須先由軟體設定SCON中TB8的位元值,然後再執行資料寫入SBUF指令,以驅動資料開始傳送的動作,然後串列埠會依序傳送起始位元、資料位元、可規劃資料位元TB8及停止位元;傳送完畢後,8051CPU會設定SCON中TI位元值,以通知串列中斷產生。
當接收資料時,若RXD接腳信號由1變為0時開始接收資料,8051CPU會依序接收11位元資料;接收資料完畢後,CPU會測試RI、SM2及停止位元是否符合下列條件:
(1)RI位元清除為0
(2)SM2位元清除為0或所接收之可規劃資料位元為1
當上列條件都符合時,8051CPU則將所接收到的8位元資料存入SBUF中,且將所接收到的可規劃資料位元存入SCON的RB8位元,再將RI位元設定為1,以通知串列中斷發生。若上列條件不能同時符合時,則該次所接收的資料將會流失。
4. 模式3:SM1=1、SM0=1
串列埠設定為模式3時,其動作與模式2相似,其唯一的差別在於模式3的傳輸速度之鮑率值設定與模式1相同,是由Timer1設定。
以上四種串列埠模式,在傳輸資料時,鮑率的準確與否對資料之接收非常的重要,因此因此在使用模式1與模式3時,要先啟動Timer工作。以下列串列埠使用的步驟以檢查串列埠設定是否正確:
(1) 設定Timer1工作模式並根據傳輸鮑率設定TH1及TL1(UART模式0與模式2不用此項)
(2)決定SMOD位元值為0或1
(3)設定串列埠工作模式,並清除RI、TI位元為0,及設定REN位元為1
(4)致能串列埠中斷
(5)啟動Timer1開始計時(UART模式0與模式2不用)
(6)執行〝MOV SBUF,XX〞指令,來啟動UART傳送資料
§ 8-5 串列埠中斷應用實例
利用UART模式1做為串列埠工作模式時,將TXD接到RXD,即可將TXD傳送出的信號再由RXD接收,並利用一七段顯示器經由7447解碼電路,顯示出其傳送值。以下為其電路圖:
UART例題圖
UART程式
;
; 本程式以UART模式1做為串列埠工作模式, 將TXD傳送的資料再由RXD接收回來
;
;
; 動作: TXD傳送的資料經由RXD接收回來, 並顯示在七段LED顯示器上
;
;
DAT EQU 45H
ORG 00H
JMP START ;規避00H至2FH間之中斷向量執行位址
ORG 30H ;
MOV SP,#30H ;將堆疊指標重新指向
START: MOV TMOD,#00100001B ;設定Timer0為模式1, Timer1為模式2
ANL PCON,#01111111B ;設定鮑率為9600 bit/sec
MOV TH1,#FDH
SETB TR1 ;啟動Timer1
MOV SCON,#01010000B ;串列埠模式1 設定為接收
MOV DAT,#0
Loop: MOV SBUF,DAT ;DAT載入SBUF開始傳送
Wait_R: JBC RI,Finish ;測試接收中斷旗號是否為1
JMP Wait_R ;否, 再回去測試
Finish: CLR TI ;是, 清除傳送旗標準備下次傳送
MOV A,SBUF ;由SBUF讀入接收資料
MOV P1,A ;由P1 輸出顯示
MOV R5,#20
CALL DELAY ;延遲1 秒
INC DAT
MOV A,#0AH
CJNE A,DAT,Loop
MOV DAT,#0
JMP Loop
DELAY: MOV TH0,#>(65536-50000)
MOV TL0,#<(65536-50000)
SETB TR0
Wait: JBC TF0,Time_out
JMP Wait
Time_out:
DJNZ R5,DELAY
CLR TR0
RET
END
程式說明:本程式以UART模式1方式傳送與接收資料,以位址45H之內容值做為傳輸,首先將45H的內容設為0,然後每隔1秒將其內容加1,再將45H之內容位元組資料經由UART的TXD傳送出去,並由UART的RXD將此資料接收回來且輸出到P1,利用七段LED顯示器顯示其資料值。其中IC7447是做為解碼電路,而9012電晶體則可用於控制七段LED之顯示與否。
- 关于SBUF读两次的问题
- 关于scanf要写两次的问题
- 关于spring容器初始两次的问题
- 关于react组件渲染两次的问题
- 关于default.aspx的page_load执行两次的问题
- 关于Asp.net页面Page_Load被执行两次的问题
- 关于页面自动提交两次的问题(360浏览器)
- 关于 contentObserver()中的onChang()执行两次的问题
- 关于struts2中action请求会执行两次的问题
- 关于struts2中action请求会执行两次的问题
- 关于JComboBox触发事件总是执行两次的问题
- 关于用表单提交给action提交两次的问题
- 关于struts2中action请求会执行两次的问题
- 关于程序两次点击才能正常响应的问题
- 关于页面自动提交两次的问题(360浏览器)
- 关于 contentObserver()中的onChang()执行两次的问题
- 关于Activity中onCreate()方法执行两次的问题
- 关于Spring mvc 一次请求Controller执行两次的问题
- 4.利用逻辑门实现加法器和减法器
- 关于原码、反码、补码
- the examples :how to use LP_SOLVE.EXE
- 本空间已不再使用,欢迎访问 http://blog.csdn.net/maikforever/
- 解析32位系统无法完全识别4GB内存的问题
- 关于SBUF读两次的问题
- Boost学习系列2-智能指针(上)
- O(n)时间求满足和的数对
- ubuntu mysql安装
- Secure Store Service无法检索凭据,返回的错误为"拒绝访问"
- 数字信号处理与数字信号处理器
- MFC 消息类型
- Spring+quartz+我犯的傻
- Linux驱动学习--时间、延迟及延缓操作(转载)