[ZigBee] 8、ZigBee之UART剖析·二(串口收發)


 

前言:上一節講UART基本知識介紹完了,並深入剖析了一個串口發送工程,本節將進一步介紹串口收發!

 

1、初始化

在串口初始化部分,和上一節不同的地方是:

 51     U0CSR |= 0x40;           //允許接收 
 52     IEN0 |= 0x84;            //開總中斷允許接收中斷  

第51行使能接收數據,上一節介紹的僅僅是發送,所以沒有這一句配置:

第51行開總中斷和UART0中斷:

  1 /****************************************************************************
  2 * 文 件 名: main.c
  3 * 描    述: 設置串口調試助手波特率:115200bps 8N1
  4 *           串口調試助手給CC2530發字符串時,開發板會返回接收到的字符串
  5 ****************************************************************************/
  6 #include <ioCC2530.h>
  7 #include <string.h>
  8 
  9 typedef unsigned char uchar;
 10 typedef unsigned int  uint;
 11 
 12 #define UART0_RX    1
 13 #define UART0_TX    2
 14 #define SIZE       51
 15 
 16 char RxBuf;
 17 char UartState;
 18 uchar count;
 19 char RxData[SIZE];        //存儲發送字符串
 20 
 21 /****************************************************************************
 22 * 名    稱: DelayMS()
 23 * 功    能: 以毫秒為單位延時
 24 * 入口參數: msec 延時參數,值越大,延時越久
 25 * 出口參數: 無
 26 ****************************************************************************/
 27 void DelayMS(uint msec)
 28 { 
 29     uint i,j;
 30     
 31     for (i=0; i<msec; i++)
 32         for (j=0; j<1070; j++);
 33 }
 34 
 35 /****************************************************************************
 36 * 名    稱: InitUart()
 37 * 功    能: 串口初始化函數
 38 * 入口參數: 無
 39 * 出口參數: 無
 40 ****************************************************************************/
 41 void InitUart(void)
 42 { 
 43     PERCFG = 0x00;           //外設控制寄存器 USART 0的IO位置:0為P0口位置1 
 44     P0SEL = 0x0c;            //P0_2,P0_3用作串口(外設功能)
 45     P2DIR &= ~0xC0;          //P0優先作為UART0
 46     
 47     U0CSR |= 0x80;           //設置為UART方式
 48     U0GCR |= 11;                       
 49     U0BAUD |= 216;           //波特率設為115200
 50     UTX0IF = 0;              //UART0 TX中斷標志初始置位0
 51 U0CSR |= 0x40; //允許接收   52 IEN0 |= 0x84; //開總中斷允許接收中斷  
 53 }
 54 
 55 /****************************************************************************
 56 * 名    稱: UartSendString()
 57 * 功    能: 串口發送函數
 58 * 入口參數: Data:發送緩沖區   len:發送長度
 59 * 出口參數: 無
 60 ****************************************************************************/
 61 void UartSendString(char *Data, int len)
 62 {
 63     uint i;
 64     
 65     for(i=0; i<len; i++)
 66     {
 67         U0DBUF = *Data++;
 68         while(UTX0IF == 0);
 69         UTX0IF = 0;
 70     }
 71 }
 72 
 73 /****************************************************************************
 74 * 名    稱: UART0_ISR(void) 串口中斷處理函數 
 75 * 描    述: 當串口0產生接收中斷,將收到的數據保存在RxBuf中
 76 ****************************************************************************/
 77 #pragma vector = URX0_VECTOR  78 __interrupt void UART0_ISR(void)  79 {  80 URX0IF = 0; // 清中斷標志   81 RxBuf = U0DBUF;  82 }  83 
 84 
 85 /****************************************************************************
 86 * 程序入口函數
 87 ****************************************************************************/
 88 void main(void)
 89 {    
 90     CLKCONCMD &= ~0x40;                        //設置系統時鍾源為32MHZ晶振
 91     while(CLKCONSTA & 0x40);                   //等待晶振穩定為32M
 92     CLKCONCMD &= ~0x47;                        //設置系統主時鍾頻率為32MHZ   
 93    
 94     InitUart();                                //調用串口初始化函數   
 95 UartState = UART0_RX; //串口0默認處於接收模式
 96     memset(RxData, 0, SIZE);
 97     
 98     while(1)
 99     {
100         if(UartState == UART0_RX)              //接收狀態 
101         { 
102             if(RxBuf != 0) 
103             {                 
104                 if((RxBuf != '#')&&(count < 50))//以'#'為結束符,一次最多接收50個字符            
105                     RxData[count++] = RxBuf; 
106                 else
107                 {
108                     if(count >= 50)             //判斷數據合法性,防止溢出
109                     {
110                         count = 0;              //計數清0
111                         memset(RxData, 0, SIZE);//清空接收緩沖區
112                     }
113                     else
114                         UartState = UART0_TX;  //進入發送狀態 
115                 }
116                 RxBuf  = 0;
117             }
118         }
119         
120 if(UartState == UART0_TX) //發送狀態  121  { 122 U0CSR &= ~0x40; //禁止接收  123 UartSendString(RxData, count); //發送已記錄的字符串。 124 U0CSR |= 0x40; //允許接收  125 UartState = UART0_RX; //恢復到接收狀態  126 count = 0; //計數清0 127 memset(RxData, 0, SIZE); //清空接收緩沖區 128  }  129     }
130 }

 

2、中斷回調函數

第77~82行是UART0中斷處理函數,每次有數據從上位機發送下來都會觸發該函數執行,在概述內將上位機發送來的數據保存在RxBuf中:

 77 #pragma vector = URX0_VECTOR 
 78 __interrupt void UART0_ISR(void) 79 { 80 URX0IF = 0; // 清中斷標志 81 RxBuf = U0DBUF; 82 }

 

3、main函數流程

串口初始狀態為接收狀態,其中100-118行把中斷處理函數中暫存的接收數據RxBuf轉存到RxData數組中,接收過程中發現結束標志位則將狀態轉換為發送狀態,則120~128行發送數據的代碼段將被執行:

120         if(UartState == UART0_TX)              //發送狀態 
121  { 122 U0CSR &= ~0x40; //禁止接收 123 UartSendString(RxData, count); //發送已記錄的字符串。 124 U0CSR |= 0x40; //允許接收 125 UartState = UART0_RX; //恢復到接收狀態 126 count = 0; //計數清0 127 memset(RxData, 0, SIZE); //清空接收緩沖區 128  } 

這里要特別注意,發送的時候要禁止接收,發送完畢要使能接收,着也就是122行和124行代碼的意圖!

 

 

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 位定時器)

[ZigBee] 7、ZigBee之UART剖析(ONLY串口發送)

 

 

PS:如果您覺得還不錯,點個贊,讓更多人受益~

@beautifulzzzz 2016-07-16 continue~  
e-mail:beautifulzzzz@qq.com 
sina:http://weibo.com/beautifulzzzz?is_all=1

 


免責聲明!

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



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