CC2541藍牙學習——串口_1


CC2541有兩個串行通信接口,分別是USART0和USART1,它們能夠分別運行於異步UART模式或者同步SPI模式。兩個USART具體同樣的功能,可以設置在單獨的I/O引腳。

1.UART模式

UART模式提供異步串行接口,在UART模式中,有2種接口選擇方式:2線接口和4線接口。

  • 2線接口,使用RXD、TXD。
  • 4線接口,使用RXD、TXD、RTS和CTS。

I/O外設引腳映射如下圖所示:

根據上面的外設I/O引腳映射可知

UART0對應的外部設置IO引腳關系為:位置1:P0_2----RX    P0_3----TX     位置2:P1_4----RX    P1_5----TX

UART1對應的外部設置IO引腳關系為:位置1:P0_5----RX    P0_4----TX     位置2:P1_7----RX    P1_6----TX

UART模式的操作有以下特點。

  • 8位或者9位負載數據
  • 奇校驗、偶校驗或者無奇偶校驗
  • 配置起始位和停止位電平
  • 配置LSB(最低有效位)或MSB(最高有效位)首先傳輸
  • 獨立接收中斷
  • 獨立收發DMA觸發
  • 奇偶校驗和幀檢驗出錯狀態

UART模式提供全雙工傳送,也就是說可以同時收發數據,傳送一個UART字節包括1個起始位,8個數據位,1個作為可選的第9位數據或者奇偶校驗位,再加上1個或者2個停止位。

UART操作由USART控制和狀態寄存器UxCSR以及UART控制寄存器UxUCR來控制,x是USART的編號,數值為0或者1。

當UxCSR.MODE設置為1時設定為UART模式。

1)UART的發送過程

當USART收發數據緩沖器UxDBUF寫入數據時,該字節自動發送到輸出引腳TXD,UxDBUF寄存器時雙緩沖的。當字節傳送開始時,UxCSR.ACTIVE位變為高電平,而當字節傳送結束時變為低電平。當傳送結束時,UxCSR.TX_BYTE位設置為1。當USART收發數據緩沖寄存器就緒,准備接收新的發送數據時,就產生了一個中斷請求,該中斷在傳送開始后立刻發生。

2)UART的接收過程

當1寫入UxCSR.RE位時,UART開始接收數據。UART在輸入引腳RXD上尋找有效起始位,並且設置UxCSR.ACTIVE位為1,當檢測出有效起始位時,收到的字節就傳入到接收寄存器,UxCSR.RX_BYTE位設置為1,該操作完成時,產生接收中斷,同時UxCSR.ACTIVE變為0,通過寄存器UxDBUF提取收到的數據字節。當UxDBUF讀出時,UxCSR.RX_BYTE位由硬件清零。

當運行UART模式時,內部的波特率發生器設置UART波特率。當運行在SPI模式時,內部的波特率發生器設置SPI主時鍾頻率。波特率由寄存器UxBAUD.BAUD_M[7:0] 和UxGCR.BAUD_E[4:0]定義。該波特率用於UART傳送,也用於SPI傳送的串行時鍾速率。波特率定義公式:

式中:f是系統的時鍾頻率,等於16MHz或者32MHz

標准波特率所需的寄存器值如下表所示,該表適用於32MHz系統時鍾。波特率誤差,用百分數表示。

CC2530配置串口的一般步驟

1、配置串口的備用位置,是備用位置1,還是備用位置2。配置寄存器PERCFG外設控制寄存器

2、配置端口的外設優先級。此處配置P0外設優先作為UART0。配置寄存器P2DIR

3、配置IO,使用外部設備功能。此處配置P0_2和P0_3用作串口UART0。配置寄存器P0SEL

4、配置相應串口的控制和狀態寄存器。配置寄存器U0CSR、U0UCR

5、配置串口工作的波特率。配置寄存器U0GCR、U0BAUD

6、將對應的串口接收/發送中斷標志位清0,清零:TCON.URX0IF、TCON.URX1IF、IRCON2.UTX0IF、IRCON2.UTX1IF

7、使能串口接收中斷(一般發送不用中斷),置1 IEN0.URX0IE

8、開總中斷

中斷相關的寄存器如下:

IEN0(0xA8)

TCON(0x88)

 

 IRCON2(0xE8)

 1 /*****************************************************************************
 2 *函 數 名:InitUART
 3 *功    能:UART0串口初始化,波特率:115200
 4 *入口參數:無
 5 *出口參數:無
 6 ******************************************************************************/
 7 void InitUART(void)
 8 {
 9   PERCFG &= ~0x01;     //USART0為位置1
10   P2DIR &= ~0xc0;      //優先級USART0 >USART1 >定時器1
11   P0SEL |= 0x0c;       //P0_2,P0_3 用作串口(外部設備功能)
12   U0CSR |= 0x80;       //設置為UART 方式
13   U0CSR |= 0x40;       //使能接收器
14   
15   U0UCR = 0x02;        //禁止流控制,8bits,無校驗位,1位停止位
16                        //起始位低電平,停止位高電平
17   U0GCR |=11;          //32MHz 下的BAUD_E:11, 115200
18   U0BAUD |= 216;       //32MHz 下的BAUD_M:216 11520
19   UTX0IF = 0;          //UART0 TX 中斷標志初始置位0
20   IEN0 |= 0x04;        //使能USART0 RX中斷
21   EA = 1;              //開總中斷
22 }

實例程序:串口控制LED1和LED2等的亮滅以及上位機控制串口接收,這里的通信協議比較簡單,上位機發送兩字節的數據:一個控制燈亮滅的字節,一個結束字節'#'

"1#":LED1滅

"2#":LED1亮

"3#":LED2滅

"4#":LED2亮

"5#":LED1、LED2亮

"6#":LED1、LED2滅

"7#":CC2541向上位機發送字符串”Hello Chen Zhao!“ 按一下界面上的”接收“按鈕,接收下位機發送過來的字符串。

這個程序寫的比較簡單,這里只是一個演示,很容易出現發送解碼錯誤,應該組幀,以一定的通信協議傳輸數據,包括幀頭、校驗、數據字節、幀尾,在后續串口介紹中,將專門介紹下這方面的技巧。

為了驗證程序,我做了一個上位機程序,界面如下,用labview軟件編寫的。如果需要的話,可以拿走源程序。

  1 /******************************************************************************
  2 *文 件 名:main.c
  3 *作    者:陳照
  4 *時    間:2015-05-18
  5 *版    本:1.0
  6 *描    述:UART串口發送與接收
  7 ******************************************************************************/
  8 #include <iocc2541.h>
  9 #include <string.h>
 10 
 11 typedef unsigned char uchar;
 12 typedef unsigned int  uint;
 13 
 14 #define LED1 P1_0
 15 #define LED2 P1_1
 16 
 17 char Rxdata[2] = " " ;  //串口接收字符串
 18 char Txdata[] = "Hello Chen Zhao!" ;  //串口接收字符串
 19 int  txnum = sizeof(Txdata);
 20 
 21 char temp;             //串口接收字符
 22 uchar datanum = 0;     //串口接收字符串長度
 23 uchar RXflag = 1;
 24 uchar TXflag = 0;
 25 
 26 /****************************************************************
 27 *函 數 名:InitClock
 28 *功    能:系統時鍾初始化
 29 *入口參數:無
 30 *出口參數:無
 31 *****************************************************************/
 32 void InitClock(void)
 33 {
 34 CLKCONCMD &= ~0x40; // 設置系統時鍾源為 32MHZ晶振
 35 while(CLKCONSTA & 0x40); // 等待晶振穩定 
 36 CLKCONCMD &= ~0x47; // 設置系統主時鍾頻率為 32MHZ
 37 }
 38 
 39 /******************************************************************************
 40 *函 數 名:InitLED
 41 *功    能:LED口功能初始化
 42 *入口參數:無
 43 *出口參數:無
 44 ******************************************************************************/
 45 void InitLED(uchar On_Off)
 46 {
 47   P1SEL &= ~0x03;      //P1.0、P1.1設置為通用I/O口
 48   P1DIR |=  0x03;      ///P1.0、P1.1設置為輸出
 49   LED1 = On_Off;       ///P1.0、P1.1亮滅初始化
 50   LED2 = On_Off;
 51 }
 52 
 53 /******************************************************************************
 54 *函 數 名:InitUART
 55 *功    能:UART0串口初始化,波特率:115200
 56 *入口參數:無
 57 *出口參數:無
 58 ******************************************************************************/
 59 void InitUART(void)
 60 {
 61   PERCFG &= ~0x01;     //USART0為位置1
 62   P2DIR &= ~0xc0;      //優先級USART0 >USART1 >定時器1
 63   P0SEL |= 0x0c;       //P0_2,P0_3 用作串口(外部設備功能)
 64   U0CSR |= 0x80;       //設置為UART 方式
 65   U0CSR |= 0x40;       //使能接收器
 66   
 67   U0UCR = 0x02;        //禁止流控制,8bits,無校驗位,1位停止位
 68                        //起始位低電平,停止位高電平
 69   U0GCR |=11;          //32MHz 下的BAUD_E:11, 115200
 70   U0BAUD |= 216;       //32MHz 下的BAUD_M:216 11520
 71   UTX0IF = 0;          //UART0 TX 中斷標志初始置位0
 72   IEN0 |= 0x04;        //使能USART0 RX中斷
 73   //IEN2 |= 0x04;      //使能USART0 TX中斷
 74   EA = 1;              //開總中斷
 75 }
 76 
 77 /****************************************************************************
 78 * 名    稱: UartSendString()
 79 * 功    能: 串口發送函數
 80 * 入口參數: Data:發送緩沖區   len:發送長度
 81 * 出口參數: 無
 82 ****************************************************************************/
 83 void UartSendString(char *Data, int len)
 84 {
 85   uint i;
 86   U0CSR &= ~0x40;  
 87   
 88   for(i=0; i<len; i++)
 89   {
 90     U0DBUF = *Data++;
 91     while(UTX0IF == 0);
 92     UTX0IF = 0;
 93   }
 94   TXflag = 0;  
 95   U0CSR |= 0x40;       //使能接收器
 96 }
 97 
 98 /******************************************************************************
 99 *函 數 名:UART0_ISR
100 *功    能:串口0中斷服務程序
101 *入口參數:無
102 *出口參數:無
103 ******************************************************************************/
104 #pragma vector = URX0_VECTOR 
105 __interrupt void UART0_ISR(void) 
106 { 
107   URX0IF = 0;           //UART0 RX中斷標志位清0
108   temp = U0DBUF;        //讀取U0DBUF的值
109 }
110 
111 /******************************************************************************
112 *程序入口函數
113 ******************************************************************************/
114 int main(void)
115 {  
116   InitClock();
117   InitLED(0);          //LED初始化,熄滅LED1、LED2
118   InitUART();          //UART0串口初始化
119   
120   UartSendString(Txdata,txnum); 
121   while(1)
122   {
123     if(RXflag == 1)
124     {
125       if(temp !=0)
126       {
127         if((temp != '#') && (datanum < 2))
128         {
129           Rxdata[datanum++] = temp;
130         }
131         else
132         {
133           RXflag = 2;
134         }
135 
136           temp = 0;
137       }
138     }
139     if(RXflag == 2)
140     {
141       switch(Rxdata[0])
142       {
143         case '1':LED1 = 0;break;
144         case '2':LED1 = 1;break;
145         case '3':LED2 = 0;break;
146         case '4':LED2 = 1;break;
147         case '5':
148         {
149           LED1 = 1;
150           LED2 = 1;
151           break;
152         }
153         case '6':
154         {
155           LED1 = 0;
156           LED2 = 0;
157           break;
158         }
159         case '7':
160         {
161            TXflag = 1;
162            break;
163            
164         }
165         default: 
166         {//LED1 = 0;
167          //LED2 = 0;
168         }
169       }
170       RXflag = 1;
171       memset(Rxdata, 0, 2);
172       datanum = 0;
173     }
174     if(TXflag == 1)
175     {
176        UartSendString(Txdata,txnum); 
177        
178     }
179   }
180 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM