前言
人類生存于世,少不了溝通。溝通使人類互相認知,傳遞信息,提升生活品質。但然單片機也需要,不然單單一個機器,無法構成一個系統,發揮更大的力量。只有單片機與外圍設備傳遞信息,互相反饋才會有一個完美的系統。串行口通信就被發明出來,下面來了解串行口通信(uart)。
幾個概念
為了能更好理解串行口通信,在介紹它之前,先來看看幾個概念,補充知識,方便深入明白uart工作原理。
通信方式
通信方式
通信方式有兩種,分別是并行通信和串行通信。
并行通信:并行是指多比特數據同時通過并行線進行傳送,這樣數據傳送速度大大提高,但并行傳送的線路長度受到限制,因為長度增加,干擾就會增加,數據也就容易出錯。
串行通信:串行通信是指 使用一條數據線,將數據一位一位地依次傳輸,每一位數據占據一個固定的時間長度。其只需要少數幾條線就可以在系統間交換信息,特別適用于計算機與計算機、計算機與外設之間的遠距離通信。
拿汽車通道來說,并行通信就是多車道,多輛車一起行駛,而串行通信就是單車道,只能一輛一輛車通過。
串行通信制式
串行通信制式
串行通信制式有單工通信,半雙工通信,雙工通信三種。
單工通信:單工通信信道是單向信道,發送端和接收端的身份是固定的,發送端只能發送信息,不能接收信息;接收端只能接收信息,不能發送信息,數據信號僅從一端傳送到另一端,即信息流是單方向的。
半雙工通信:半雙工數據傳輸指數據可以在一個信號載體的兩個方向上傳輸,但是不能同時傳輸。例如,在一個局域網上使用具有半雙工傳輸的技術,一個工作站可以在線上發送數據,然后立即在線上接收數據,這些數據來自數據剛剛傳輸的方向。像全雙工傳輸一樣,半雙工包含一個雙向線路(線路可以在兩個方向上傳遞數據)。
雙工通信:雙工通信是指在同一時刻信息可以進行雙向傳輸,和打電話一樣,說的同時也能聽,邊說邊聽。這種發射機和接收機分別在兩個不同的頻率上(兩個頻率差有一定要求)能同時進行工作的雙工機也稱為異頻雙工機。
三種通信制式很容易理解,對照上圖看,單工通信不就是單方面通信,只能發出指令或接收指令。半雙工通信就是能接收又能發送,但是不能同時進行。雙工就最厲害,可以同時發送和接收指令。
串行通信分類
串行通信有兩種,一位異步串行通信,二為同步串行通信。
異步串行通信:異步串行通信是指通信雙方以一個字符(包括特定附加位)作為數據傳輸單位且發送方傳送字符的間隔時間不一定,具有不規則數據段傳送特性的串行數據傳輸。
同步串行通信:所謂同步通信是指在約定的通信速率下,發送端和接收端的時鐘信號頻率和相位始終保持一致(同步),這就保證了通信雙方在發送和接收數據時具有完全一致的定時關系。
兩種串行通信不同就只有時間,在發送字符時,異步可以是不同時間間隔發送,但同步只能以固定的時間間隔發送。
波特率
波特率:波特率表示每秒鐘傳送的二進制位數,是衡量數據傳送速率的指標,它用單位時間內載波調制狀態改變的次數來表示。
相互通信的甲乙雙方必須具有相同的波特率,不然無法成功完成串行通信。
概述
52單片機具有一個全雙工串行通信口。一個全雙工UART(通用異步接收發送器)的串行I/O口,用于實現單片機之間或單片機與微機之間的串行通信;片內振蕩器和時鐘產生電路,石英晶體和微調電容需要外接。最佳振蕩頻率為6M—12M。管腳RXD( P3.0),TXD(P3.1)與串口通信有關。波特率可以設置。
內部結構
串行口內部結構邏輯圖
串行口通信與三個寄存器有關,分別是:
?1.?PCON寄存器
?2.?SCON寄存器
?3.?SBUF特殊功能寄存器
寄存器
PCON電源管理寄存器
電源管理寄存器
SMOD:該位與串口通信有關。
SMOD=0; 串口方式1,2,3時,波特率正常。
SMOD=1; 串口方式1,2,3時,波特率加倍。
LVDF:低電壓檢測標志位,同時也是低電壓檢測中斷請求標志位
GF1,GF0:兩個通用工作標志位,用戶可以自由使用。
PD:掉電模式設定位。
PD=0 單片機處于正常工作狀態。
PD=1 單片機進入掉電(Power Down)模式 ,可由外部中斷或硬件復位模式喚醒,進入掉電模式后,外部晶振停振,CPU、定時器、串行口全部停止工作,只有外部中斷工作。在該模式下,只有硬件復位和上電能夠喚醒單片機。
IDL:空閑模式設定位。
IDL=0 單片機處于正常工作狀態。
IDL=1 單片機進入空閑(Idle)模式,除CPU不工作外,其余仍繼續工作,在空閑模式下可由任一個中斷或硬件復位喚醒。
這個寄存器只有SMOD位與串行口通信有關。系統復位默認為SMOD=0。當為用52單片機的定時器2產生波特率時,波特率不受SMOD影響。用定時器1產生波特率時,不去設置,就默認為0,波特率正常,設置為1時,波特率加倍。
SCON串行口控制寄存器
串行口控制寄存器
SM0,SM1:共同決定串行口工作模式。
SM2:多機通信控制位。在方式0中,SM2一定要等于0。在方式1中,當SM2為1時則只有接收到有效停止位時,RI才置1。在方式2或3中,當SM2為1且接收到的第9位數據RB8為0時,RI才置1。
REN:接收允許控制位。由 軟件置位以允許接收,又由 軟件清零來禁止接收。
TB8:要發送數據的第9位。在方式2或3中,要發送的第9位數據,根據需要由軟件置1或清零軟件置1或清零。例如,可約定作為奇偶校驗位,或在多機通信中作為區別地址幀或數據幀的標志位。(很少用)
RB8:接收到的數據的第9位。在方式0中不使用RB8。在方式1中,若SM2為0,RB8為接收到的停止位。在方式2或3中,RB8為到的第9位數據。(很少用)
TI:發送中斷標志。在方式0中,第8位發送結束時,由 硬件置位。在其它方式的發送停止位前,由 硬件置位。TI置位既表示一幀信息發送結束,同時也向CPU申請中斷。可根據需要,用軟件查詢的方法獲得數據已發送完畢的信息,或用中斷的方式來發送下一個數據。TI必須用 軟件清零。
RI:接收中斷標志位。在方式0中,當接收完第8位數據后,由 硬件置位。在其它方式中,在接收到停止位的中間時刻由硬件置位(例外情況見對SM2的說明)。RI表示一幀數據接收完畢,可用查詢的方法獲知或者用中斷的方法獲知。RI也必須用 軟件清零。串行口工作模式
由于52單片機內部有一個硬件模塊,讓它自動接收數據,接收完了,通知我們一下就可以了,就不需要再手動配置TB8,RB8。只要配置好SCON,內部就自動幫弄好了。
SBUF特殊功能寄存器
特殊功能寄存器
SBUF是指串行口中的兩個緩沖寄存器,一個是發送寄存器,一個是接收寄存器,在物理結構上是完全獨立的,但地址是重疊的。它們都是字節尋址的寄存器,字節地址均為99H。只要在編寫程序時,用不同指令即可操作兩個寄存器。
比如,SBUF=A;這個是指將A的數據移入發送寄存器,然后發送寄存器再把數據發送出去。A=SBUF;則是指將接受寄存器中的數據賦值給A。
串行口方式1
方式1邏輯圖
串行口為10位通用異步接口。發送或接收一幀數據信息為10位,包括1位起始位“0”、8位數據位、1位停止位“1”。發送數據:數據從TXD端口輸出,當數據寫入發送緩沖器SBUF時,就啟動發送器發送。發送完一幀數據后,置中斷標志TI=1,申請中斷,通知CPU可以發送下一個數據了。接收數據:首先使REN=1(允許接收數據),串行口從RXD接收數據,當采樣到1至0跳變時,確認是起始位“0”,就開始接收一幀數據,當接收完一幀數據時,置中斷標志RI=1,申請中斷,通知CPU從SBUF取走接收到的數據 。
計算波特率
方式1波特率計算
溢出速率即溢出頻率,只要算出定時器每溢出一次所需要的時間T,那溢出率就是1/T。計算在沒有波特率加倍(SMOD=0)的情況下,波特率為9600bps時怎樣賦值計數器。這里說明一下,由于波特率是需要很精確的,不然通信會出錯。如果采用定時器工作模式1,采用人工重載,會有較大誤差,因為進入中斷函數也需要時間,累積時間就會出錯。所以這里運用工作模式2,8位自動重裝。計數器自動重裝不需人工干預,減少誤差。
對照上面公式,波特率不加倍,SMOD=0,工作模式2,那n=8,波特率=9600,就可以算出x=253,十六進制為fd。
編寫步驟
設置串行口方式
設置定時器工作模式
計數器寄存器賦值
中斷寄存器控制
啟動定時器中斷
發送函數
接收函數
范例1
#include
unsigned?char?date;????//定義變量數據中斷
bit?flag;??//定義變量標志
void?send?();?//聲明發送函數
void?receive?();?//聲明接收函數
void?initialize?();????//聲明初始化函數
main()
{????????
????initialize();??//調用初始化函數
????while(1)
????{
????????send();????//調用發送函數
????????receive();?//調用接收函數
????}
}
void?initialize()??//初始化函數
{
????SCON=0X50;?????//0011?0000?串行口工作模式1
????TMOD?=?0X20;????//定時器1工作模式2,8為自動重裝
????TH1?=?0xFD;?????//設定定時初值????????波特率為9600
????TL1?=?0xFD;?????//設定定時器重裝值
????TR1?=?1;????????//啟動定時器1
????IE=0;
}
void?send()?????????//發送函數
{
????if(flag==1)????//證明已經接收數據
????{???
????????SBUF=date;????//將接收的數據發送出去
????????while(!TI);???//等待發送中斷
????????TI=0;?????????//軟件置0
????????flag=0;???????//清零
????}
}
void?receive()???????//接收函數
{
????while(!RI);???//等待接收中斷
????date=SBUF;????//將收到的數據存進接收緩沖寄存器
????RI=0;????????//軟件置0
????flag=1;??????//將標志位置1
}
范例1是將接受的數據原封不動發送出去。采用查詢法,故不需要打開串口中斷,不用中斷函數。只需不斷查詢TI,RI的值,就知道數據接收發送情況。
范例2
#include
unsigned?char?date;
bit?flag;
main?()
{
????SCON=0X50;??????//初始化
????TMOD=0X20;
????TH1=0XFD;???????????????????????????????????
????TL1=0XFD;
????IE=0X90;
????TR1=1;
????while(1);
}
void?interrupt_uart()?interrupt?4?????//中斷函數
{
????if(RI==1)????????//判斷有無數據接收
????{
????????date=SBUF;?????//將寄存器的值賦給變量
????????RI=0;??????????//置0
????????flag=1;????????//標志位置1
????}
????if(flag==1)?????????????//已接收數據
????{
????????SBUF=date;????????//將數據發出
????????while(!TI);
????????TI=0;
????????flag=0;
????}
}
與范例1如出一撤,就不詳細注釋。
總結
在串口通信中,方式1是最常用的,要認真理解方式1。串行數據一位一位的已經不用處理了,52單片機已經有一個模塊處理完了。只要知道接收一個數據,產生一次接收中斷,要軟件置0.,發送一個數據會產生一次發送中斷,也要軟件置0。自行置0,處理好數據就OK。下一篇將介紹其他三種方式,歡迎關注。
前言
人類生存于世,少不了溝通。溝通使人類互相認知,傳遞信息,提升生活品質。但然單片機也需要,不然單單一個機器,無法構成一個系統,發揮更大的力量。只有單片機與外圍設備傳遞信息,互相反饋才會有一個完美的系統。串行口通信就被發明出來,下面來了解串行口通信(uart)。
幾個概念
為了能更好理解串行口通信,在介紹它之前,先來看看幾個概念,補充知識,方便深入明白uart工作原理。
通信方式
通信方式
通信方式有兩種,分別是并行通信和串行通信。
并行通信:并行是指多比特數據同時通過并行線進行傳送,這樣數據傳送速度大大提高,但并行傳送的線路長度受到限制,因為長度增加,干擾就會增加,數據也就容易出錯。
串行通信:串行通信是指 使用一條數據線,將數據一位一位地依次傳輸,每一位數據占據一個固定的時間長度。其只需要少數幾條線就可以在系統間交換信息,特別適用于計算機與計算機、計算機與外設之間的遠距離通信。
拿汽車通道來說,并行通信就是多車道,多輛車一起行駛,而串行通信就是單車道,只能一輛一輛車通過。
串行通信制式
串行通信制式
串行通信制式有單工通信,半雙工通信,雙工通信三種。
單工通信:單工通信信道是單向信道,發送端和接收端的身份是固定的,發送端只能發送信息,不能接收信息;接收端只能接收信息,不能發送信息,數據信號僅從一端傳送到另一端,即信息流是單方向的。
半雙工通信:半雙工數據傳輸指數據可以在一個信號載體的兩個方向上傳輸,但是不能同時傳輸。例如,在一個局域網上使用具有半雙工傳輸的技術,一個工作站可以在線上發送數據,然后立即在線上接收數據,這些數據來自數據剛剛傳輸的方向。像全雙工傳輸一樣,半雙工包含一個雙向線路(線路可以在兩個方向上傳遞數據)。
雙工通信:雙工通信是指在同一時刻信息可以進行雙向傳輸,和打電話一樣,說的同時也能聽,邊說邊聽。這種發射機和接收機分別在兩個不同的頻率上(兩個頻率差有一定要求)能同時進行工作的雙工機也稱為異頻雙工機。
三種通信制式很容易理解,對照上圖看,單工通信不就是單方面通信,只能發出指令或接收指令。半雙工通信就是能接收又能發送,但是不能同時進行。雙工就最厲害,可以同時發送和接收指令。
串行通信分類
串行通信有兩種,一位異步串行通信,二為同步串行通信。
異步串行通信:異步串行通信是指通信雙方以一個字符(包括特定附加位)作為數據傳輸單位且發送方傳送字符的間隔時間不一定,具有不規則數據段傳送特性的串行數據傳輸。
同步串行通信:所謂同步通信是指在約定的通信速率下,發送端和接收端的時鐘信號頻率和相位始終保持一致(同步),這就保證了通信雙方在發送和接收數據時具有完全一致的定時關系。
兩種串行通信不同就只有時間,在發送字符時,異步可以是不同時間間隔發送,但同步只能以固定的時間間隔發送。
波特率
波特率:波特率表示每秒鐘傳送的二進制位數,是衡量數據傳送速率的指標,它用單位時間內載波調制狀態改變的次數來表示。
相互通信的甲乙雙方必須具有相同的波特率,不然無法成功完成串行通信。
概述
52單片機具有一個全雙工串行通信口。一個全雙工UART(通用異步接收發送器)的串行I/O口,用于實現單片機之間或單片機與微機之間的串行通信;片內振蕩器和時鐘產生電路,石英晶體和微調電容需要外接。最佳振蕩頻率為6M—12M。管腳RXD( P3.0),TXD(P3.1)與串口通信有關。波特率可以設置。
內部結構
串行口內部結構邏輯圖
串行口通信與三個寄存器有關,分別是:
?1.?PCON寄存器
?2.?SCON寄存器
?3.?SBUF特殊功能寄存器
寄存器
PCON電源管理寄存器
電源管理寄存器
SMOD:該位與串口通信有關。
SMOD=0; 串口方式1,2,3時,波特率正常。
SMOD=1; 串口方式1,2,3時,波特率加倍。
LVDF:低電壓檢測標志位,同時也是低電壓檢測中斷請求標志位
GF1,GF0:兩個通用工作標志位,用戶可以自由使用。
PD:掉電模式設定位。
PD=0 單片機處于正常工作狀態。
PD=1 單片機進入掉電(Power Down)模式 ,可由外部中斷或硬件復位模式喚醒,進入掉電模式后,外部晶振停振,CPU、定時器、串行口全部停止工作,只有外部中斷工作。在該模式下,只有硬件復位和上電能夠喚醒單片機。
IDL:空閑模式設定位。
IDL=0 單片機處于正常工作狀態。
IDL=1 單片機進入空閑(Idle)模式,除CPU不工作外,其余仍繼續工作,在空閑模式下可由任一個中斷或硬件復位喚醒。
這個寄存器只有SMOD位與串行口通信有關。系統復位默認為SMOD=0。當為用52單片機的定時器2產生波特率時,波特率不受SMOD影響。用定時器1產生波特率時,不去設置,就默認為0,波特率正常,設置為1時,波特率加倍。
SCON串行口控制寄存器
串行口控制寄存器
SM0,SM1:共同決定串行口工作模式。
SM2:多機通信控制位。在方式0中,SM2一定要等于0。在方式1中,當SM2為1時則只有接收到有效停止位時,RI才置1。在方式2或3中,當SM2為1且接收到的第9位數據RB8為0時,RI才置1。
REN:接收允許控制位。由 軟件置位以允許接收,又由 軟件清零來禁止接收。
TB8:要發送數據的第9位。在方式2或3中,要發送的第9位數據,根據需要由軟件置1或清零軟件置1或清零。例如,可約定作為奇偶校驗位,或在多機通信中作為區別地址幀或數據幀的標志位。(很少用)
RB8:接收到的數據的第9位。在方式0中不使用RB8。在方式1中,若SM2為0,RB8為接收到的停止位。在方式2或3中,RB8為到的第9位數據。(很少用)
TI:發送中斷標志。在方式0中,第8位發送結束時,由 硬件置位。在其它方式的發送停止位前,由 硬件置位。TI置位既表示一幀信息發送結束,同時也向CPU申請中斷。可根據需要,用軟件查詢的方法獲得數據已發送完畢的信息,或用中斷的方式來發送下一個數據。TI必須用 軟件清零。
RI:接收中斷標志位。在方式0中,當接收完第8位數據后,由 硬件置位。在其它方式中,在接收到停止位的中間時刻由硬件置位(例外情況見對SM2的說明)。RI表示一幀數據接收完畢,可用查詢的方法獲知或者用中斷的方法獲知。RI也必須用 軟件清零。串行口工作模式
由于52單片機內部有一個硬件模塊,讓它自動接收數據,接收完了,通知我們一下就可以了,就不需要再手動配置TB8,RB8。只要配置好SCON,內部就自動幫弄好了。
SBUF特殊功能寄存器
特殊功能寄存器
SBUF是指串行口中的兩個緩沖寄存器,一個是發送寄存器,一個是接收寄存器,在物理結構上是完全獨立的,但地址是重疊的。它們都是字節尋址的寄存器,字節地址均為99H。只要在編寫程序時,用不同指令即可操作兩個寄存器。
比如,SBUF=A;這個是指將A的數據移入發送寄存器,然后發送寄存器再把數據發送出去。A=SBUF;則是指將接受寄存器中的數據賦值給A。
串行口方式1
方式1邏輯圖
串行口為10位通用異步接口。發送或接收一幀數據信息為10位,包括1位起始位“0”、8位數據位、1位停止位“1”。發送數據:數據從TXD端口輸出,當數據寫入發送緩沖器SBUF時,就啟動發送器發送。發送完一幀數據后,置中斷標志TI=1,申請中斷,通知CPU可以發送下一個數據了。接收數據:首先使REN=1(允許接收數據),串行口從RXD接收數據,當采樣到1至0跳變時,確認是起始位“0”,就開始接收一幀數據,當接收完一幀數據時,置中斷標志RI=1,申請中斷,通知CPU從SBUF取走接收到的數據 。
計算波特率
方式1波特率計算
溢出速率即溢出頻率,只要算出定時器每溢出一次所需要的時間T,那溢出率就是1/T。計算在沒有波特率加倍(SMOD=0)的情況下,波特率為9600bps時怎樣賦值計數器。這里說明一下,由于波特率是需要很精確的,不然通信會出錯。如果采用定時器工作模式1,采用人工重載,會有較大誤差,因為進入中斷函數也需要時間,累積時間就會出錯。所以這里運用工作模式2,8位自動重裝。計數器自動重裝不需人工干預,減少誤差。
對照上面公式,波特率不加倍,SMOD=0,工作模式2,那n=8,波特率=9600,就可以算出x=253,十六進制為fd。
編寫步驟
設置串行口方式
設置定時器工作模式
計數器寄存器賦值
中斷寄存器控制
啟動定時器中斷
發送函數
接收函數
范例1
#include
unsigned?char?date;????//定義變量數據中斷
bit?flag;??//定義變量標志
void?send?();?//聲明發送函數
void?receive?();?//聲明接收函數
void?initialize?();????//聲明初始化函數
main()
{????????
????initialize();??//調用初始化函數
????while(1)
????{
????????send();????//調用發送函數
????????receive();?//調用接收函數
????}
}
void?initialize()??//初始化函數
{
????SCON=0X50;?????//0011?0000?串行口工作模式1
????TMOD?=?0X20;????//定時器1工作模式2,8為自動重裝
????TH1?=?0xFD;?????//設定定時初值????????波特率為9600
????TL1?=?0xFD;?????//設定定時器重裝值
????TR1?=?1;????????//啟動定時器1
????IE=0;
}
void?send()?????????//發送函數
{
????if(flag==1)????//證明已經接收數據
????{???
????????SBUF=date;????//將接收的數據發送出去
????????while(!TI);???//等待發送中斷
????????TI=0;?????????//軟件置0
????????flag=0;???????//清零
????}
}
void?receive()???????//接收函數
{
????while(!RI);???//等待接收中斷
????date=SBUF;????//將收到的數據存進接收緩沖寄存器
????RI=0;????????//軟件置0
????flag=1;??????//將標志位置1
}
范例1是將接受的數據原封不動發送出去。采用查詢法,故不需要打開串口中斷,不用中斷函數。只需不斷查詢TI,RI的值,就知道數據接收發送情況。
范例2
#include
unsigned?char?date;
bit?flag;
main?()
{
????SCON=0X50;??????//初始化
????TMOD=0X20;
????TH1=0XFD;???????????????????????????????????
????TL1=0XFD;
????IE=0X90;
????TR1=1;
????while(1);
}
void?interrupt_uart()?interrupt?4?????//中斷函數
{
????if(RI==1)????????//判斷有無數據接收
????{
????????date=SBUF;?????//將寄存器的值賦給變量
????????RI=0;??????????//置0
????????flag=1;????????//標志位置1
????}
????if(flag==1)?????????????//已接收數據
????{
????????SBUF=date;????????//將數據發出
????????while(!TI);
????????TI=0;
????????flag=0;
????}
}
與范例1如出一撤,就不詳細注釋。
總結
在串口通信中,方式1是最常用的,要認真理解方式1。串行數據一位一位的已經不用處理了,52單片機已經有一個模塊處理完了。只要知道接收一個數據,產生一次接收中斷,要軟件置0.,發送一個數據會產生一次發送中斷,也要軟件置0。自行置0,處理好數據就OK。下一篇將介紹其他三種方式,歡迎關注。
評論