日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

串行通信协议 —— UART

發布時間:2024/8/26 综合教程 35 生活家
生活随笔 收集整理的這篇文章主要介紹了 串行通信协议 —— UART 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

UART ——Universal Asynchronous Receiver/Transmitter —— 通用異步收發器

一、UART簡介

(強烈推薦一篇詳細介紹UART的博客:https://www.cnblogs.com/mylinux/p/4078576.html)

UART是異步串口通信協議,

工作原理是將傳輸數據的每個字符一位接一位地傳輸,它能將要傳輸的資料在串行通信與并行通信之間加以轉換,能夠靈活地與外部設備進行全雙工數據交換。

USART是UART的升級版,其支持同步模式,用法與UART相同

二、概念辨析

------------------------------------UART COM口 串口 USB口 RS - 232 TTL---------------------------------------------

UART,在硬件上表現為串口收發的邏輯電路,可被集成為獨立地模塊化芯片

COM口,串行通信端口,有時也稱為串口,是一種連接器的結構,這里區別于USB的“通用串行總線”和硬盤的“SATA”,串口的接口標準規范和總線標準規范是RS-232

   常見的有兩種物理標準,D型9針插頭,和4針杜邦頭,

USB口:通用串行總線,和串口完全是兩個概念。雖然也是串行方式通信,但由于USB的通信時序和信號電平都和串口完全不同,因此和串口沒有任何關系。USB是高速的通信接口,用于PC連接各種外設,U盤、鍵鼠、移動硬盤、當然也包括“USB轉串口”的模塊。(USB轉串口模塊,就是USB接口的UART模塊)

TTL,RS232,RS485等都是一種邏輯電平的表示方式,詳見:A


三、UART原理說明

  發送數據時,CPU將并行數據寫入UART,UART按照一定格式在一根電線上串行發出;接收數據時,UART檢測另一根電線上的信號,將串行收集放在緩沖區,CPU就可以讀取UART獲取這些數據。

  TxD —— 發送數據 RxD —— 接收數據   Gnd —— 用于給雙方提供參考電平

  UART使用標準的TTL / CMOS 邏輯電平來表示數據,高電平表示1,低電平為0,。為了增強數據的抗干擾能力,提高傳輸長度,通常將TTL / COMS邏輯電平轉換為RS-232邏輯電平


  數據傳輸流程:以傳輸一字節數據‘A’為例

  傳送時,數據的低位在前,高位在后

  傳送開始前,發收雙方把所采用的起止式格式(包括字符的數據位長度,停止位位數,有無校驗位以及是奇校驗還是偶校驗等)和數據傳輸速率---波特率(每一位占據的時間)作統一規定。

   規定傳輸協議 

  1)平時數據線處于“空閉”狀態(1狀態)

   2)當要發送數據時,UART改變TxD數據線的狀態,變為0狀態,并維持一位的時間,這樣接收方檢測到開始位后,再等待1.5位的時間就開始一位一位地檢測數據線的狀態得到所傳輸的數據。

  3)UART一幀中可以有5/6/7/8位的數據,發送方一位一位的改變數據線的狀態將數據發送出去,首先發送最低位

  4)如果使用校驗功能,UART在發送完數據后,還要發送一個校驗位:奇校驗,偶校驗——數據位連同校驗位中,“1”的數目屬于奇數或偶數。

  5)最后發送停止位,數據線恢復到“空閉”狀態(1狀態),停止位長度有三種:1位、1.5位、2位

圖1-1 TTL / COMS邏輯電平下,傳輸A時的波形

  

圖1-2 RS - 232邏輯電平下,傳輸數據A的波形

  對于TTL / CMOS 電平,在xV至5V之間,就認為是邏輯1,在0V至yV之間就為邏輯0。

  對于RS - 232電平,在-12V至-3V之間,就認為是邏輯1,在+3V至+12V之間就為邏輯0。

  RS-232的電平比TTL/CMOS高,能傳輸更遠的距離,在工業上用得比較多。

在ARM芯片上的串口都是TTL電平的,通過板子或外接電平轉換芯片,可以轉成RS232標準的接口。如圖2-1所示

如今終端上的RS-232標準的接口越來越少,越多的是USB口,因也可以使用USB轉串口芯片將TTL電平轉為USB傳輸電平。


四、異步串行通信的特點

所謂異步通信,是指數據傳送以字節為單位,字符與字符間的傳送是完全異步的,位與位的傳送基本是同步的。

特點:

  1)以字符為單位傳送信息

  2)相鄰兩字符間的間隔任意長

  3)由于一個字符的波特位長度有限,所以需要接受時鐘和發送時鐘相近就可以

  4)字符間異步,字符內同步


五、基本結構

圖3-1 UART結構圖

  ARM處理器中UART功能相似,都有獨立的通道,每個通道都可工作于中斷或DMA模式,即UART可以發出中斷或DMA請求以便在UART、CPU間傳輸數據。具體的UART特性可參見不同芯片的芯片手冊。以下以S3C2440芯片分析UART的使用過程。

  S3C2440 UART的FIFO深度為64字節。發送數據時,CPU先將數據寫入發送FIFO中,然后UART自動將FIFO的數據復制到“發送移位器”中,發送移位器將數據一位一位地發送到TxDn數據線上(按照設定的格式,插入開始位,校驗位和停止位)。接收數據時,“接收移位器”將RxDn數據線上的數據一位一位接收進來,然后復制到FIFO中,CPU即可從中讀取數據。UART的結構如圖3-1所示。


六、使用UART

  在UART通道0上實現最簡單的字符發送與接收功能

1、看原理圖,找到對應引腳

使用TxD0與RxD0,對應GPH2, GPH3

2、設置波特率

每個UART的波特率發生器要為發送器與接收器提供串行時鐘,對于S3C2440,其波特率發送器的時鐘源可以選擇

PCLK(外設時鐘),FCLK/n(幀時鐘),UEXTCLK,設置波特率可以通過UART波特率分頻寄存器所得,有以下公式:

  UBRDIVn = (int)( UART 時鐘源 / ( 波特率 x 16) ) –1

  PCLK = 50MHZ = 50000000,使用波特率115200,得出UBRDIVn=26

  

  

接下來看如何設置相關寄存器:

  1) UCON0 —— UART 控制寄存器

  選擇PCLK外設時鐘作為時鐘源,

  僅需設置[11:10] - 時鐘選擇,設置成0,對于[15:12]為時鐘源為FCLK情況下的設置,故不用設置。

   [9:4]位,為uart中斷相關,暫時不用設置。

  

  接收模式和接收模式都設置為中斷或查詢模式。[3:0] = 0101

  由上:UCON0 = 0x00000005; UBRDIVn=26;

3、設置其他的特殊寄存器

  1)ULCON -- UART線路控制寄存器

  

  不使用紅外模式;奇偶校驗位,暫時不設置;停止位設置為0,使用一個停止位;傳送的數據位數選擇8位;

  ULCON0 = 0x00000003;

  2)UFCON0 --- FIFO控制寄存器

    FIFO在UART傳輸大量數據的時候有很大作用,暫時先不設置,保持默認值

  3)UMCON0 --- 流量控制寄存器

    默認值

  4)UTRSTAT0 -- Tx / Rx狀態寄存器

    

    發送器空[2]=1,說明發送緩沖空間為空,且移位寄存器里的數據已經發送出去,因此可以通過判斷這

    一位,當其為1時,就可往里面寫數據。

    接收緩沖器,[0]=1, 有數據,可以讀取

  5)UFRSTAT0 -- 錯誤狀態寄存器

    假設一切正常,默認值

  6)UFSTAT0 -- FIFO狀態寄存器

    暫時沒用到FIFO,不用設置(對于2440,使用FIFO時,緩沖區可以存放64字節的數據,不使用FIFO

    只能存放1字節的數據)

  7)UMSTAT0 -- MODEM狀態寄存器

    不用設置

  8)UTXH0 與 URXH0 ---發送/接收緩沖寄存器

    發送數據,將數據寫入UTXH0即可,接收數據,從URXH0讀即可

七、示例

 1 #include "uart.h"
 2 
 3 int main(void)
 4 {
 5     unsigned char c;
 6     
 7     uart0_init();
 8     puts("Hello, world!
");
 9     
10     while(1) 
11     {
12         c = getchar();
13         if (c == '')
14         {
15             putchar('
');
16         }
17 
18         if (c == '
')
19         {
20             putchar('');
21         }
22 
23         putchar(c);
24     }
25     return 0;
26 }

main.c

 1 #define     __REG(x)                    (*(volatile unsigned int *)(x)) 
 2 #define     GPHCON                   __REG(0x56000070)  //Port H control
 3 #define     GPHUP                    __REG(0x56000078)  //Pull-up control H  
 4 #define     UCON0                    __REG(0x50000004)  //UART 0 control 
 5 #define     UBRDIV0                  __REG(0x50000028)  //UART 0 baud rate divisor 
 6 #define     ULCON0                   __REG(0x50000000)  //UART 0 line control
 7 #define     UTRSTAT0                 __REG(0x50000010)  //UART 0 Tx/Rx status      
 8 #define     UTXH0                    __REG_BYTE(0x50000020)  //UART 0 transmission hold 
 9 #define     URXH0                    __REG_BYTE(0x50000024)  //UART 0 receive
10 
11 
12 void uart0_init()
13 {
14     /* 設置引腳用于串口  */
15     /* GPH2->TxD0->[5:4]=10,GPH3->RxD0->[7:6]=10 ,即[7:4]=1010*/
16     GPHCON &= ~((3<<4) | (3<<6)); //先將第5位到第8位清零,~(110000 | 11000000) = ~1111000 = 00001111
17     GPHCON |=  ((2<<4) | (2<<6)); //(100000 | 10000000) = 10100000,由于[7:4]已經清零了。所以直接或上就可以
18 
19     GPHUP  &= ~((1<<2) | (1<<3)) ; //將2,3引腳使能內部上拉,將[2:3]=00
20     
21     /* 設置波特率  */
22     /**UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1*/
23     /*UART CLOCK設置為PCLK (50MHZ)= 50000000, UBRDIV0 = 26*/
24     UCON0 = 0x00000005;  /*PCLK,查詢/中斷*/
25     UBRDIV0 = 26;
26 
27     /* 設置數據格式  */
28     ULCON0 = 0x00000003;  /* 8n1:8個數據位,沒有校驗位,1個停止位 */
29 
30     /*  */
31 }
32 
33 int putchar(int c)
34 {
35     /* UTRSTAT0 -- 發送接收狀態寄存器*/
36     /* UTXH0 發送緩沖寄存器 */
37     while(!(UTRSTAT0 & (1<<2))) ; //UTRSTAT0的[2]不為1,說明有數據,循環等待
38     UTXH0 = (unsigned char)c;  //沒有數據,寫入數據
39     
40 }
41 
42 int getchar(void)
43 {
44     /* URXH0  接收緩沖寄存器 */
45     while(!(UTRSTAT0 & (1<<0))) ; //UTRSTAT0的[1]不為1,說明沒有數據在接收緩沖區,循環等待
46     return URXH0;  //有數據,讀出數據
47 
48 }
49 
50 int puts(const char *s)
51 {
52     while(*s)
53     {
54         putchar(*s);
55         s++;
56     }
57 }

uart.c

1 #ifndef _UART_H
2 #define _UART_H
3 
4 void uart0_init();
5 int putchar(int c);
6 int getchar(void);
7 int puts(const char *s);
8 
9 #endif 

uart.h

1 all:
2     arm-linux-gcc -c -o uart.o uart.c
3     arm-linux-gcc -c -o main.o main.c
4     arm-linux-gcc -c -o start.o start.S
5     arm-linux-ld -Ttext 0 start.o  uart.o main.o -o uart.elf
6     arm-linux-objcopy -O binary -S uart.elf uart.bin
7     arm-linux-objdump -D uart.elf > uart.dis
8 clean:
9     rm *.bin *.o *.elf *.dis

Makefile

 1 .text
 2 .global _start
 3  
 4 _start:
 5 
 6     /* 關閉看門狗 */
 7     ldr r0, =0x53000000
 8     ldr r1, =0
 9     str r1, [r0]
10 
11     /* 設置MPLL, FCLK : HCLK : PCLK = 400m : 100m : 50m */
12     /* LOCKTIME(0x4C000000) = 0xFFFFFFFF */
13     ldr r0, =0x4C000000
14     ldr r1, =0xFFFFFFFF
15     str r1, [r0]
16 
17     /* CLKDIVN(0x4C000014) = 0X5, tFCLK:tHCLK:tPCLK = 1:4:8  */
18     ldr r0, =0x4C000014
19     ldr r1, =0x5
20     str r1, [r0]
21 
22     /* 設置CPU工作于異步模式 */
23     mrc p15,0,r0,c1,c0,0
24     orr r0,r0,#0xc0000000   //R1_nF:OR:R1_iA
25     mcr p15,0,r0,c1,c0,0
26 
27     /* 設置MPLLCON(0x4C000004) = (92<<12)|(1<<4)|(1<<0) 
28      *  m = MDIV+8 = 92+8=100
29      *  p = PDIV+2 = 1+2 = 3
30      *  s = SDIV = 1
31      *  FCLK = 2*m*Fin/(p*2^s) = 2*100*12/(3*2^1)=400M
32      */
33     ldr r0, =0x4C000004
34     ldr r1, =(92<<12)|(1<<4)|(1<<0)
35     str r1, [r0]
36 
37     /* 一旦設置PLL, 就會鎖定lock time直到PLL輸出穩定
38      * 然后CPU工作于新的頻率FCLK
39      */
40     
41     
42 
43     /* 設置內存: sp 棧 */
44     /* 分辨是nor/nand啟動
45      * 寫0到0地址, 再讀出來
46      * 如果得到0, 表示0地址上的內容被修改了, 它對應ram, 這就是nand啟動
47      * 否則就是nor啟動
48      */
49     mov r1, #0
50     ldr r0, [r1] /* 讀出原來的值備份 */
51     str r1, [r1] /* 0->[0] */ 
52     ldr r2, [r1] /* r2=[0] */
53     cmp r1, r2   /* r1==r2? 如果相等表示是NAND啟動 */
54     ldr sp, =0x40000000+4096 /* 先假設是nor啟動 */
55     moveq sp, #4096  /* nand啟動 */
56     streq r0, [r1]   /* 恢復原來的值 */
57     
58 
59     bl main
60 
61 halt:
62     b halt
63     

start.s

結果:

小結:

簡要描述串行通信協議

通信協議,

  即通信雙方約定的一種協議,約定內容包括:數據格式,同步方式,傳輸速度,傳輸步驟,檢糾錯方式等。
串口通信協議:
  通常分為同步協議與異步,此處描述的是異步串口通信協議,UART。
  UART是異步,全雙工的通信協議,以字符為單位,按照順序逐位進行傳送。有兩根線,RXD接收數據、TXD發送數據;
傳送每個字符都是以起始位開始,以停止位結束,傳送時,數據的低位在前,高位在后;
在傳輸數據前,收發雙方會對傳輸協議做統一規定:數據位長度—8位、停止位位數—1位、奇校驗、傳輸速率115200bit/s
現以發送數據為例:
  TxD在空閑時和停止位時都是高電平,當想要發送數據,先發送一個起始位,即改變TxD為低電平維持一位的時間,借著就
傳輸8位數據位與1位奇校驗位與一個高電平的停止位,接受方檢測到下降沿并確認為起始位后,就開始接收數據位,
校驗位與停止位,且將停止位去掉,將數據位拼接為并行字節,經校驗無錯,就算接收一個字符完畢。發送端繼續發送數據,接收端繼續接收,直至數據傳輸完畢。

參考文檔:

嵌入式LINUX應用開發 —— 韋東山

基于STM32之UART串口通信協議(一)詳解

串口、COM口、UART口, TTL、RS-232、RS-485區別詳解

總結

以上是生活随笔為你收集整理的串行通信协议 —— UART的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。