目錄
串口介紹
串口是一種應用十分廣泛的通訊接口,串口成本低、容易使用、通信線路簡單,可實現兩個設備的互相通信。
單片機的串口可以使單片機與單片機、單片機與電腦、單片機與各式各樣的模塊互相通信,極大的擴展了單片機的應用范圍,增強了單片機系統的硬件實力。
51單片機內部自帶UART(Universal Asynchronous Receiver Transmitter,通用異步收發器),可實現單片機的串口通信。
硬件電路

簡單雙向串口通信有兩根通信線(發送端TXD和接收端RXD)
TXD與RXD要交叉連接
當只需單向的數據傳輸時,可以直接一根通信線
當電平標准不一致時,需要加電平轉換芯片
下圖是以前的投影儀的插口線腳分布圖,可以看的也用了TXD來發送數據,RXD來接受數據

電平標准
電平標准是數據1和數據0的表達方式,是傳輸線纜中人為規定的電壓與數據的對應關系,串口常用的電平標准有如下三種:
TTL電平:+5V表示1,0V表示0
RS232電平:-3~-15V表示1,+3~+15V表示0
RS485電平:兩線壓差+2~+6V表示1,-2~-6V表示0(差分信號)
注意這里單片機用的是TTL電平,而計算機用的是RS232電平,所以在單片機與電腦進行串口通信的時候要加電平轉換芯片
常見通訊接口比較

全雙工:通信雙方可以在同一時刻互相傳輸數據
半雙工:通信雙方可以互相傳輸數據,但必須分時復用一根數據線
單工:通信只能有一方發送到另一方,不能反向傳輸
異步:通信雙方各自約定通信速率
同步:通信雙方靠一根時鍾線來約定通信速率
總線:連接各個設備的數據傳輸線路(類似於一條馬路,把路邊各住戶連接起來,使住戶可以相互交流)
51單片機的UART
串口參數及時序圖
波特率:串口通信的速率(發送和接收各數據位的間隔時間)
檢驗位:用於數據驗證(九位數據模式時的最后一位,RB8/TB8)
停止位:用於數據幀間隔

串口通信流程圖
看串口模式圖我們軟件在進行編程的時候要注意:
SUBF(數據緩存器),TI(數據發送標志位),RI(數據接受標志位)的配置要求
以及T1溢出率的配置(TH1,TL1初值),SMOD置0時為正常波特率,置1時波特率加倍
串口相關寄存器
這里還是為了盡可能的全面,所以在手冊截的圖。



補充說明一下,波特率的計算方法:
在圖上的寄存器SCON的配置中也可以看出來。1,是看SMOD的配置為1那么波特率加倍。2,其次是定時器1的溢出率,計算方法是周期的倒數。
下面舉波特率為4800的計算方法(也是我們下面的代碼里面的定時器1配置的)
設T=13us,定時器1的溢出率=1/T=0.0769230769230769,為使定時器誤差小,這里的SMOD的配置為1,所以最后,波特率=(1/T)x(1/16)x1000000=4,807.692307692308 約等於4800
中斷模式以及寄存器的配置
串口中斷位要打開,而定時器1的中斷就不用開了(溢出后不用進行中斷執行其他操作,計時器只是提供穩定的波特率)
這里有個小錯誤:上面的為定時器0,下面的是定時器1

數據顯示模式
HEX模式/十六進制模式/二進制模式:以原始數據的形式顯示
文本模式/字符模式:以原始數據編碼后的形式顯示(即ASCLL代碼編譯以后)

代碼示例(串口與電腦互發數據)
主函數:
#include <REGX52.H>
#include "UART.h"
unsigned char Sec;
void main()
{
UART_Init(); //串口初始化
while(1)
{
}
}
void UART_Routine() interrupt 4
{
if(RI==1) //如果接收到數據,硬件自動將標志位RI置1,表示接收到了電腦發送的數據
{
P2=SBUF; //讀取SBUF數據,取反后輸出到LED
UART_SendByte(SBUF);//將受到的數據發回串口(實現單片機向電腦發送數據)
RI=0; //按照手冊RI需要手動置0
}
}
SUBF輸入函數:
#include <REGX52.H>
void UART_Init()
{
SCON = 0x50; //工作方式1,其中的REN為1,允許接收
PCON |= 0x80; //為了減少誤差波特率加倍
TMOD &= 0x0F; //設置定時器1模式
TMOD |= 0x20; //設置定時器1模式
TL1 = 0xF3; //設定定時初值
TH1 = 0xF3; //設定定時器重裝值
ET1 = 0; //禁止定時器1中斷
TR1 = 1; //啟動定時器1
ES=1; //設置接收發送中斷
EA=1;
}
void UART_SendByte(unsigned char Byte)
{
SBUF=Byte; //將SBUF數據賦值
while(TI==0);//if(TI==1) {TI=0;}在停止位后硬件自動將TI置1,按照手冊,這里要手動置0
TI=0;
}




