(一)串口發送
一、實驗現象:
開發板實現功能發送
二、實驗過程
1、PL2303 USB轉串口電路圖
2、串口發送
(1)查看用戶手冊有:
UART0 對應的外部設備 IO 引腳關系為: P0_2 ------ RX
P0_3 ------ TX
UART1 對應的外部設備 IO 引腳關系為: P0_5 ------ RX
P0_4 ------ TX
(2)USART功能特點:
在 CC2540中, UART0和UART1是串行通信接口,它們能夠分別運於異步UART模式或者同步SPI模式兩個模式。兩個UART的功能是一樣,可以通過設置在單獨的 IO引腳上。
UART 模式的操作具有下列特點:
①8位或者 9位負載數據
②奇校驗、偶校驗或者無奇偶校驗
③配置起始位和停止電平
④配置 LSB 或者 MSB 首先傳送
⑤獨立收發中斷
⑥獨立收發 DMA 觸發
(3)CC2540配置串口的一般步驟
① 配置 IO,使用外部設備功能。 此處配置 P0_2 和 P0_3用作串口 UART0
② 配置相應串口的控制和狀態寄存器。 此處配置 UART0 的工作寄存器
③ 配置串口工作的波特率。 此處配置波特率為115200
(4)寄存器的相關內容:
U0CSR (UART0控制和狀態寄存器) |
BIT7:MODE | 0:SPI模式 1:UART模式 |
BIT6:RE | 0:接收器進制 1:接收器使能 | |
BIT5:SLAVE | 0:SPI主模式 1:SPI從模式 | |
BIT4:FE | 0:沒有檢測到出幀錯誤 1:收到字節停止位電平出錯 |
|
BIT3:ERR | 0:沒有檢測出奇偶檢驗出錯 1:收到字節奇偶檢驗出錯 |
|
BIT2:RX_BYTE | 0:沒有收到字節 1:收到字節就緒 |
|
BIT1:TX_BYTE | 0:沒有發送字節 1:寫到數據緩沖區寄存器的最后字節已發送 |
|
BIT0:ACTIVE | 0:UART空閑 1:UART忙碌 |
|
U0GCR (UART0通用控制寄存器) |
BIT7:CPOL | 0:SPI負時鍾極性 1:SPI正時鍾極性 |
BIT6:CPHA | 0:當來自CPOL的SCK反相之后又返回CPOL時,數據輸出到 MOSI;當來自CPOL的SCK返回CPOL反相時,輸入數據采樣到MISO。 1:當來自CPOL的SCK反相之后又返回CPOL時,輸入數據采樣MOSI;當來自CPOL的SCK返回CPOL反相時,數據輸出到 MOSI。 |
|
BIT5:ORDER | 0:LSB先傳送 1:MSB先傳送 |
|
BIT[4,0]:BAUD_E | 波特率指數值 BAUD_E連同BAUD_M一起決定了UART的波特率 | |
U0BAUD UART0 波特率控制寄存器 |
BIT[7,0]:BAUD_M | 波特率尾數值 BAUD_E連同BAUD_M一起決定了UART的波特率 |
U0DBUF | 串口發送/接受數據緩沖區 | |
UTX0IF 發送中斷標志 |
中斷標志5IRCON2的BIT1 | 0:中斷未掛起 1:中斷掛起 |
(5)串口波特率設置
公式如下:
常用波特率設置:
(6)代碼實現:
#include<ioCC2540.h> #include <string.h> #define uint unsigned int #define uchar unsigned char //定義LED的端口 #define LED1 P1_0 #define LED2 P1_1 //函數聲明 void Delay_ms(uint); void initUART(void); void UartSend_String(char *Data,int len); char Txdata[19]; //存放"Hello BlueTooth4.0\n"共19個字符串 /**************************************************************** 延時函數 ****************************************************************/ void Delay_ms(uint n) { uint i,j; for(i=0;i<n;i++) for(j=0;j<1774;j++); } void IO_Init() { P1DIR = 0x01; //P1_0,P1_1 IO方向輸出 LED1 = 0; } /**************************************************************** 串口初始化函數 ****************************************************************/ void InitUART(void) { PERCFG = 0x00; //位置1 P0口 P0SEL = 0x0c; //P0_2,P0_3用作串口(外部設備功能) P2DIR &= ~0XC0; //P0優先作為UART0 U0CSR |= 0x80; //設置為UART方式 U0GCR |= 11; U0BAUD |= 216; //波特率設為115200 UTX0IF = 0; //UART0 TX中斷標志初始置位0 } /**************************************************************** 串口發送字符串函數 ****************************************************************/ void UartSend_String(char *Data,int len) { int j; for(j=0;j<len;j++) { U0DBUF = *Data++; while(UTX0IF == 0); UTX0IF = 0; } } /**************************************************************** 主函數 ****************************************************************/ void main(void) { CLKCONCMD &= ~0x40; //設置系統時鍾源為32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振穩定為32M CLKCONCMD &= ~0x47; //設置系統主時鍾頻率為32MHZ IO_Init(); InitUART(); strcpy(Txdata,"Hello BlueTooth4.0\n"); //將發送內容copy到Txdata; while(1) { UartSend_String(Txdata,sizeof("Hello BlueTooth4.0\n")); //串口發送數據 Delay_ms(500); //延時 LED1=!LED1; //標志發送狀態 } }
三、實驗成果:
PS:串口驅動,不行去百度下一個,然后更新驅動程序,在列表中選擇,直到選到一個能用的。。真是無底坑。
(二)串口接受和發送
一、實驗現象:
開發板實現收發
二、實驗過程
原理部分同上,直接上源碼
#include<ioCC2540.h> #include<string.h> //宏定義 #define LED1 P1_0 #define LED2 P1_1 //函數聲明 void Delay_ms(unsigned int delay); //延時函數 void IO_init(); //IO配置 void UART_init(); //初始化UART void Send_String(char *Data,int len); //發送字符串函數 //變量聲明 char temp=0; //接收到的字符 char Strdata[60]; //存放字符串 //延時函數 void Delay_ms(unsigned int delay) { unsigned int i,j; for(i=delay;i>0;i--) { for(j=0;j<1774;j++); } } //IO配置 void IO_init() { P1SEL=0x00; P1DIR=0X03; P1INP=0X00; LED1=0; LED2=0; } //初始化UART void UART_init() { PERCFG=0X00; //位置一:P0口 P0SEL=0X3c; //P0_2,P0_3,P0_4,P0_5用作第三用途 P2DIR &= ~0XC0; //方向為輸入 U0CSR|=0X80; //設置UART方式 U0GCR|=11; U0BAUD|=216; //設置波特率 UTX0IF=0; //清除中斷標志位 //用來接收字符 U0CSR |= 0x40; //允許接收 IEN0 |= 0x84; //開總中斷,接收中斷 } //發送字符串函數 void Send_String(char *Data,int len) { unsigned int i; for(i=0;i<len;i++) { //U0DBUF = *Data++; //兩種方法都可以 U0DBUF = Data[i]; while(UTX0IF==0); //發送完一個字符后,會產生一個中斷。我們通過等待中斷產生,來控制傳輸時間間隔。 UTX0IF = 0; } } void main() { int datanumber = 0; //統計字符長度 int RXTXflag = 1; //接收狀態標志變量 CLKCONCMD &= ~0x40; //設置系統時鍾源為32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振穩定 CLKCONCMD &= ~0x47; //設置系統主時鍾頻率為32MHZ。 IO_init(); //初始化 UART_init(); strcpy(Strdata,"Hello World~\n"); while(1) { if(RXTXflag == 1) //接收狀態 { LED1 = 1; //接收狀態表示 if(temp!=0) { if((temp!='#')&&(datanumber<50)) //最多接收50個字符,和以#號結束 { Strdata[datanumber++] = temp; } else { RXTXflag=3; //進入發送狀態 LED1=0; //關指示燈 } temp=0; } } if(RXTXflag == 3) { LED2=1; //發送狀態表示 U0CSR &= ~0X40; //禁止接收 Send_String(Strdata,datanumber); U0CSR |= 0x40; //允許接受 RXTXflag = 1; //恢復到接收狀態 datanumber = 0; //指針歸0 LED2 = 0; //關發送提示 } } } //一個個拿出發送的字符,使用中斷的手段
#pragma vector = URX0_VECTOR __interrupt void fu(void) { URX0IF=0; //清除中斷標志 temp=U0DBUF; }
三、實驗結果
(三)UART0控制LED
一、實驗現象:
開發板實現UARTO控制LED
二、實驗過程
原理部分同上,直接上源碼
#include<ioCC2540.h> #include<string.h> //宏定義 #define LED1 P1_0 #define LED2 P1_1 //函數聲明 void Delay_ms(unsigned int delay); //延時函數 void IO_init(); //IO配置 void UART_init(); //初始化UART void Send_String(char *Data,int len); //發送字符串函數 //變量聲明 char temp=0; //接收到的字符 char Strdata[60]; //存放字符串 //延時函數 void Delay_ms(unsigned int delay) { unsigned int i,j; for(i=delay;i>0;i--) { for(j=0;j<1774;j++); } } //IO配置 void IO_init() { P1SEL=0x00; P1DIR=0X03; P1INP=0X00; LED1=0; LED2=0; } //初始化UART void UART_init() { PERCFG=0X00; //位置一:P0口 P0SEL=0X3c; //P0_2,P0_3,P0_4,P0_5用作第三用途 P2DIR &= ~0XC0; //方向為輸入 U0CSR|=0X80; //設置UART方式 U0GCR|=11; U0BAUD|=216; //設置波特率 UTX0IF=0; //清除中斷標志位 //用來接收字符 U0CSR |= 0x40; //允許接收 IEN0 |= 0x84; //開總中斷,接收中斷 } //發送字符串函數 void Send_String(char *Data,int len) { unsigned int i; for(i=0;i<len;i++) { //U0DBUF = *Data++; //兩種方法都可以 U0DBUF = Data[i]; while(UTX0IF==0); //發送完一個字符后,會產生一個中斷。我們通過等待中斷產生,來控制傳輸時間間隔。 UTX0IF = 0; } } void main() { int datanumber = 0; //統計字符長度 int RXTXflag = 1; //接收狀態標志變量 CLKCONCMD &= ~0x40; //設置系統時鍾源為32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振穩定 CLKCONCMD &= ~0x47; //設置系統主時鍾頻率為32MHZ。 IO_init(); //初始化 UART_init(); while(1) { if(RXTXflag == 1) //接收狀態 { if(temp!=0) { if((temp!='#')&&(datanumber<50)) //最多接收50個字符,和以#號結束 { Strdata[datanumber++] = temp; } else { RXTXflag=3; //進入發送狀態 } temp=0; } } if(RXTXflag == 3) { if( Strdata[0]=='L') { switch( Strdata[1]-'0') { case 1: LED1=~LED1;break; //低電平點亮 case 2: LED2=~LED2;break; } } RXTXflag = 1; //恢復到接收狀態 datanumber = 0; //指針歸0 } } } #pragma vector = URX0_VECTOR __interrupt void fu(void) { URX0IF=0; //清除中斷標志 temp=U0DBUF; }
三、實驗結果