[ZigBee] 7、ZigBee之UART剖析(ONLY串口发送)
?
?
綜述:USART0和USART1是串行通信接口,它們能夠分別運行于異步UART模式或者同步SPI 模式。兩個USART具有同樣的功能,可以設置在單獨的I/O 引腳。
?
1、UART 模式
UART 模式提供異步串行接口。在UART 模式中,接口使用2 線或者含有引腳RXD、TXD、可選RTS 和CTS 的4 線。
UART 模式的操作具有下列特點:
● 8 位或者9 位負載數據
● 奇校驗、偶校驗或者無奇偶校驗
● 配置起始位和停止位電平
● 配置LSB 或者MSB 首先傳送
● 獨立收發中斷
● 獨立收發DMA 觸發
● 奇偶校驗和幀校驗出錯狀態
UART 模式提供全雙工傳送,接收器中的位同步不影響發送功能。傳送一個UART 字節包含1 個起始位、8個數據位、1 個作為可選項的第9 位數據或者奇偶校驗位再加上1 個或2 個停止位。注意,雖然真實的數據包含8 位或者9 位,但是,數據傳送只涉及一個字節。
UART操作由USART控制寄存器UxUCR和狀態寄存器UxCSR來控制。這里的x 是USART的編號,其數值為0 或者1。
當UxCSR.MODE 設置為1 時,就選擇了UART 模式。
?
1.1、UART 發送
當USART 收/發數據緩沖器、寄存器UxBUF 寫入數據時,該字節發送到輸出引腳TXDx。UxBUF 寄存器是雙緩沖的。
當字節傳送開始時, UxCSR.ACTIVE 位變為高電平,而當字節傳送結束時為低。當傳送結束時,UxCSR.TX_BYTE 位設置為1。當USART 收/發數據緩沖寄存器就緒,準備接收新的發送數據時,就產生了一個中斷請求。該中斷在傳送開始之后立刻發生,因此,當字節正在發送時,新的字節能夠裝入數據緩沖器。
1.2、UART 接收
當1 寫入UxCSR.RE 位時,在UART 上數據接收就開始了。然后UART 會在輸入引腳RXDx 中尋找有效起始位,并且設置UxCSR.ACTIVE 位為1。當檢測出有效起始位時,收到的字節就傳入到接收寄存器,UxCSR.RX_BYTE 位設置為1。該操作完成時,產生接收中斷。同時UxCSR.ACTIVE 變為低電平。
通過寄存器UxBUF 提供收到的數據字節。當UxBUF 讀出時,UxCSR.RX_BYTE 位由硬件清0。
??注意:當應用程序讀UxDBUF,很重要的一點是不清除UxCSR.RX_BYTE。
?
1.3、UART 硬件流控制
當UxUCR.FLOW 位設置為1,硬件流控制使能。然后,當接收寄存器為空而且接收使能時,RTS 輸出變低。在CTS 輸入變低之前,不會發生字節傳送。
?
1.4、UART 特征格式
如果寄存器UxUCR 中的BIT9 和奇偶校驗位設置為1,那么奇偶校驗產生而且檢測使能。奇偶校驗計算出來,作為第9 位來傳送。在接收期間,奇偶校驗位計算出來而且與收到的第9 位進行比較。如果奇偶校驗出錯,則UxCSR.ERR 位設置為高電平。當讀取UxCSR 時,UxC-SR.ERR 位清除。
要傳送的停止位的數量設置為1 或者2,這取決于寄存器位UxUCR. SPB。接收器總是要核對一個停止位。如果在接收期間收到的第一個停止位不是期望的停止位電平,就通過設置寄存器位UxCSR.FE 為高電平,發出幀出錯信號。當讀取UxCSR 時,UxCSR.FE 位清除,當UxCSR.SPB 設置為1 時,接收器將核對兩個停止位。
注意:當檢測到第一個停止位正確時,將設置RX 中斷。如果第二個停止位不正確,設置幀誤碼時將有一個延遲。這個延遲與波特率有關(位持續時間)。
?
2、SPI 模式
本節描述了同步通信的SPI 模式。在SPI 模式中,USART 通過3 線接口或者4 線接口與外部系統通信。接口包含引腳MOSI、MISO、SCK 和SS_N。參見GPIO節中有關如何將USART 引腳指派到I/O 引腳的描述。
SPI 模式包含下列特征:
? 3 線(主要)或者4 線SPI 接口
? 主和從模式
? 可配置的SCK 極性和相位
? 可配置的LSB 或MSB 傳送
當UxCSR.MODE 設置為0 時,選中SPI 模式。在SPI 模式中,USART 可以通過寫UxCSR.SLAVE 位來配置SPI 為主模式或者從模式。
?
2.1、SPI 主模式操作
當寄存器UxBUF 寫入字節后,SPI 主模式字節傳送就開始了。USART 使用波特率發生器生成SCK 串行時鐘,而且傳送發送寄存器提供的字節到輸出引腳MOSI。與此同時,接收寄存器從輸入引腳MISO獲取收到的字節。
當傳送開始UxCSR.ACTIVE 位變高,而當傳送結束后, UxCSR.ACTIVE 位變低。當傳送結束時,UxCSR.TX_BYTE 位設置為1。
串行時鐘SCK 的極性由UxGCR.CPOL 位選擇,其相位由UxCSR.CPHA 位選擇。字節傳送的順序由UxCSR.ORDER 位選擇。
傳送結束時,收到的數據字節由UxBUF 提供讀取。當這個新的數據在UxDBUF USART 接收/發送數據寄存器中準備好,就產生一個接收中斷。當單元就緒接收另一個字節用來發送時,發送中斷產生。由于UxBUF 是雙緩沖,這個操作剛好在發送開始時就發生了。注意數據不應寫入UxDBUF,直到UxCSR.TX_BYTE 是1。對于DMA 傳輸這是自動處理的。
對于使用DMA 的背對背傳輸,如果傳輸字節不能被損壞,UxGDR.CPHA 位必須設置為0。對于需要設置UxGDR.CPHA 的系統,需要輪詢UxCSR.TX_BYTE。還要注意發送中斷和接收中斷的區別,因為前者比后者大約提前8 位周期到達。
如上所述的SPI 主模式操作是一個3 線接口。不選擇輸入用于使能主模式。如果外部從模式需要一個從模式選擇信號,這可以使用一個通用I/O 引腳通過軟件實現。
?
2.2、SPI 從模式操作
SPI 從模式字節傳送由外部系統控制。輸入引腳MISO 上的數據傳送到接收寄存器,該寄存器由串行時鐘SCK 控制。SCK 為從模式輸入。與此同時,發送寄存器中的字節傳送到輸出引腳MOSI。
當傳送開始時UxCSR.ACTIVE 位變高,而當傳送結束后,UxCSR.ACTIVE 位變低。當傳送結束時,UxCSR.RX_BYTE 位設置為1,接收中斷產生。
串行時鐘SCK 的極性由UxCSR.CPOL 位選擇,其相位由UxGCR.CPHA 位選擇。字節傳送的順序由UxGCR.ORDER 位選擇。
傳送結束時,收到的數據字節由UxBUF 提供讀取。當SPI 從模式操作開始時,發送中斷。
?
2.3、SSN 從模式選擇引腳
當USART 運行在SPI 模式,配置為SPI 從模式,從模式選擇(SSN)引腳使用一個4 線接口來作為SPI的輸入(邊沿控制)。SSN 的下降沿,SPI 從模式活躍,在MOSI 輸入上接收數據,在MOSI 輸出上輸出數據。SSN 的上升沿,SPI 從模式不活躍,不接收數據。還要注意SSN 上升沿之后MISO 輸出不是三態。還要注意釋放SSN(SSN 變為高電平)必須在字節接收或發送結束。如果在字節中間釋放,下一個要接收的字節將不能正確接收,因為關于之前字節的信息在SPI 系統中。USART 清除能用于刪除這個信息。在SPI 主模式中,不使用SSN 引腳。當USART 運行在SPI 主模式,外部SPI 從模式設備需要提供一個從模式選擇信號,然后一個通用I/O 引腳應在軟件方面作為從模式選擇信號功能。
?
2.4、波特率的產生
當運行在UART 模式時,內部的波特率發生器設置UART 波特率。當運行在SPI 模式時,內部的波特率發生器設置SPI 主時鐘頻率。
由寄存器UxBAUD.BAUD_M[7:0]和UxGCR.BAUD_E[4:0]定義波特率。該波特率用于UART 傳送,也用于SPI 傳送的串行時鐘速率。波特率由下式給出:
式中:f 是系統時鐘頻率,等于16 MHz RCOSC 或者32 MHz XOSC。
標準波特率所需的寄存器值如表16-1 所列。該表適用于典型的32 MHz 系統時鐘。真實波特率與標準波特率之間的誤差,用百分數表示。
當BAUD_E 等于16 且BAUD_M 等于0 時,UART 模式的最大波特率是f/16 且f 是系統時鐘頻率。SPI 模式下的最大波特率見設備數據手冊。
注意:波特率必須通過UxBAUD 和寄存器UxGCR 在任何其他UART 和SPI 操作發生之前設置。這意味著使用這個信息的定時器不會更新,直到它完成它的起始條件,因此改變波特率是需要時間的。
?
?
2.5、清除USART
通過設置寄存器位UxUCR.FLUSH 可以取消當前的操作。這一事件會立即停止當前操作并且清除全部數據緩沖器。應注意在TX/RX 位中間設置清除位,清除將不會發生,直到這個位結束(緩沖將被立即清除但是知道位持續時間的定時器不會被清除)。因此使用清除位應符合USART 中斷,或在USART 可以接收更新的數據或配置之前,使用當前波特率的等待時間位。
?
2.6 USART 中斷
每個USART 都有兩個中斷:RX 完成中斷(URXx)和TX 完成中斷(UTXx)。當傳輸開始觸發TX 中斷,且數據緩沖區被卸載。
USART 的中斷使能位在寄存器IEN0 和寄存器IEN2 中,中斷標志位在寄存器TCON 和寄存器IRCON2 中,中斷使能和標志總結如下。
中斷使能:
● USART0 RX:IEN0.URX0IE
● USARTl RX:IEN0.URXlIE
● USART0 TX:IEN2.UTX0IE
● USARTl TX:IEN2.UTXlIE
中斷標志:
● USART0 RX:TCON.URX0IF
● USARTl RX:TCON.URXlIF
● USART0 TX:IRCON2.UTX0IF
● USARTl TX:IRCON2.UTX1IF
?
2.7、USART DMA 觸發
有兩個DMA 觸發與每個USART 相關。DMA 觸發由事件RX 或者TX 完成激活,也就是說,該事件作為DMA 中斷請求。可以配置DMA 通道使用USART 收/發緩沖器(即UxBUF)作為它的源地址或者目標地址。
2.8、USART 寄存器
本節描述了USART 的寄存器。對于每個USART,有5 個如下的寄存器(x 是USART 的編號,為0 或者1):
● UxCSR:USARTx 控制和狀態;
● UxUCR:USARTx UART 控制;
● UxGCR:USARTx 通用控制
● UxBUF:USART x 接收/發送數據緩沖
● UxBAUD:USART x 波特率控制
?
3、代碼分析
3.1、發送代碼分析
1 /**************************************************************************** 2 * 文 件 名: main.c 3 * 描 述: 設置串口調試助手波特率:115200bps 8N1 4 * 會收到CC2530發過來的:Hello Zigbee 5 ****************************************************************************/ 6 #include <ioCC2530.h> 7 #include <string.h> 8 9 typedef unsigned char uchar; 10 typedef unsigned int uint; 11 #define TX_SIZE 20 12 13 #define TX_STRING "Hello Zigbee " 14 15 char TxData[TX_SIZE]; //存儲發送字符串 16 17 /**************************************************************************** 18 * 名 稱: DelayMS() 19 * 功 能: 以毫秒為單位延時 16M時約為535,32M時要調整,系統時鐘不修改默認為16M 20 * 入口參數: msec 延時參數,值越大延時越久 21 * 出口參數: 無 22 ****************************************************************************/ 23 void DelayMS(uint msec) 24 { 25 uint i,j; 26 27 for (i=0; i<msec; i++) 28 for (j=0; j<1070; j++); 29 } 30 31 /**************************************************************************** 32 * 名 稱: InitUart() 33 * 功 能: 串口初始化函數 34 * 入口參數: 無 35 * 出口參數: 無 36 ****************************************************************************/ 37 void InitUart(void) 38 { 39 PERCFG = 0x00; //外設控制寄存器 USART 0的IO位置:0為P0口位置1 40 P0SEL = 0x0c; //P0_2,P0_3用作串口(外設功能) 41 P2DIR &= ~0XC0; //P0優先作為UART0 42 43 U0CSR |= 0x80; //設置為UART方式 44 U0GCR |= 11; 45 U0BAUD |= 216; //波特率設為115200 46 UTX0IF = 0; //UART0 TX中斷標志初始置位0 47 } 48 49 /**************************************************************************** 50 * 名 稱: UartSendString() 51 * 功 能: 串口發送函數 52 * 入口參數: Data:發送緩沖區 len:發送長度 53 * 出口參數: 無 54 ****************************************************************************/ 55 void UartSendString(char *Data, int len) 56 { 57 uint i; 58 59 for(i=0; i<len; i++) 60 { 61 U0DBUF = *Data++; 62 while(UTX0IF == 0); 63 UTX0IF = 0; 64 } 65 } 66 67 /**************************************************************************** 68 * 程序入口函數 69 ****************************************************************************/ 70 void main(void) 71 { 72 CLKCONCMD &= ~0x40; //設置系統時鐘源為32MHZ晶振 73 while(CLKCONSTA & 0x40); //等待晶振穩定為32M 74 CLKCONCMD &= ~0x47; //設置系統主時鐘頻率為32MHZ 75 76 InitUart(); //調置串口相關寄存器 77 memset(TxData, 0, TX_SIZE); //數據清0 78 memcpy(TxData, TX_STRING, sizeof(TX_STRING)); //復制發送字符串到TxData 79 80 while(1) 81 { 82 UartSendString(TxData, sizeof(TX_STRING)); //串口發送數據 83 DelayMS(1000); //延時 84 } 85 }第39~41行是串口的IO設置相關,這個要回到IO節進行了解。
首先我們先看下面外設IO映射表:發現USART0和USART1都各自對應著兩種端口映射關系:
以USART0為例,第一種映射關系是RT-P05\CT-P04\TX-P03\RX-P02;另一種映射關系是TX-P15\RX-P14\RT-P13\CT-P12。
?
那么在使用過程中,一種模式對應兩種映射肯定會出現矛盾!因此代碼中第39行:
PERCFG = 0x00;就是實現選中USART0和USART1的各自的第一種映射!(這樣我們就能找到對應的引腳了!)這里的SFR 寄存器位PERCFG.U0CFG的功能就是選擇是否使用備用位置1 或備用位置2。
?
對于USART 和定時器I/O,在一個數字I/O 引腳上選擇外設I/O 功能,需要設置對應的PxSEL 位為1。因此,代碼中第40行0x0c=1100
P0SEL = 0x0c;是設置P02、P03用在串口外設IO
?
以上兩個設置導致USART0的4個串口IO和USART1的四個IO沖突了,如果同時發生USART事件就會導致問題。因此可以通過指派這些沖突外設的優先級:
P2DIR &= ~0XC0;P2DIR.PRIP0 選擇為端口0 指派一些外設的優先順序。當設置為00 時,USART 0 優先。注意如果選擇了UART 模式,且硬件流量控制禁用,UART 1 或定時器1 將優先使用端口P0.4 和P0.5。2SEL.PRI3P1 和P2SEL.PRI0P1 選擇為端口1 指派一些外設的優先順序。當它們兩個都設置為0 時,USART0 優先。注意如果選擇了UART 模式,且硬件流量控制禁用,定時器1 或定時器3 將優先使用端口P1.2 和P1.3。這里設置的是00,因此UART0優先于UART1!
?
上面這么長的分析我們才知道39~41行是設置UART1和UART0對應的引腳及他們的優先級關系!
接下來的幾行代碼主要和串口設置有關,比如波特率、奇偶校驗等...
其中第43行:
U0CSR |= 0x80;用來設置UART0模式:UART模式,不接收數據(僅僅發送)等
?
其中第44行:
U0GCR |= 11;設置USART0:MSB first及波特率其中一個影響因素BAUD_E(和45行U0BAUD設置BAUD_M一起根據上面講的公式能夠計算波特率)
?
其中第45行:
U0BAUD |= 216;用來設置BAUD_M
?
其中第46行用來初始化UART0 TX中斷標志為0:
UTX0IF = 0;在串口發送函數中將數據寫入BUF,然后等待UART0 TX為1,表示發送出去了,然后清除中斷標志,等待下一次發送。這個類似51單片機中的串口發送,不多講!
?
?今天太晚了,此外這篇文章寫的太長了!就不準備把串口收發等剖析放在這里講了~晚安,各位!
?
Zigbee系列文章:
[ZigBee] 1、 ZigBee簡介
[ZigBee] 2、 ZigBee開發環境搭建
[ZigBee] 3、ZigBee基礎實驗——GPIO輸出控制實驗-控制Led亮滅
[ZigBee] 4、ZigBee基礎實驗——中斷
[ZigBee] 5、ZigBee基礎實驗——圖文與代碼詳解定時器1(16位定時器)(長文)
[ZigBee] 6、ZigBee基礎實驗——定時器3和定時器4(8 位定時器)
本文轉自beautifulzzzz博客園博客,原文鏈接:http://www.cnblogs.com/zjutlitao/p/5675169.html,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的[ZigBee] 7、ZigBee之UART剖析(ONLY串口发送)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sap IUT255 Integrati
- 下一篇: extjs中js资源缓存策略