CC2540開發板學習筆記(五)——串口通信


(一)串口發送

一、實驗現象:

    開發板實現功能發送

二、實驗過程

1、PL2303 USB轉串口電路圖

image

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)串口波特率設置

公式如下:

image

常用波特率設置:

image

(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;                       //標志發送狀態
   }
}

三、實驗成果:

image

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;
}

三、實驗結果

image

(三)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;
}

三、實驗結果

image


免責聲明!

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



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