UART通信
通信領域的數據通信方式
在通信領域,有兩種數據通信方式:并行通信,和串行通信
通信的常用術語
單工通信:只能在一個方向上進行傳送數據
半雙工通信:可以在兩個方向上進行傳送數據,但這種傳送不能同時進行
全雙工通信:可以同時在在兩個方向上進行傳送數據
并行通信和串行通信的的圖解
1、串行傳輸
優點:使用的數據線少,在遠距離通信中可以節約通信成本。
缺點:因為每次只能傳輸一位數據,所以傳輸速度比較低。
2、并行傳輸
優點:因為可以多位數據一起傳輸,所以傳輸速度很快。
缺點:數據有多少位,就要用多少數據線,所以需要大量的數據線,成本很高。使用場合
串口通信的數據傳輸速度
串口的數據傳輸是以串行方式進行的。串口在數據通信中,一次只傳輸一個比特數據,串行數據的傳輸速度用bps或者波特率來描述。
串行通信涉及的常用術語
同步方式:
** 1)所有的數據沒有其實位和停止位,一次傳送的字符個數可變。在傳送前,按照一定的格式將各種信息裝配成一包,該包包括供接收識別用的同步字符一個或兩個,其后緊跟著要傳送的n個字符,再后就是校驗字符。
2)在約定的通信速率下,發送端和接收端的時鐘頻率信號和相位始終保持一致(同步),這樣保證了通信雙方在放松和接受數據時完全一致的定時關系;
3)同步通信把許多字符組成一個信息組(幀),每幀的開始用同步字符來指示,一次通信只能傳送一幀信息,在傳輸數據的同時還需要傳輸時鐘信號,以便接收方可以同時鐘信號來確定每個信息位。
4)同步通信的優點時傳送信息的位數幾乎不受限制,一次通信傳輸的數據有幾十到幾千字節,通信效率較高。同步通信的缺點時要求通信中始終保持精確的同步時鐘,即發送時鐘和接收時鐘要嚴格的同步,常用的做法時兩個設備使用同一時鐘源。**
異步方式:也稱”起止式同步“
1)異步通信,以字符為單位進行傳輸的,字符之間沒有固定的時間間隔要求,而每個字符中的各位以固定的時間傳送。
2)在異步通信中,收發雙方取得同步是通過在字符格式中設置 起始位和停止位得方法來實現得;具體來說就是在字符正式發送之前,發送器先發送一個起始位,然后發送有效字符位,在字符結束時再發送一個停止位,起始位至停止位構成一幀。停止位和空閑位都是高電平(邏輯值為1),這樣保證了起始位開始處一定會有一個下降沿,由此可以標志一個字符傳輸的起始。而根據起始位和停止位也就很容易的實現字符的界定和同步。
3)顯然,采用異步通信時,發送端和接收端可以由各自的時鐘來控制數據的收發,這兩個時鐘源彼此獨立,可以互不干擾。
幀的概念
TCP/IP詳解1里面對幀有描述,它是一個鏈路層的PDU,PDU的意思是協議數據單元;簡單來講就是具有特定數據格式的數據包,這個數據包不單單包含數據。也可能包含一些非數據的內容,而這部分內容由不同的協議各自約定;在TCP/IP的網絡層中PDU被叫做分組,而傳輸層中PDU叫段;
簡單來講,幀就是包含數據和特定格式的數據包;
UART幀格式
(1)起始位:起始位必須是持續一個比特時間的邏輯0電平,標志傳輸一個字符的開始,接收方可用起始位使自己的接收時鐘與發送方的數據同步。
(2)數據位:數據位緊跟在起始位之后,是通信中的真正有效信息。數據位的位數可以由通信雙方共同約定,一般可以是5位、7位或8位,標準的ASCII碼是0127(7位),擴展的ASCII碼是0255(8位)。傳輸數據時先傳送字符的低位,后傳送字符的高位。
(3)奇偶校驗位:奇偶校驗位僅占一位,用于進行奇校驗或偶校驗,奇偶檢驗位不是必須有的。如果是奇校驗,需要保證傳輸的數據總共有奇數個邏輯高位;如果是偶校驗,需要保證傳輸的數據總共有偶數個邏輯高位。
舉例來說,假設傳輸的數據位為01001100,如果是奇校驗,則奇校驗位為0(要確保總共有奇數個1),如果是偶校驗,則偶校驗位為1(要確保總共有偶數個1)。
由此可見,奇偶校驗位僅是對數據進行簡單的置邏輯高位或邏輯低位,不會對數據進行實質的判斷,這樣做的好處是接收設備能夠知道一個位的狀態,有可能判斷是否有噪聲干擾了通信以及傳輸的數據是否同步。
(4)停止位:停止位可以是是1位、1.5位或2位,可以由軟件設定。它一定是邏輯1電平,標志著傳輸一個字符的結束。
(5)空閑位:空閑位是指從一個字符的停止位結束到下一個字符的起始位開始,表示線路處于空閑狀態,必須由高電平來填充。
數據發送過程
清楚了異步通信的數據格式之后,就可以按照指定的數據格式發送數據了,發送數據的具體步驟如下:
(1)初始化后或者沒有數據需要發送時,發送端輸出邏輯1,可以有任意數量的空閑位。
(2)當需要發送數據時,發送端首先輸出邏輯0,作為起始位。
(3)接著就可以開始輸出數據位了,發送端首先輸出數據的最低位D0,然后是D1,最后是數據的最高位。
(4)如果設有奇偶檢驗位,發送端輸出檢驗位。
(5)最后,發送端輸出停止位(邏輯1)。
(6)如果沒有信息需要發送,發送端輸出邏輯1(空閑位),如果有信息需要發送,則轉入步驟(2)。
數據接收過程
在異步通信中,接收端以接收時鐘和波特率因子決定每一位的時間長度。下面以波特率因子等于16(接收時鐘每16個時鐘周期使接收移位寄存器移位一次)為例來說明。
(1)開始通信,信號線為空閑(邏輯1),當檢測到由1到0的跳變時,開始對接收時鐘計數。
(2)當計到8個時鐘的時候,對輸入信號進行檢測,若仍然為低電平,則確認這是起始位,而不是干擾信號。
(3)接收端檢測到起始位后,隔16個接收時鐘對輸入信號檢測一次,把對應的值作為D0位數據。
(4)再隔16個接收時鐘,對輸入信號檢測一次,把對應的值作為D1位數據,直到全部數據位都輸入。
(5)檢驗奇偶檢驗位。
(6)接收到規定的數據位個數和校驗位之后,通信接口電路希望收到停止位(邏輯1),若此時未收到邏輯1,說明出現了錯誤,在狀態寄存器中置“幀錯誤”標志;若沒有錯誤,對全部數據位進行奇偶校驗,無校驗錯時,把數據位從移位寄存器中取出送至數據輸入寄存器,若校驗錯,在狀態寄存器中置“奇偶錯”標志。
(7)本幀信息全部接收完,把線路上出現的高電平作為空閑位。
(8)當信號再次變為低時,開始進入下一幀的檢測。
以上就是異步通信中數據發送和接收的全過程了。
總結:簡單來說,起止式同步:
(1)應該有起止位和停止位,及數據位,可以有校驗位可以沒有;
(2)起始位電平為低電平(觸發條件為檢測到下降沿,且在接收移位寄存器約定的移位時鐘周期的一半仍然是低電平);
(3)接收移位寄存器約定的移位時鐘周期取決于波特率因子兩者相等;
(4)空閑位或停止位電平為高電平;
(5)傳輸時從每個字符的低位到高位傳輸,串口通信傳輸的是字符;
(6)幀的大小在傳輸開始之前已經約定好;
(7)當一幀傳輸完成后,如果置為高電平說明后面沒有緊跟著要繼續傳輸的下一幀這個時候是空閑狀態;若是置為0,那么后面可能緊繼續傳輸的下一幀,但是也可能是
(8)起始位可以使得自己的接收時鐘和發送方的時鐘數據同步;過程大致就是,當發送方檢測出現起始位的時候,將時鐘清零,重新開始時鐘計數,而此時接收方檢測到起始位同樣將時鐘清零,然后重新開始時鐘計數從而實現時鐘同步;
(9)停止位標志著一幀數據的結束,同時位起始位提供一個出現下降沿的機會
串口驅動常用寄存器介紹
(1)引腳復用控制寄存器;因為一個引腳通常具有多種功能,當我們要使用某個引腳功能的時候使能相應位即可;引腳復用控制寄存器一般名為GPxxCON;
(2)UART線路控制寄存器;這個寄存器用來設置串口的通信協議,如模式是正常模式還是紅外模式,其中紅外模式的描述是檢測到為低電平需要檢測3/16的脈沖周期,校驗位是無校驗還是奇偶校驗,停止位長度,數據為長度;一般設置為正常模式,無校驗,停止位長度1位,數據為長度8位;UART線路控制寄存器一般名為;ULCONn
(3)波特分頻寄存器;一般名為UBRDIVn和UFRACVALn寄存器,前者和整數部分有關,后者跟小數部分有關;
參照數據手冊:UART典型的工作頻率在時鐘管理單元一般會有描述,假為設100MHZ,SCL_UART即為100;,假設波特率我們規定為115200;
DIV_VAL = (SCLK_UART/(bps x 16)) - 1;
DIV_VAL=(100/(115200X16))-1
DIV_VAL=53.25
UBRDIVn = int(DIV_VAL) = 53
UFRACVALn/16=0.25
UFRACVALn = 0.25*16 = 4
(4)UART模式控制寄存器;這個寄存器可以設置傳輸模式和發送模式,還有超時使能,中斷類型等等;一般設置只設置傳輸模式和發送模式,設置為 Interrupt request or polling mode;UART模式控制寄存器一般名為UCON
(5)硬件流控制寄存器,,一般明為UMCONn,和UMSTATn;這兩個寄存器分別控制的是nRTS,和nCTS;其中UMCONn默認是自動控制nRTS;
nRTS:用于指示本設備可以接收數據,nRTS低電平有效,說明本設備可以接收數據;
nCTS:用于判斷是否可以向對方發送數據,nCTS低電平有效,低電平可以向對方發送數據
具體情況參照芯片手冊;
(6)FIFO控制寄存器:選擇開啟或關閉FIFO模式;及其設置FIFO的觸發條件;FIFO控制寄存器一般名為:UFCONn
(7)串口傳輸狀態寄存器: UTRSTATn,作用是檢查緩沖區的狀態
(8)發送寄存器UTXH,接收寄存器URXH:作用是發送數據和接收數據
UART驅動實驗 COM2 芯片:Exynos 4412 (no FIFO)
下面部分的代碼可能有問題,沒有實驗過;
寄存器:
(1)引腳復用寄存器:GPA1CON
(2)串口線路控制寄存器:ULCON2
(3)設置波特率的寄存器:UBRDIV2和UFRACVAL2
(4)串口控制寄存器:UCON2
(5)串口傳輸狀態寄存器: UTRSTAT2
(6)發送寄存器UTXH,接收寄存器URXH
其他寄存器值沒修改,直接用默認值即可
代碼
/** 串口uart編程:* 1、在目標板上找到 串口(CON7)* 2、在原理圖中,找到cpu上的引腳 (GPA1_0 和 GPA1_1)* 3、分析原理圖, GPA1_0 復用 UART_RXD接收端, GPA1_1復用 UART_TXD發送端* 4、查看芯片手冊:* 1、配置引腳復用的功能(GPA1CON)* 2、設置串口協議: 波特率,數據位,停止位,校驗位,(數據流控位未設置)* 3、查看串口數據發送和接受的原理圖* 4、數據發送* 5、數據接受* */ #include <stdio.h>#define GPA1CON *(volatile unsigned int *)0x11400020 //volatile聲明這個變量是容易改變的,每次需要從內存中存取#define ULCON2 *(volatile unsigned int *)0x13820000 #define UCON2 *(volatile unsigned int *)0x13820004 #define UBRDIV2 *(volatile unsigned int *)0x13820028 #define UFRACVAL2 *(volatile unsigned int *)0x1382002c#define UTRSTAT2 *(volatile unsigned int *)0x13820010 #define UTxH2 *(volatile unsigned int *)0x13820020 void uart_init() {//1、設置引腳復用串口的接受和發送功能: GPA1_0 復用UART_2_RXD,GPA1_1復用UART_2_TXDGPA1CON2 = GPA1CON2 & ( ~(0xff << 0)) | (0x22 << 0);//2、設置串口的通信協議:數據位8bit、停止位1個、無校驗。ULCON2 = ULCON2 &(~(0x7f << 0)) | (0x3 << 0);//3、設置串口通信協議:波特率 115200// DIV_VAL = (SCLK_UART)/ (bps * 16) -1// = 100*10^6 / (115200 * 16) - 1// = 53.25// UBRDIV2 = int(DIV_VAL) = 53// UFRACVAL2 = 0.25*16 = 4UBRDIV2 = 53;UFRACVAL2 = 4;//4、設置串口接受數據或者發送數據的工作方式UCON2 = UCON2 & (~(0xFFFFFF << 0)) | (0x5 << 0); } void uart_sendCh(char ch) {//循環的方式判斷,發送緩沖區是否有數據,如果有數據,就意味著上條數據沒發完,因此必須循環等待while( (UTRSTAT2 & (0x1 << 1) ) == 0 );//當發送緩沖區為空時,將新的代發數據寫入 發送緩沖區寄存器UTxH2 = ch; }void delay() {int i, j;for (i = 0; i < 1000; i++){for(j = 0; j < 10000; j++);} }int main(int argc, char *argv[]) {uart_init();while(1){uart_sendCh('a');delay();}}UART驅動實驗 COM2 芯片 :Exynos 4412 ( FIFO)
UART框圖
In FIFO mode, all bytes of Buffer Register are used as FIFO register.
In non-FIFO mode, only 1 byte of Buffer Register is used as Holding register.
這句話很關鍵
寄存器:
(1)GPA1CON:引腳復用
(3)ULCONn:協議設置
(4)UCONn:設置傳輸模式
(5)UFCONn:設置FIFO模式
(6)UBRDIVn和UFRACVALn:設置波特率
(7)UFSTATn:返回FIFO的狀態
(9)發送寄存器UTXH,接收寄存器URXH
代碼
/** 串口uart編程:* 1、在目標板上找到 串口(CON7)* 2、在原理圖中,找到cpu上的引腳 (GPA1_0 和 GPA1_1)* 3、分析原理圖, GPA1_0 復用 UART_RXD接收端, GPA1_1復用 UART_TXD發送端* 4、查看芯片手冊:* 1、配置引腳復用的功能(GPA1CON)* 2、設置串口協議: 波特率,數據位,停止位,校驗位,(數據流控位未設置)* 3、查看串口數據發送和接受的原理圖* 4、數據發送* 5、數據接受* */ #include <stdio.h>#define GPA1CON *(volatile unsigned int *)0x11400020 //volatile聲明這個變量是容易改變的,每次需要從內存中存取#define ULCON2 *(volatile unsigned int *)0x13820000 #define UCON2 *(volatile unsigned int *)0x13820004 #define UFCON2 *(volatile unsigned int *)0x13820008#define UBRDIV2 *(volatile unsigned int *)0x13820028 #define UFRACVAL2 *(volatile unsigned int *)0x1382002c#define UFSTAT2 *(volatile unsigned int *)0x13820018 #define UTxH2 *(volatile unsigned int *)0x13820020 void uart_init() {//1、設置引腳復用串口的接受和發送功能: GPA1_0 復用UART_2_RXD,GPA1_1復用UART_2_TXDGPA1CON2 = GPA1CON2 & ( ~(0xff << 0)) | (0x22 << 0);//2、設置串口的通信協議:數據位8bit、停止位1個、無校驗。ULCON2 = ULCON2 &(~(0x7f << 0)) | (0x3 << 0);//3、設置串口通信協議:波特率 115200// DIV_VAL = (SCLK_UART)/ (bps * 16) -1// = 100*10^6 / (115200 * 16) - 1// = 53.25// UBRDIV2 = int(DIV_VAL) = 53// UFRACVAL2 = 0.25*16 = 4UBRDIV2 = 53;UFRACVAL2 = 4;//4.設置串口接受數據或者發送數據的工作方式UCON2 = UCON2 & (~(0xFFFFFF << 0)) | (0x85 << 0);UFCON2=UFCON&(~(0X7FF<<0))|(0x771<<0); } void uart_sendCh(char ch) {//當FIFO沒滿就裝數據進FIFOif(UFSTAT2&(0x1<<24)==0)UTxH2 = ch; }void delay() {int i, j;for (i = 0; i < 1000; i++){for(j = 0; j < 10000; j++);} }int main(int argc, char *argv[]) {uart_init();while(1){uart_sendCh('a');delay();}}總結
- 上一篇: 代理自动配置文件PAC的使用方法
- 下一篇: HTML5+CSS3快速入门每日一篇网页