串行通信的初步認識
通信方式分類
1、按照數據傳送方式:
并行通信:通信時數據的各個位同時傳送,可以實現字節為單位的通信。
但是通信線多,占用資源多,成本高。
串行通信:一次只能發送一位,要發送8次才能發送一個字節。(從低位開始發送)
2、按照數據同步方式:
同步通信:發送端在發送串行數據的同時,提供一個時鐘信號,并按照一定的約定(例如:在時鐘信號的上升沿的時候,將數據發送出去)發送數據,接收端根據發送端提供的時鐘信號來接收數據。如:I2C、SPI等有時鐘信號的協議,都屬于這種通信方式。
異步通信:接收方并不知道數據什么時候會到達,收發雙方可以有各自自己的時鐘。發送方發送的時間間隔可以不均,接收方是在數據的起始位和停止位的幫助下實現信息同步的。
3、按照數據傳輸方向:
單工通信:只允許一方向另外一方傳送信息(即單方面傳送),比如電視遙控機等。
半雙工通信:數據可以在雙方之間相互傳播,同一時間只能其中一方發給另外一方,比如對講機。
全雙工通信:發送數據的同時也能夠接收數據,兩者可以同時進行,比如視頻通話。
UART串口通信
UART(通用異步收發器)是一種通用串行數據總線,用于異步通信。該總線雙向通信,可以實現全雙工傳輸和接收。通過發送和接收數據來使單片機與單片機、單片機與電腦、單片機與各式各樣的模塊互相通信。
對于51單片機,以STC89C52RC為例,有兩個引腳專門用來通信:一個是RXD,一個是TXD,其基本模型如下:
其中,GND必須連接在一起,因為GND是電平基準。
如果單片機1要給單片機2發送11110 0100這個數據,先發送一個0,持續一段時間,再發送一個0,再持續一段時間......以此類推,逐次把所有的位都發送出去。
1、持續時間是多長時間?
引入波特率,也叫比特率:發送二進制數據的速率,習慣上用baud表示。發送一位二進制數據的持續時間為:1/baud。
如果單片機1和單片機2要通信,必須要保持波特率的一致。
2、數據什么時候開始、結束?
UART串口通信里規定:當沒有通信信號發生的時候,通信線路保持高電平。在發送數據之前,先發送一個0表示起始位(這個0的持續時間也是1/baud)。之后再發送8位的數據位,最后再發送一位1表示停止位。
RS232通信接口
串口通信可以實現單片機與單片機通信,也可實現單片機與電腦通信。對于電腦,其CPU就相當于一個單片機。
通常,臺式電腦上有RS232接口(九針九孔,也叫公頭母頭),但筆記本電腦一般沒有,通常用USB虛擬的串口。
RS232接口及其各個針孔功能:
RS232電平標準:
高電平1:-3V~-15V;低電平0:+3V~+15V,為負邏輯。
其不能直接與單片機相連(會燒壞單片機),通常情況下用MAX232轉換芯片來實現我們單片機電壓與電腦電壓之間的轉換。
缺點:傳輸距離有限,最大傳輸距離標準值為50英尺,實際上也只能用在15米左右。且接口使用一根信號線和一根信號返回線而構成共地的傳輸形式,這種共地傳輸容易產生共模干擾,所以抗噪聲干擾性弱。
電平轉換芯片
MAX232轉換芯片
MAX232芯片是美信(MAXIM)公司專為RS-232標準串口設計的單電源電平轉換芯片,使用+5v單電源供電。
TTL/CMOS數據從11引腳(T1IN)、10引腳(T2IN)輸入轉換成RS-232數據從14(T1OUT)、7腳(T2OUT)送到電腦DB9插頭;DB9插頭的RS-232數據從13引腳(R1IN)、8引腳(R2IN)輸入轉換成TTL/CMOS數據后從12引腳(R1OUT)、9引腳(R2OUT)輸出。
USB轉串口通信
我們在工業上常使用RS232串口通信,但在商業上大部分為USB轉UART技術。
USB轉串口設備是一種將計算機的USB接口轉換為通用串口(如RS232、RS485等)的轉換器。這種設備使得沒有串口的老式設備(如編程器、機械控制系統等)能夠通過USB接口與現代計算機連接。
串行口通信相關寄存器
SCON:串行控制寄存器
地址 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
98H | SM0/FE | SM1 | SM2 | REN | TB8 | RB8 | TI | RI |
SCON用于選擇串行通信的工作方式,和某些控制功能,其格式如上,可位尋址。通常只考慮SM0、SM1、REN、TI和RI。
SM0/FE:當PCON寄存器中的SMOD0為1,該位用于幀錯誤檢測;當PCON寄存器中的SMOD0為0時,該位與SM1一起指定串行通信的工作方式,具體如下:
REN:允許/禁止穿行接收控制位。由軟件置位REN,REN=1為允許串行接收狀態,可啟動串行接收器RXD,開始接收信息;軟件復位REN,即REN=0,則禁止接收;
TI:發送中斷請求標志位。在模式1中,停止位開始發送時由內部硬件置1,表示向主機請求中斷;中斷響應后需要軟件復位,即TI=0。初始化為0。
RI:接收中斷請求標志位。在模式1中,接收到停止位時由內部硬件置1;中斷響應后由軟件復位0,初始化為0。
PCON:電源控制寄存器
地址 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
87H | SMOD | SMOD0 | / | POF | GF1 | GF0 | PD | IDL |
不可位尋址。
SMOD:波特率選擇位,就是決定波特率是否加倍。用軟件置位SMOD,當SMOD=1時,使波特率加倍;當SMOD=0時,各工作方式的波特率不加倍。復位時默認SMOD=0。
SMOD0:幀錯誤檢測有效控制位,當SMOD0=1時,SCON寄存器中的SM0/FE位用于FE功能(幀錯誤檢測);當SMOD0=0時,SCON寄存器中的SM0/FE位用于SM0功能,與SM1一起指定串行口工作方式。
SBUF:串行口數據緩沖寄存器
SBUF寄存器有2個,一個是發送寄存器,另一個是接收寄存器(名字都一樣),但在邏輯上SBUF只有一個(地址都為99H),物理結構上,這是倆個完全獨立的寄存器。如果CPU寫SBUF,數據就會被送入發送寄存器準備發送;如果CPU讀SBUF,則讀入的數據一定來自接收寄存器。
簡單來講:a=SBUF,代表單片機從計算機接收到了數據(接收到的數據自動存在接收寄存器SBUF中)并且從接收寄存器SBUF讀取數據并賦給a。SBUF=a,代表單片機要給計算機發送a數據,只需將a賦給發送寄存器SBUF就行,發送寄存器SBUF會自動給計算機發送SBUF中的數據。
波特率的設置
為選擇波特率,關鍵在于定時器/計數器1的溢出率。
溢出率:單位時間內(1秒)定時器/計數器溢出的次數。
通常用的是定時器T1的模式2。模式2中,不再是 TH1 代表高 8 位,TL1 代表低 8 位了,而只有 TL1 在進行計數,當 TL1 溢出后,不僅僅會讓 TF1 變 1,而且還會將 TH1 中的內容重新自動裝到 TL1 中。這樣有一個好處,就是我們可以把想要的定時器初值提前存在 TH1 中,當 TL1 溢出后,TH1 自動把初值就重新送入 TL1 了,全自動的,不需要程序中再給 TL1 重新賦值了。
代碼設計
UART串口通信初始化
void UART_Init(){SCON=0x40; //0100 0000PCON=0;/**通過定時器T1來設置波特率*/TMOD&=0x0F; //0000 1111,清零定時器T1TMOD|=0x20; //0010 1111,設置T1定時模式TL1 = 0xFA; //設定定時初值TH1 = 0xFA; //設定定時器重裝值ET1 = 0; //禁止定時器1中斷TR1 = 1; //啟動定時器1
}
其中,要禁止定時器1中斷。如果允許中斷,當中斷服務程序執行時,可能會引入額外的延遲或抖動,這會干擾波特率發生器的正常工作,導致數據傳輸錯誤或不穩定。
此處SCON=0x40,說明REN=0,不允許接收數據;若需要單片機接收數據,將REN置1,即:SCON=0x50。
串口發送一個字節
void UART_SendByte(unsigned char Byte)
{SBUF=Byte;while(TI==0);//檢測是否完成發送TI=0;
}
串口中斷函數模版
void UART_Routine() interrupt 4
{if(RI==1){執行程序RI=0; }
}
注意,中斷函數要進行條件判斷,因為串口接收和發送字節都能產生中斷請求(即:當TI為1或RI為1時都能產生中斷請求),通過條件判斷來區分接收和發送。