STC89C52單片機串口通信以及代碼演示


目錄

串口介紹

硬件電路

電平標准

常見通訊接口比較

51單片機的UART

串口參數及時序圖

串口通信流程圖

串口相關寄存器

波特率的計算方法

中斷模式以及寄存器的配置

數據顯示模式

 代碼示例(串口與電腦互發數據)


串口介紹

串口是一種應用十分廣泛的通訊接口,串口成本低、容易使用、通信線路簡單,可實現兩個設備的互相通信。

單片機的串口可以使單片機與單片機、單片機與電腦、單片機與各式各樣的模塊互相通信,極大的擴展了單片機的應用范圍,增強了單片機系統的硬件實力。

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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM