NXP(I.MX6uLL) UART串口通信原理————这个未复习
參考:Linux NXP (I.MX6uLL) UART串口通信原理
作者:一只青木呀
發布時間: 2020-09-20 16:48:33
網址:https://blog.csdn.net/weixin_45309916/article/details/108694634
目錄
- 1、UART簡介
- 1.1、UART串口通訊格式
- 1.2、UART 的通信格式:
- 1.3、UART 電平標準
- 2、I.MX6U UART 簡介
- 2.1、UART的時鐘源選擇
- 3、UART 幾個重要的寄存器
- 3.1、UART 的控制寄存器 1,即UARTx_UCR1(x=1~8)
- 3.2、UART 的控制寄存器 2,即: UARTx_UCR2
- 3.3、寄存器UARTx_UCR3
- 3.4、寄存器 UARTx_USR2
- 3.5、寄 存 器 UARTx_UFCR 、 UARTx_UBIR 和 UARTx_UBMR
- UART1 的配置步驟
- 硬件原理分析
- 實驗程序編寫
- 編譯下載驗證
- 編寫Makefile 和鏈接腳本
- 編譯下載
不管是單片機開發還是嵌入式 Linux 開發,串口都是最常用到的外設。可以通過串口將開發板與電腦相連,然后在電腦上通過串口調試助手來調試程序。還有很多的模塊,比如藍牙、GPS、 GPRS 等都使用的串口來與主控進行通信的,在嵌入式 Linux 中一般使用串口作為控制臺,所以掌握串口是必備的技能。
1、UART簡介
1.1、UART串口通訊格式
串口全稱叫做串行接口,通常也叫做 COM 接口,串行接口指的是數據一個一個的順序傳輸,通信線路簡單。使用兩條線即可實現雙向通信,一條用于發送,一條用于接收。串口通信距離遠,但是速度相對會低,串口是一種很常用的工業接口。 I.MX6U 自帶的 UART 外設就是串口的一種, UART 全稱是 Universal Asynchronous Receiver/Trasmitter,也就是異步串行收發器。既然有異步串行收發器,那肯定也有同步串行收發器,學過 STM32 的同學應該知道, STM32除 了 有 UART 外 ,還有 另 外一 個 叫 做 USART 的 東 西。 USART 的全 稱 是 UniversalSynchronous/Asynchronous Receiver/Transmitter,也就是同步/異步串行收發器。 相比 UART 多了一個同步的功能,在硬件上體現出來的就是多了一條時鐘線。 一般 USART 是可以作為 UART使用的,也就是不使用其同步的功能。
UART 作為串口的一種,其工作原理也是將數據一位一位的進行傳輸,發送和接收各用一條線,因此通過 UART 接口與外界相連最少只需要三條線: TXD(發送)、RXD(接收) 和 GND(地線)。
1.2、UART 的通信格式:
上圖中的每個位的含義如下:
| 空閑位 | 數據線在空閑狀態的時候為邏輯“1”狀態,也就是高電平,表示沒有數據線空閑,沒有數據傳輸。 |
| 起始位 | 當要傳輸數據的時候先傳輸一個邏輯“0”,也就是將數據線拉低,表示開始數據傳輸。 |
| 數據位 | 數據位就是實際要傳輸的數據,數據位數可選擇 5~8 位,我們一般都是按照字節傳輸數據的,一個字節 8 位,因此數據位通常是 8 位的。低位在前,先傳輸,高位最后傳輸。 |
| 奇偶校驗位 | 這是對數據中“1”的位數進行奇偶校驗用的,可以不使用奇偶校驗功能。 |
| 停止位 | 數據傳輸完成標志位,停止位的位數可以選擇 1 位、 1.5 位或 2 位高電平,一般都選擇 1 位停止位。 |
| 波特率 | 波特率就是 UART 數據傳輸的速率,也就是每秒傳輸的數據位數,一般選擇 9600、19200、 15200(用的最多)等。 |
1.3、UART 電平標準
UART 一般的接口電平有 TTL 和 RS-232,一般開發板上都有 TXD 和 RXD 這樣的引腳,這些引腳低電平表示邏輯 0,高電平表示邏輯 1,這個就是 TTL 電平。 RS-232 采用差分線, -3~ -15V 表示邏輯 1, +3~+15V 表示邏輯 0。一般下圖中的接口就是 TTL 電平:
上圖中的模塊就是 USB 轉 TTL 模塊, TTL 接口部分有 VCC、 GND、 RXD、 TXD、RTS 和 CTS。 RTS 和 CTS 基本用不到,使用的時候通過杜邦線和其他模塊的 TTL 接口相連即可。
RS-232 電平需要 DB9 接口, I.MX6U-ALPHA 開發板上的 COM3(UART3)口就是 RS-232 接口的,如下圖所示:
由于現在的電腦都沒有 DB9 接口了,取而代之的是 USB 接口,所以就催生出了很多 USB轉串口 TTL 芯片,比如 CH340、PL2303 等 。通過這些芯片就可以實現串口 TTL 轉 USB。I.MX6UALPHA開發板就使用CH340 芯片來完成UART1 和電腦之間的連接,只需要一條USB 線即可,
2、I.MX6U UART 簡介
上面介紹了 UART 接口,下面具體看一下 I.MX6U 的 UART 接口, I.MX6U 一共有 8 個 UART,其主要特性如下:
- ①、兼容 TIA/EIA-232F 標準,速度最高可到 5Mbit/S。
- ②、支持串行 IR 接口,兼容 IrDA,最高可到 115.2Kbit/s。
- ③、支持 9 位或者多節點模式(RS-485)。
- ④、 1 或 2 位停止位。
- ⑥、可編程的奇偶校驗(奇校驗和偶校驗)。
- ⑦、自動波特率檢測(最高支持 115.2Kbit/S)
2.1、UART的時鐘源選擇
UART 的時鐘源是由寄存器 CCM_CSCDR1 的 UART_CLK_SEL(bit)位來選擇的,當為 0 的時候 UART 的時鐘源為 pll3_80m(80MHz),如果為 1 的時候 UART 的時鐘源為 osc_clk(24M),一般選擇 pll3_80m 作為 UART 的時鐘源。寄存器 CCM_CSCDR1 的 UART_CLK_PODF(bit5:0)位是 UART 的時鐘分頻值,可設置 0~ 63,分別對應 1~64 分頻,一般設置為 1 分頻,因此最終進入 UART 的時鐘為 80MHz
3、UART 幾個重要的寄存器
3.1、UART 的控制寄存器 1,即UARTx_UCR1(x=1~8)
寄存器 UARTx_UCR1 我們用到的重要位如下:
| ADBR(bit14) | 自動波特率檢測使能位,為 0 的時候關閉自動波特率檢測,為 1 的時候使能自動波特率檢測。 |
| UARTEN(bit0) | UART 使能位,為 0 的時候關閉 UART,為 1 的時候使能 UART。 |
3.2、UART 的控制寄存器 2,即: UARTx_UCR2
寄存器 UARTx_UCR2 用到的重要位如下:
| IRTS(bit14) | 為 0 的時候使用 RTS 引腳功能,為 1 的時候忽略 RTS 引腳。 |
| PREN(bit8) | 奇偶校驗使能位,為 0 的時候關閉奇偶校驗,為 1 的時候使能奇偶校驗。 |
| PROE(bit7) | 奇偶校驗模式選擇位,開啟奇偶校驗以后此位如果為 0 的話就使用偶校驗,此位為 1 的話就使能奇校驗。 |
| STOP(bit6) | 停止位數量,為 0 的話 1 位停止位,為 1 的話 2 位停止位。 |
| WS(bit5) | 數據位長度,為 0 的時候選擇 7 位數據位,為 1 的時候選擇 8 位數據位。 |
| TXEN(bit2) | 發送使能位,為 0 的時候關閉 UART 的發送功能,為 1 的時候打開 UART的發送功能。 |
| RXEN(bit1) | 接收使能位,為 0 的時候關閉 UART 的接收功能,為 1 的時候打開 UART的接收功能。 |
| SRST(bit0) | 軟件復位,為 0 的是時候軟件復位 UART,為 1 的時候表示復位完成。復位完成以后此位會自動置 1, 表示復位完成。此位只能寫 0,寫 1 會被忽略掉。 |
3.3、寄存器UARTx_UCR3
寄存器 UARTx_UCR3 用到的重要位如下:
| RXDMUXSEL(bit2) | 這個位應該始終為 1 |
3.4、寄存器 UARTx_USR2
寄存器 UARTx_USR2 用到的重要位如下:
| TXDC(bit3) | 發送完成標志位,為 1 的時候表明發送緩沖(TxFIFO)和移位寄存器為空,也就是發送完成,向 TxFIFO 寫入數據此位就會自動清零。 |
| RDR(bit0) | 數據接收標志位,為 1 的時候表明至少接收到一個數據,從寄存器UARTx_URXD 讀取數據接收到的數據以后此為會自動清零 |
3.5、寄 存 器 UARTx_UFCR 、 UARTx_UBIR 和 UARTx_UBMR
通過這三個寄存器可以設置 UART 的波特率,波特率的計算公式如下:
- Ref Freq:經過分頻以后進入 UART 的最終時鐘頻率。
- UBMR:寄存器 UARTx_UBMR 中的值。
- UBIR:寄存器 UARTx_UBIR 中的值。
通過 UARTx_UFCR 的 RFDIV 位、 UARTx_UBMR 和 UARTx_UBIR 這三者的配合即可得到我們想要的波特率。比如現在要設置 UART 波特率為 115200,那么可以設置 RFDIV 為5(0b101),也就是 1 分頻,因此 Ref Freq=80MHz。設置 UBIR=71, UBMR=3124,根據上面的公式可以得到:
最后來看一下寄存器 UARTx_URXD 和 UARTx_UTXD,這兩個寄存器分別為 UART 的接收和發送數據寄存器,這兩個寄存器的低八位為接收到的和要發送的數據。讀取寄存器UARTx_URXD 即可獲取到接收到的數據,如果要通過 UART 發送數據,直接將數據寫入到寄存器 UARTx_UTXD 即可。
寄 存 器UARTx_UFCR中我們要用到的是位 RFDIV(bit9:7),用來設置參考時鐘分頻,如下表:
| 000 | 6 分頻 |
| 001 | 5 分頻 |
| 010 | 4 分頻 |
| 011 | 3 分頻 |
| 100 | 2 分頻 |
| 101 | 1 分頻 |
| 110 | 7 分頻 |
| 111 | 保留 |
UART1 的配置步驟
關于UART 的寄存器就介紹到這里,關于這些寄存器詳細的描述,請參考《I.MX6ULL 參考手冊》第3608 頁的55.15 小節。本章我們使用I.MX6U 的UART1 來完成開發板與電腦串口調試助手之間串口通信,UART1 的配置步驟如下:
1、設置UART1 的時鐘源
設置UART 的時鐘源為pll3_80m,設置寄存器CCM_CSCDR1 的UART_CLK_SEL 位為0即可。
2、初始化UART1
初始化UART1 所使用IO,設置UART1 的寄存器UART1_UCR1~UART1_UCR3,設置內容包括波特率,奇偶校驗、停止位、數據位等等。
4、使能UART1
UART1 初始化完成以后就可以使能UART1 了,設置寄存器UART1_UCR1 的位UARTEN為1。
5、編寫UART1 數據收發函數
編寫兩個函數用于UART1 的數據收發操作。
硬件原理分析
本試驗用到的資源如下:
①、一個LED 燈:LED0。
②、串口1。
I.MX6U-ALPHA 開發板串口1 硬件原理圖如圖21.2.1 所示:
在做實驗之前需要用USB 串口線將串口1 和電腦連接起來,并且還需要設置JP5 跳線帽,將串口1 的RXD、TXD 兩個引腳分別與P116、P117 連接一起,如圖21.2.2 所示:
硬件連接設置好以后就可以開始軟件編寫了,本章實驗我們初始化好UART1,然后等待SecureCRT 給開發板發送一個字節的數據,開發板接收到SecureCRT 發送過來的數據以后在同通過串口1 發送給SecureCRT。
實驗程序編寫
本實驗對應的例程路徑為:開發板光盤-> 1、裸機例程-> 13_uart。
本章實驗在上一章例程的基礎上完成,更改工程名字為“uart”,然后在bsp 文件夾下創建名為“uart”的文件夾,然后在bsp/uart 中新建bsp_uart.c 和bsp_uart.h 這兩個文件。在bsp_uart.h中輸入如下內容:
1 #ifndef _BSP_UART_H 2 #define _BSP_UART_H 3 #include "imx6ul.h" 4 /*************************************************************** 5 Copyright ? zuozhongkai Co., Ltd. 1998-2019. All rights reserved. 6 文件名: bsp_uart.h 7 作者: 左忠凱 8 版本: V1.0 9 描述: 串口驅動文件頭文件。 10 其他: 無 11 論壇: www.openedv.com 12 日志: 初版V1.0 2019/1/15 左忠凱創建 13 ***************************************************************/ 14 15 /* 函數聲明*/ 16 void uart_init(void); 17 void uart_io_init(void); 18 void uart_disable(UART_Type *base);文件bsp_uart.h 內容很簡單,就是一些函數聲明。繼續在文件bsp_uart.c 中輸入如下所示內容:
/*************************************************************** Copyright ? zuozhongkai Co., Ltd. 1998-2019. All rights reserved. 文件名: bsp_uart.c 作者: 左忠凱 版本: V1.0 描述: 串口驅動文件。 其他: 無 論壇: www.openedv.com 日志: 初版V1.0 2019/1/15 左忠凱創建 ***************************************************************/ 1 #include "bsp_uart.h" 2 3 /* 4 * @description : 初始化串口1,波特率為115200 5 * @param : 無 6 * @return : 無 7 */ 8 void uart_init(void) 9 { 10 /* 1、初始化串口IO */ 11 uart_io_init(); 12 13 /* 2、初始化UART1 */ 14 uart_disable(UART1); /* 先關閉UART1 */ 15 uart_softreset(UART1); /* 軟件復位UART1 */ 16 17 UART1->UCR1 = 0; /* 先清除UCR1寄存器*/ 18 UART1->UCR1 &= ~(1<<14); /* 關閉自動波特率檢測*/ 19文件bsp_uart.c 中共有10 個函數,我們依次來看一下這些函數都是做什么的,第一個函數是uart_init,這個函數是UART1 初始化函數,用于初始化UART1 相關的IO、并且設置UART1的波特率、字長、停止位和校驗模式等,初始化完成以后就使能UART1。第二個函數是uart_io_init,用于初始化UART1 所使用的IO。第三個函數是uart_setbaudrate,這個函數是從
NXP 官方的SDK 包里面移植過來的,用于設置波特率。我們只需將要設置的波特率告訴此函數,此函數就會使用逐次逼近方式來計算出寄存器UART1_UFCR 的FRDIV 位、寄存器UART1_UBIR 和寄存器UART1_UBMR 這三個的值。第四和第五這兩個函數為uart_disable 和uart_enable,分別是使能和關閉UART1。第6 個函數是uart_softreset,用于軟件復位指定的UART。第七個函數是putc,用于通過UART1 發送一個字節的數據。第八個函數是puts,用于通過UART1發送一串數據。第九個函數是getc,用于通過UART1 獲取一個字節的數據,最后一個函數是raise,這是一個空函數,防止編譯器報錯。
最后在main.c 中輸入如下所示內容:
/************************************************************** Copyright ? zuozhongkai Co., Ltd. 1998-2019. All rights reserved. 文件名: main.c第5 行調用函數uart_init 初始化UART1,最終在while 循環里面獲取串口接收到的數據,并且將獲取到的數據通過串口打印出來。
編譯下載驗證
編寫Makefile 和鏈接腳本
在Makefile 文件中輸入如下內容:
1 CROSS_COMPILE ?= arm-linux-gnueabihf- 2 TARGET ?= uart 3 4 CC := $(CROSS_COMPILE)gcc 5 LD := $(CROSS_COMPILE)ld 6 OBJCOPY := $(CROSS_COMPILE)objcopy 7 OBJDUMP := $(CROSS_COMPILE)objdump 8 9 LIBPATH := -lgcc -L /usr/local/arm/gcc-linaro-4.9.4-2017.01- x86_64_arm-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/4.9.4 10 11 12 INCDIRS := imx6ul \ 13 bsp/clk \ 14 bsp/led \ 15 bsp/delay \ 16 bsp/beep \ 17 bsp/gpio \ 18 bsp/key \ 19 bsp/exit \ 20 bsp/int \ 21 bsp/epittimer \ 22 bsp/keyfilter \ 23 bsp/uart 24 25 SRCDIRS := project \ 26 bsp/clk \上述的Makefile 文件內容和上一章實驗的區別不大。將TARGET 為uart,在INCDIRS 和SRCDIRS 中加入“bsp/uart”。但是,相比上一章中的Makefile 文件,本章實驗的Makefile 有兩處重要的改變:
①、本章Makefile 文件在鏈接的時候加入了數學庫,因為在bsp_uart.c 中有個函數uart_setbaudrate,在此函數中使用到了除法運算,因此在鏈接的時候需要將編譯器的數學庫也鏈接進來。第9 行的變量LIBPATH 就是數學庫的目錄,在第56 行鏈接的時候使用了變量LIBPATH。
在后面的學習中,我們常常要用到一些第三方庫,那么在連接程序的時候就需要指定這些第三方庫所在的目錄,Makefile 在鏈接的時候使用選項“-L”來指定庫所在的目錄,比如“示例代碼21.4.1”中第9 行的變量LIBPATH 就是指定了我們所使用的編譯器庫所在的目錄。
②、在第61 行和64 行中,加入了選項“-fno-builtin”,否則編譯的時候提示“putc”、“puts”這兩個函數與內建函數沖突,錯誤信息如下所示:
warning: conflicting types for built-in function ‘putc’ warning: conflicting types for built-in function ‘puts’在編譯的時候加入選項“-fno-builtin”表示不使用內建函數,這樣我們就可以自己實現putc和puts 這樣的函數了。
鏈接腳本保持不變。
編譯下載
使用Make 命令編譯代碼,編譯成功以后使用軟件imxdownload 將編譯完成的uart.bin 文件下載到SD 卡中,命令如下:
chmod 777 imxdownload //給予imxdownload 可執行權限,一次即可 ./imxdownload uart.bin /dev/sdd //燒寫到SD 卡中,不能燒寫到/dev/sda 或sda1 設備里面!燒寫成功以后將SD 卡插到開發板的SD 卡槽中,然后復位開發板。打開SourceCRT,點擊File->Quick Connect…,打開快速連接設置界面,設置好相應的串口參數,比如在我的電腦上是COM8,設置如圖21.4.2.1 所示:
設置好以后就點擊“Connect”就可以了,連接成功以后SecureCRT 收到來自開發板的數據,但是SecureCRT 顯示可能會是亂碼,如圖21.4.2.2 所示:
這是因為有些設置還沒做,點擊Options->Session Options…,打開會話設置窗口,按照圖21.4.2.3 所示設置:
設置好以后點擊“OK”按鈕就可以了,清屏,然后重新復位一次開發板,此時SecureCRT顯示就正常了,如圖21.4.2.4 所示:
根據提示輸入一個字符,這個輸入的字符就會通過串口發送給開發板,開發板接收到字符以后就會通過串口提示你接收到的字符是什么,如圖21.4.2.5 所示:
至此,I.MX6U 的串口1 就工作起來了,以后我們就可以通過串口來調試程序。但是本章只實現了串口最基本的收發功能,如果我們要想使用格式化輸出話就不行了,比如最常用的printf 函數,下一章就講解如何移植printf 函數。
總結
以上是生活随笔為你收集整理的NXP(I.MX6uLL) UART串口通信原理————这个未复习的全部內容,希望文章能夠幫你解決所遇到的問題。