前言:上一節講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] 3、ZigBee基礎實驗——GPIO輸出控制實驗-控制Led亮滅
[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