天天看點

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

目錄

  • 硬知識
    • USCI通信子產品
    • USCI的UART模式
      • 1. USCI初始化和複位
      • 2. 異步通信字元格式
      • 3. 異步多機通信模式
      • 4. 自動波特率檢測
      • 5. IrDA編碼和解碼
      • 6. 自動錯誤檢測
      • 7. USCI接收使能
      • 8. USCI發送使能
      • 9. UART波特率的産生
      • 10. UART波特率的設定(重要)
        • (1)低頻波特率設定
        • (2)過采樣波特率設定
  • UART API(機翻)
    • USCI_A_UART的配置和控制函數:
      • 參數
    • 用于發送和接收資料的函數
      • 參數
    • 管理USCI_A_UART中斷和狀态的函數
      • 參數
    • DMA相關
      • 參數
  • 通過DriverLib庫和硬體知識編寫UART初始化函數
  • 原理圖的序列槽部分
  • 上機實戰

平台:Code Composer Studio 10.3.1

MSP430F5529 LaunchPad™ Development Kit

(MSP‑EXP430F5529LP)

硬知識

USCI通信子產品

       通用串行通信接口(USCI)子產品支援多種串行通信模式,不同的USCI子產品支援不同的通信模式。每個不同的USCI子產品以不同的字母命名,如USCI_A、USCI_B等。如果在一個MSP430單片機上實作了不止一個相同的USCI子產品,那麼這些子產品将以遞增的數字命名。例如,當一個MSP430單片機支援兩個USCI_A子產品時,這兩個子產品應該被命名為USCI_A0和USCI_A1。具體可查閱相關晶片的資料手冊,來确定該晶片具有哪些USCI通信子產品。

       USCI_Ax子產品支援以下模式:

 UART通信模式;

 具有脈沖整形的IrDA通信模式;

 具有自動波特率檢測的LIN通信模式;

 SPI通信模式。

       USCI_Bx子產品支援以下通信模式:

 I2C通信模式;

 SPI通信模式。

USCI的UART模式

       異步串行通信(UART)的特點如下:

 傳輸7位或8位資料,可采用奇校驗、偶校驗或者無校驗;

 具有獨立的發送和接收移位寄存器;

 具有獨立的發送和接收緩沖寄存器;

 支援最低位優先或最高位優先的資料發送和接收方式;

 内置多處理器系統,包括線路空閑和位址位通信協定;

 通過有效的起始位檢測将MSP430單片機從低功耗模式下喚醒;

 可程式設計實作分頻因子為整數或小數的波特率;

 具有用于檢測錯誤或排除錯誤的狀态标志位;

 具有用于位址檢測的狀态标志位;

 具有獨立的發送和接收中斷能力。

在UART模式下,USCI_Ax的結構如圖所示。

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

1. USCI初始化和複位

       通過産生一個PUC複位信号或者置位UCSWRST控制位可以使USCI子產品複位。在産生一個PUC複位信号之後,系統可自動置位UCSWRST控制位,保持USCI子產品在複位狀态。若UCSWRST控制位置位,将重置UCRXIE、UCTXIE、UCRXIFG、UCRXERR、UCBRK、UCPE、UCOE、UCFE、UCSTOE和UCBTOE寄存器,并置位UCTXIFG中斷标志位。清除UCSWRST控制位,USCI子產品才可進行工作。

是以,可按照以下步驟進行初始化或重新配置USCI子產品:

① 置位UCSWRST控制位;

② 在UCSWRST=1時,初始化所有的USCI寄存器(包括UCTxCTL1);

③ 将相應的引腳端口配置為UART通信功能;

④ 軟體清除UCSWRST控制位;

⑤ 通過設定接收或發送中斷使能控制寄存器UCRXIE和UCTXIE或兩者之一,使能中斷。

2. 異步通信字元格式

       如圖所示,異步通信字元格式由5個部分組成:一個起始位、7位或8位資料位、一個奇/偶/無校驗位、一個位址位和一個或兩個停止位。其中,使用者可以通過軟體設定資料位、停止位的位數,還可以設定奇偶校驗位的有無。通過選擇時鐘源和波特率寄存器的資料來确定傳輸速率。UCMSB控制位用來設定傳輸的方向和選擇最低位還是最高位先發送。一般情況下,對于UART通信選擇先發送最低位。

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

3. 異步多機通信模式

       當兩個裝置異步通信時,不需要多機通信協定。當3個或更多的裝置通信時,USCI支援兩種多機通信模式,即線路空閑和位址位多機模式。資訊以一個多幀資料塊,從一個指定的源傳送到一個或多個目的位置。在同一個串行鍊路上,多個處理機之間可以用這些格式來交換資訊,實作在多處理機通信系統間的有效資料傳輸。控制寄存器的UCMODEx控制位可用來确定這兩種模式,這兩種模式具有喚醒發送、位址特征和激活等功能。在兩種多處理機模式下,USCI資料交換過程可以用資料查詢方式,也可以用中斷方式來實作。

(1)線路空閑多機模式

       當UCMODEx控制位被配置為01時,USCI就選擇了線路空閑多機模式,如圖7.1.3所示。在這種模式下,發送和接收資料線上的資料塊被空閑時間分割。圖(a)為資料塊傳輸的總體示意,圖(b)為每個資料塊中字元的傳輸示意。在圖(a)中,在字元的一個或兩個停止位之後,若收到10個以上的1,則表示檢測到接收線路空閑。在識别到線路空閑後,波特率發生器就會被關斷,直到檢測到下一個起始位才會重新被啟動。當檢測到空閑線路後,将置位UCIDLE标志位。在圖(b)中,每兩個資料塊之間的線路空閑時間應少于10個空閑周期,這樣資料才能正确、正常地傳輸。

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

(2)位址位多機模式

       當UCMODEx控制位被配置為10時,USCI就選擇了位址位多機模式。在這種模式下,字元包含一個附加的位作為位址标志。位址位多機模式的格式如圖所示。資料塊的第1個字元帶有一個置位的位址位,用以表明該字元是一個位址。當接收到的字元位址位置位且被傳送到UCAxRXBUF接收緩沖寄存器中,USCI子產品将置位UCADDR标志位。

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

4. 自動波特率檢測

       當UCMODEx控制位被配置為11時,就選擇了帶自動波特率選擇的UART模式。對于UART自動波特率檢測方式,在資料幀前面會有一個包含打斷和同步域的同步序列。當在總線上檢測到11個或更多個0時,被識别為總線打斷。如果總線打斷的長度超過21位時間長度,則将置位打斷逾時錯誤标志UCBTOE。當接收打斷或同步域時,USCI不能發送資料。同步域在打斷域之後,示意圖如左圖所示。

       在1個位元組裡,同步域包含資料055h,如右圖所示。同步是基于這種模式的第一個下降沿和最後一個下降沿之間的時間測量,如果通過置位UCABDEN控制位,将使能自動波特率檢測功能,則發送波特率發生器通常用于時間的測量。否則,在該模式下隻接收并不測量。測量的結果将被移送到波特率控制寄存器(UCAxBR0、UCAxBR1和UCAxMCTL)中。如果同步域的長度超過了可測量的時間,将置位同步逾時錯誤标志位UCSTOE。

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

5. IrDA編碼和解碼

       當置位UCIREN控制位時,将會使能IrDA編碼器和解碼器,并對IrDA通信提供硬體編碼和解碼。

(1)IrDA編碼

       IrDA編碼器會在UART資料流的基礎上,對UART傳輸中遇到的每一位0發送一個脈沖進行編碼,編碼方式如圖所示,脈沖的持續時間由UCIRTXPLx進行定義。

(2)IrDA解碼

       當UCIRRXPL=0時,解碼器檢測到高電平,否則檢測低電平。除了模拟抗尖峰脈沖濾波器,USCI内部還包含可程式設計數字濾波器,使用者可通過置位UCIRRXFE控制位使能該内部可程式設計數字濾波器。當UCIRRXFE置位時,隻有超過程式設計過濾長度的脈沖可以通過,短脈沖被丢棄。過濾器長度UCIRRXFLx的程式設計計算公式如下

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰
MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

6. 自動錯誤檢測

       USCI子產品接收字元時,能夠自動進行校驗錯誤、幀錯誤、溢出錯誤和打斷狀态檢測。當檢測到它們各自的狀态時,會置位相應的中斷标志位UCFE、UCPE、UCOE和UCBRK。當這些錯誤标志位置位時,UCRXERR也會被置位。各種錯誤的含義和标志如表所示。

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

7. USCI接收使能

       通過清除UCSWRST控制位可以使能USCI子產品,此時,接收端準備接收資料并處于空閑狀态,接收波特率發生器處于準備狀态,但并沒有産生時鐘。

       起始位的下降沿可以使能波特率發生器。UART狀态機可檢測有效起始位,如果未檢測到有效起始位,則UART狀态機傳回空閑狀态同時停止波特率發生器;如果檢測到有效起始位,則字元将會被接收。

       當選擇線路空閑多機模式時(UCMODEx=01),在接收完一個字元之後,UART狀态機檢測空閑線路。若檢測到一個起始位,則接收下一個字元。否則,如果線上路上檢測到10個1,就會置位UCIDLE空閑标志位,并且UART狀态機傳回空閑狀态同時波特率發生器被禁止。

       抑制接收資料脈沖幹擾能夠防止USCI子產品意外啟動,任何在UCAxRXD的時間少于抗尖峰脈沖時間tt(近似150ns)的短時脈沖都将被USCI忽略,緊接着進行初始化,如左圖所示,若在UCAxRXD上的短時脈沖時間少于tt,USCI并沒有開始接收資料。

       當一個尖峰脈沖時間長于tt,或者在UCAxRXD上發生一個有效的起始位,USCI開始接收工作并采用多數表決方式,如右圖所示。如果多數表決沒有檢測到起始位,則USCI停止接收字元。

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

8. USCI發送使能

       通過清除UCSWRST控制位可以使能USCI子產品,此時,發送端準備發送資料并處于空閑狀态,發送波特率發生器處于準備狀态,但是,并沒有産生時鐘。

       通過寫資料到發送緩沖寄存器中,USCI就可以開始發送資料。波特率發生器開始工作,當發送移位寄存器為空時,在下一個BITCLK上,發送緩沖寄存器中的資料将被移送到發送移位寄存器中。

       在前一位元組發送完成之後,隻要發送緩沖寄存器UCAxTXBUF中有新資料,發送即可繼續。若前一位元組發送完成之後,發送緩沖寄存器UCAxTXBUF中并沒有寫入新的資料,發送端将傳回空閑狀态,同時停止波特率發生器。

9. UART波特率的産生

       USCI波特率發生器可以從非标準的時鐘源頻率中産生标準的波特率,可以通過UCOS16控制位選擇系統提供的兩種操作模式,分别為:産生低頻波特率模式(UCOS16=0)和産生過采樣波特率模式(UCOS16=1)。UART波特率的參考時鐘來自于BRCLK,BRCLK可以通過UCSSELx控制位配置為外部時鐘UCAxCLK或内部時鐘ACLK或SMCLK。

(1)産生低頻波特率模式

       當UCOS16=0時,選擇低頻波特率模式。該模式允許從低頻時鐘源産生标準的波特率(例如,從32768Hz晶振産生9600bps的波特率)。通過使用較低的輸入頻率,可以降低系統的功耗。注意:在高頻輸入或高分頻設定下,使用這種模式,将導緻在更小的視窗中采用多數表決方式,是以會降低多數表決法的優勢。

       在低頻模式下,波特率發生器使用1個預分頻器和1個調制器産生時鐘時序。在這種組合下,産生的波特率支援小數分頻。在這種模式下,最大的USCI波特率是UART源時鐘頻率BRCLK的1/3。

       每一位的時序如圖所示。對于接收的每一位,為了确定該位的值,采用多數表決法,即3取2表決法。每次表決時采樣3次,最終該位的值至少在采樣中出現兩次。這些采樣發生在(N/2-1/2),N/2和(N/2+1/2)個BRCLK周期處,如圖中的方框所示,這裡的N是每個BITCLK包含的BRCLKs的數值,圖中的m為調制設定,具體請參見下表。

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰
MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

(2)産生過采樣波特率模式

       當UCOS16=1時,選擇過采樣模式。該模式支援在較高的輸入參考時鐘頻率下,産生較高的UART波特率。該模式的參考時鐘為經預分頻器和調制器産生的BITCLK16時鐘,該時鐘頻率為BITCLK的1/16。是以,在計算分頻系數時,需将波特率發生器的參考時鐘頻率除以16之後,再進行計算。例如,若波特率發生器的參考時鐘BITCLK選擇内部的SMCLK=1048576Hz,最終需要産生9600bps的波特率,首先将BITCLK除以16為65536Hz作為該模式下的波特率參考時鐘,計算分頻系數為n=65536/9600=6.83。

       這種組合方式支援BITCLK16和BITCLK産生不是整數倍的波特率,在這種情況下,最大的USCI波特率是UART源時鐘頻率的1/16。當UCBRx設定為0或1時,将忽略第一級分頻器和調制器,BITCLK16等于BITCLK,在這種情況下,BITCLK16沒有調制,是以将忽略UCBRFx位。

       BITCLK16的調制是建立在如下表所示的UCBRFx設定的基礎之上的。表中的0和1表示m的值,m=1時所對應的BITCLK的周期比m=0時所對應的BITCLK的周期要長,具體原理請參考産生低頻波特率模式下的調制原理。

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

10. UART波特率的設定(重要)

       設定方法:設定波特率時,首先要選擇合适的時鐘源。對于較低的波特率(9600bps以下),可以選擇ACLK作為時鐘源,這使得在LPM3模式下仍然能夠使用序列槽。由于序列槽接收過程中有一個三取二表決邏輯,這需要至少3個時鐘周期,是以要求分頻系數必須大于3。是以,在波特率高于9600bps的情況下,應選擇頻率較高的SMCLK作為時鐘源。在某些特殊應用中,也可以使用外部的時鐘輸入作為波特率發生器的時鐘源。

對于給定的BRCLK時鐘源,所使用的波特率将決定分頻因子N,計算公式為

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

分頻因子N通常不是一個整數值 ,是以至少需要一個分頻器和一個調制器來盡可能接近分頻因子。如果N等于或大于16,可以通過置位UCOS16選擇過采樣波特率産生模式。

(1)低頻波特率設定

在低頻模式下,分頻因子的整數部分通過預分頻器實作,配置方式為(其中INT為取整)

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

小數部分由調制器實作,配置方式為(round為取附近整數)

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

【例1】 在MSP430單片機中,使用ACLK作為序列槽時鐘源,波特率設為4800bps。

       分析:在ACLK=32768Hz時産生4800bps波特率,需要的分頻系數是32768/4800=6.83。整數部分為6,小數部分為0.83。将整數部分賦給UCA0BR寄存器,調制器分頻餘數為0.83 × 8 = 6.64,取最接近的整數7,是以将7賦給UCBRS控制位。

(2)過采樣波特率設定

在過采樣模式下,預分頻設定為:

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

調制器設定為:

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

【例2】 在MSP430單片機中,使用SMCLK作為序列槽時鐘源,波特率設定為9600bps。

       分析:在SMCLK=1048576Hz時産生9600bps波特率,需要的分頻系數N=1048576/ 9600=109.23,大于16分頻,是以應選擇過采樣波特率産生模式,預分頻UCBR應設定為INT(N/16)=INT(6.83)=6。調制器UCBRF應設定為0.83 × 16 = 13.28,取最接近的整數13,是以将13賦給UCBRF控制位。

波特率設定也可直接參考下表

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰
MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

也可以從MSP430 USCI/EUSCI UART Baud Rate Calculation中擷取

UART API(機翻)

USCI_A_UART API被分為幾組功能:

USCI_A_UART子產品的配置和控制的函數,

用于發送和接收資料的函數,

以及進行中斷處理和處理DMA的函數。

USCI_A_UART的配置和控制函數:

USCI_A_UART_init(uint16_t baseAddress, USCI_A_UART_initParam ∗param)
//初始化函數
USCI_A_UART_enable(uint16_t baseAddress)
//使能UART子產品
USCI_A_UART_disable(uint16_t baseAddress)
//失能UART子產品
USCI_A_UART_setDormant(uint16_t baseAddress)
//将UART子產品設定為休眠模式
USCI_A_UART_resetDormant(uint16_t baseAddress)
//從休眠模式重新啟用UART子產品
           

參數

baseAddress

是USCI_A_UART子產品的基位址

USCI_A0_BASE
USCI_A1_BASE
           

USCI_A_UART_initParam 結構體

typedef struct USCI_A_UART_initParam {
    //! Selects Clock source.
    //! \n Valid values are:
    //! - \b USCI_A_UART_CLOCKSOURCE_SMCLK
    //! - \b USCI_A_UART_CLOCKSOURCE_ACLK
    uint8_t selectClockSource;
    //! Is the value to be written into UCBRx bits
    uint16_t clockPrescalar;
    //! Is First modulation stage register setting. This value is a pre-
    //! calculated value which can be obtained from the Device Users Guide.
    //! This value is written into UCBRFx bits of UCAxMCTLW.
    uint8_t firstModReg;
    //! Is Second modulation stage register setting. This value is a pre-
    //! calculated value which can be obtained from the Device Users Guide.
    //! This value is written into UCBRSx bits of UCAxMCTLW.
    uint8_t secondModReg;
    //! Is the desired parity.
    //! \n Valid values are:
    //! - \b USCI_A_UART_NO_PARITY [Default]
    //! - \b USCI_A_UART_ODD_PARITY
    //! - \b USCI_A_UART_EVEN_PARITY
    uint8_t parity;
    //! Controls direction of receive and transmit shift register.
    //! \n Valid values are:
    //! - \b USCI_A_UART_MSB_FIRST
    //! - \b USCI_A_UART_LSB_FIRST [Default]
    uint8_t msborLsbFirst;
    //! Indicates one/two STOP bits
    //! \n Valid values are:
    //! - \b USCI_A_UART_ONE_STOP_BIT [Default]
    //! - \b USCI_A_UART_TWO_STOP_BITS
    uint8_t numberofStopBits;
    //! Selects the mode of operation
    //! \n Valid values are:
    //! - \b USCI_A_UART_MODE [Default]
    //! - \b USCI_A_UART_IDLE_LINE_MULTI_PROCESSOR_MODE
    //! - \b USCI_A_UART_ADDRESS_BIT_MULTI_PROCESSOR_MODE
    //! - \b USCI_A_UART_AUTOMATIC_BAUDRATE_DETECTION_MODE
    uint8_t uartMode;
    //! Indicates low frequency or oversampling baud generation
    //! \n Valid values are:
    //! - \b USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION
    //! - \b USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION
    uint8_t overSampling;
} USCI_A_UART_initParam;
           

其中的clockPrescalar,firstModReg,secondModReg,overSampling

可在MSP430 USCI/EUSCI UART Baud Rate Calculation中擷取

用于發送和接收資料的函數

USCI_A_UART_transmitData(uint16_t baseAddress, uint8_t transmitData)		
//通過UART子產品傳輸一個位元組
USCI_A_UART_receiveData(uint16_t baseAddress)								
//接收一個已發送到UART子產品的位元組。
USCI_A_UART_transmitAddress(uint16_t baseAddress, uint8_t transmitAddress)	
//Transmits the next byte to be transmitted marked as address depending on selected multiprocessor mode
USCI_A_UART_transmitBreak(uint16_t baseAddress)
//傳輸中斷
           

參數

baseAddress

是USCI_A_UART子產品的基位址

USCI_A0_BASE
USCI_A1_BASE
           

transmitData

UART子產品要傳輸的資料

transmitAddress

is the next byte to be transmitted

管理USCI_A_UART中斷和狀态的函數

USCI_A_UART_enableInterrupt(uint16_t baseAddress, uint8_t mask)
//啟用UART中斷
USCI_A_UART_disableInterrupt(uint16_t baseAddress, uint8_t mask)
//失能UART中斷
USCI_A_UART_getInterruptStatus(uint16_t baseAddress, uint8_t mask)
//擷取目前UART中斷狀态。這将根據傳遞的标志傳回UART子產品的中斷狀态
USCI_A_UART_clearInterrupt(uint16_t baseAddress, uint8_t mask)
//清除UART中斷源,使其不再斷言。當使用中斷向量生成器時,最高中斷标志将自動清除
USCI_A_UART_queryStatusFlags(uint16_t baseAddress, uint8_t mask)
//擷取目前UART狀态标志。這将根據傳遞的标志傳回UART子產品的狀态。
           

參數

baseAddress

是USCI_A_UART子產品的基位址

USCI_A0_BASE
USCI_A1_BASE
           

mask

USCI_A_UART_enableInterrupt、

USCI_A_UART_disableInterrupt:

/*
is the bit mask of the interrupt sources to be enabled. Mask value is the logical
OR of any of the following:
*/
USCI_A_UART_RECEIVE_INTERRUPT	// - Receive interrupt
USCI_A_UART_TRANSMIT_INTERRUPT	// - Transmit interrupt
USCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT	// - Receive erroneous-character interrupt enable
USCI_A_UART_BREAKCHAR_INTERRUPT	// - Receive break character interrupt enable
           

USCI_A_UART_getInterruptStatus、

USCI_A_UART_clearInterrupt:

/*
is the masked interrupt flag status to be returned. Mask value is the logical OR
of any of the following:
*/
USCI_A_UART_RECEIVE_INTERRUPT_FLAG	// - Receive interrupt flag
USCI_A_UART_TRANSMIT_INTERRUPT_FLAG	// - Transmit interrupt flag
           

USCI_A_UART_queryStatusFlags:

/*
is the masked interrupt flag status to be returned. Mask value is the logical OR
of any of the following:
*/
USCI_A_UART_LISTEN_ENABLE
USCI_A_UART_FRAMING_ERROR
USCI_A_UART_OVERRUN_ERROR
USCI_A_UART_PARITY_ERROR
USCI_A_UART_BREAK_DETECT
USCI_A_UART_RECEIVE_ERROR
USCI_A_UART_ADDRESS_RECEIVED
USCI_A_UART_IDLELINE
USCI_A_UART_BUSY
           

DMA相關

USCI_A_UART_getReceiveBufferAddressForDMA(uint16_t baseAddress)
//傳回UART DMA子產品的RX緩沖區位址
USCI_A_UART_getTransmitBufferAddressForDMA(uint16_t baseAddress)
//傳回UART DMA子產品的TX緩沖區位址
           

參數

baseAddress

是USCI_A_UART子產品的基位址

USCI_A0_BASE
USCI_A1_BASE
           

通過DriverLib庫和硬體知識編寫UART初始化函數

根據之前的知識,我們可以寫出如下初始化函數

baseAddress的參數可選為

USCI_A0_BASE、USCI_A1_BASE,

分别對應P3.3、P3.4和P4.4、P4.5

Baudrate為目标波特率

bool UART_Init(uint16_t baseAddress, uint32_t Baudrate)
{
    float UART_Temp = 0;
    USCI_A_UART_initParam huart = {0};
	//将所用引腳複用為UART模式
    if(baseAddress == USCI_A0_BASE)         //P3.3, P3.4 = USCI_A0 TXD/RXD
    {
        GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3, GPIO_PIN3);
        GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN4);
    }
    else if(baseAddress == USCI_A1_BASE)    //P4.4, P4.5 = USCI_A1 TXD/RXD
    {
        GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P4, GPIO_PIN4);
        GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN5);
    }
	//當目标波特率較低時,UART選用時鐘源為ACLK,反之選擇SMCLK
	//調用UCS_getACLK/UCS_getSMCLK前需正确調用UCS_setExternalClockSource函數,我已加到SystemClock_Init函數中
    if(Baudrate <= 9600)
    {
        huart.selectClockSource = USCI_A_UART_CLOCKSOURCE_ACLK;
        UART_Temp = (float)UCS_getACLK()/Baudrate;
    }
    else
    {
        huart.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;
        UART_Temp = (float)UCS_getSMCLK()/Baudrate;
    }
	
    if(UART_Temp < 16)	//當分頻因子小于16時,采用低頻波特率設定
        huart.overSampling = USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;
    else	//反之,采用過采樣波特率設定
    {
        huart.overSampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;
        UART_Temp /= 16;
    }

    huart.clockPrescalar = (int)UART_Temp;

    if(huart.overSampling == USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION)
    {	//低頻波特率設定	UCBRSx
        huart.secondModReg = (int)((UART_Temp - huart.clockPrescalar) * 8);
    }
    else
    {	//過采樣波特率設定 UCBRFx
        huart.firstModReg = (int)((UART_Temp - huart.clockPrescalar) * 16);
    }

    huart.parity = USCI_A_UART_NO_PARITY;
    huart.msborLsbFirst = USCI_A_UART_LSB_FIRST;
    huart.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;
    huart.uartMode = USCI_A_UART_MODE;

    if (STATUS_FAIL == USCI_A_UART_init(baseAddress, &huart))
    {	//初始化對應序列槽
        return STATUS_FAIL;
    }

    //Enable UART module for operation 使能對應序列槽
    USCI_A_UART_enable(baseAddress);	

    //Enable Receive Interrupt 啟用序列槽中斷
    USCI_A_UART_clearInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);	
    USCI_A_UART_enableInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);	

    return STATUS_SUCCESS;
}
           

序列槽中斷服務函數 接收一個字元就回發一個

//******************************************************************************
//
//This is the USCI_A0 interrupt vector service routine.
//
//******************************************************************************
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR (void)
{
    uint8_t receivedData = 0;
    switch (__even_in_range(UCA0IV,4))
    {
        //Vector 2 - RXIFG
        case 2:
            receivedData = USCI_A_UART_receiveData(USCI_A0_BASE);
            USCI_A_UART_transmitData(USCI_A0_BASE,receivedData);
            break;
        default:
            break;
    }
}

//******************************************************************************
//
//This is the USCI_A1 interrupt vector service routine.
//
//******************************************************************************
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR (void)
{
    uint8_t receivedData = 0;
    switch (__even_in_range(UCA1IV,4))
    {
        //Vector 2 - RXIFG
        case 2:
            receivedData = USCI_A_UART_receiveData(USCI_A1_BASE);
            USCI_A_UART_transmitData(USCI_A1_BASE,receivedData);
            break;
        default:
            break;
    }
}
           

原理圖的序列槽部分

USCI_A0 UART對應P3.3、P3.4

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

USCI_A1 UART對應P4.4、P4.5

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰
MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰
MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

如圖所示,MSP430F5529的USCI_A1 UART 通過 eZ-FET 與USB通訊

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

換句話說,插上microUSB後識别到的序列槽應為USCI_A1 UART

上機實戰

整個源檔案如下

#include "driverlib.h"

#define MCLK_IN_HZ      25000000

#define delay_us(x)     __delay_cycles((MCLK_IN_HZ/1000000*(x)))
#define delay_ms(x)     __delay_cycles((MCLK_IN_HZ/1000*(x)))

void SystemClock_Init(void)
{
    PMM_setVCore(PMM_CORE_LEVEL_3);     //高主頻工作需要較高的核心電壓

    //XT1引腳複用
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4);
    GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN5);

    //起振XT1
    UCS_turnOnLFXT1(UCS_XT1_DRIVE_3,UCS_XCAP_3);

    //XT2引腳複用
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN2);
    GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN3);

    //起振XT2
    UCS_turnOnXT2(UCS_XT2_DRIVE_4MHZ_8MHZ);

    //XT2作為FLL參考時鐘,先8分頻,再50倍頻 4MHz / 8 * 50 = 25MHz
    UCS_initClockSignal(UCS_FLLREF, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_8);
    UCS_initFLLSettle(25000, 50);

    //XT1作為ACLK時鐘源 = 32768Hz
    UCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);

    //DCOCLK作為MCLK時鐘源 = 25MHz
    UCS_initClockSignal(UCS_MCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);

    //DCOCLK作為SMCLK時鐘源 = 25MHz
    UCS_initClockSignal(UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);

    //設定外部時鐘源的頻率,使得在調用UCS_getMCLK, UCS_getSMCLK 或 UCS_getACLK時可得到正确值
    UCS_setExternalClockSource(32768, 4000000);
}

bool UART_Init(uint16_t baseAddress, uint32_t Baudrate)
{
    float UART_Temp = 0;
    USCI_A_UART_initParam huart = {0};

    if(baseAddress == USCI_A0_BASE)         //P3.3, P3.4 = USCI_A0 TXD/RXD
    {
        GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3, GPIO_PIN3);
        GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN4);
    }
    else if(baseAddress == USCI_A1_BASE)    //P4.4, P4.5 = USCI_A1 TXD/RXD
    {
        GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P4, GPIO_PIN4);
        GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN5);
    }

    if(Baudrate <= 9600)
    {
        huart.selectClockSource = USCI_A_UART_CLOCKSOURCE_ACLK;
        UART_Temp = (float)UCS_getACLK()/Baudrate;
    }
    else
    {
        huart.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;
        UART_Temp = (float)UCS_getSMCLK()/Baudrate;
    }

    if(UART_Temp < 16)
        huart.overSampling = USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;
    else
    {
        huart.overSampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;
        UART_Temp /= 16;
    }

    huart.clockPrescalar = (int)UART_Temp;

    if(huart.overSampling == USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION)
    {
        huart.secondModReg = (int)((UART_Temp - huart.clockPrescalar) * 8);
    }
    else
    {
        huart.firstModReg = (int)((UART_Temp - huart.clockPrescalar) * 16);
    }

    huart.parity = USCI_A_UART_NO_PARITY;
    huart.msborLsbFirst = USCI_A_UART_LSB_FIRST;
    huart.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;
    huart.uartMode = USCI_A_UART_MODE;

    if (STATUS_FAIL == USCI_A_UART_init(baseAddress, &huart))
    {
        return STATUS_FAIL;
    }

    //Enable UART module for operation
    USCI_A_UART_enable(baseAddress);

    //Enable Receive Interrupt
    USCI_A_UART_clearInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);
    USCI_A_UART_enableInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);

    return STATUS_SUCCESS;
}

int main(void)
{
    WDT_A_hold(WDT_A_BASE);
    SystemClock_Init();

    UART_Init(USCI_A1_BASE, 115200);

    //interrupts enabled
    __bis_SR_register(GIE);

    while(1)
    {

    }
}

//******************************************************************************
//
//This is the USCI_A0 interrupt vector service routine.
//
//******************************************************************************
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR (void)
{
    uint8_t receivedData = 0;
    switch (__even_in_range(UCA0IV,4))
    {
        //Vector 2 - RXIFG
        case 2:
            receivedData = USCI_A_UART_receiveData(USCI_A0_BASE);
            USCI_A_UART_transmitData(USCI_A0_BASE,receivedData);
            break;
        default:
            break;
    }
}

//******************************************************************************
//
//This is the USCI_A1 interrupt vector service routine.
//
//******************************************************************************
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR (void)
{
    uint8_t receivedData = 0;
    switch (__even_in_range(UCA1IV,4))
    {
        //Vector 2 - RXIFG
        case 2:
            receivedData = USCI_A_UART_receiveData(USCI_A1_BASE);
            USCI_A_UART_transmitData(USCI_A1_BASE,receivedData);
            break;
        default:
            break;
    }
}


           

在main函數中,通過

初始化我們用到的序列槽

連上序列槽調試助手,成功回顯

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

修改波特率,通訊仍能成功

MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰
MSP430F5529 DriverLib 庫函數學習筆記(四)UART通信硬知識UART API(機翻)通過DriverLib庫和硬體知識編寫UART初始化函數原理圖的序列槽部分上機實戰

繼續閱讀