感知層編程實驗三


南昌航空大學實驗報告

011018

 

課程名稱:  感知層編程實驗  實驗名稱:UART編程

班級學號:        姓名:         同組人:                           

指導教師評定:                                      簽名:              

實驗 UART編程

實驗目的:

  1. 加深和鞏固學生對於CC2530串口的理解和掌握
  2. 讓學生初步掌握CC2530串口編程方法
  3. 高學生的上機和編程過程中處理具體問題的能力

實驗要求:

  1. 實驗要求自己獨立的完成
  2. 編寫和調試過程中出現的問題記錄,並事后總結到報告中
  3. 實驗程序調試完成后, 用給定的平台進行測試,由老師檢查測試結果,並給予相應的成績
  4. 實驗完成后,要上交實驗報告

實驗內容:

  1. 首先完成教材上的串口實驗
  2. 開發一個新的應用,能夠利用串口消息控制LED燈的亮滅
    1. 設計串口通信消息包格式,包含起始字段(2個字節,內容自定)、包長度(1個字節,不CRC字節)、命令碼(1個字節)、CRC字段(1個字節,除CRC之外所有字節的異或和)有上位機到CC2530的命令包,CC2530到上位機的狀態包。
    2. 命令包括:on/off/toggleon命令開燈、off關燈、toggle切換燈狀態
    3. 采用FSM(有限狀態機)處理命令包。
  3. 在實驗報告中分別給出源碼

實驗環境:

集成開發環境為IAR

實驗過程

首先根據要求設計串口通信包,根據起始字段,包長度,命令碼計算CRC,設計起始位為BF AA,包長為30,命令碼分別為303132,則可以算出CRC分別為131211。在把main函數中代碼里的大串if判斷語句改寫為FSM包判斷在IAR上寫好代碼,debug調試好,再接上cc2530板子燒入,再借助串口調試助手,調好波特率,選擇hex文件,在輸入指令觀察板子亮燈情況以及顯示窗口情況。

實驗代碼

#include <iocc2530.h>

#include <string.h>

 

#define uint unsigned int

#define uchar unsigned char

 

//定義控制燈的端口

#define LED1   P1_0

#define LED2   P1_1

#define LED3   P1_4

 

void initUART0(void);

void Init_LED_IO(void);

void LED_Services(uchar code);

void sendmsg(char *data);

uint xor(uchar *data);

uint FSM(uchar *buff);

 

uchar Recdata[6];

uint  datanumber = 0;

uint  stringlen;

 

 

#define  STATE1  'a'

#define  STATE2  'b'

#define  STATE3  'c'

#define  STATE4  'd'

#define  STATE5  'e'

 

void initUART0(void)

{

  CLKCONCMD &= ~0x40;                           //設置系統時鍾源為32MHZ晶振

  while(CLKCONSTA & 0x40);                      //等待晶振穩定

  CLKCONCMD &= ~0x47;                           //設置系統主時鍾頻率為32MHZ

  PERCFG = 0x00;           //位置1 P0

  P0SEL = 0x3c;   //P0用作串口

  P2DIR &= ~0XC0;                               //P0優先作為UART0    

  U0CSR |= 0x80;   //串口設置為UART方式

  U0GCR |= 11;

  U0BAUD |= 216;   //波特率設為115200

  UTX0IF = 1;                                   //UART0 TX中斷標志初始置位1    

  U0CSR |= 0X40;   //允許接收

  IEN0 |= 0x84;  //開總中斷,接收中斷

}

 

void Init_LED_IO(void)

{

  P1DIR = 0x13;          //P10 P11 P14為輸出

  LED1 = 1;

  LED3 = 1;

  LED2 = 1; //LED

}

 

void main(void)

{

  Init_LED_IO();

  initUART0();

  while(1)

  {

 

      if(datanumber==5)

      {

        if(xor(Recdata) == 1 )

        {

          sendmsg("Accept Sucess!\r\n");

          if(FSM(Recdata) == 1)

          {

            sendmsg("Data Valid!\r\n");

            LED_Services(Recdata[3]);

            

            memset(Recdata,0,6);

            datanumber = 0;                     //指針歸0

          }

          else

          {

            sendmsg("Data Invalid!\r\n");

          }

        }

        else

        {

          sendmsg("Accept False!\r\n");

        }

      }

    

  }//while

}

 

void sendmsg(char *data)

{

  while(1)

  {

    if(*data=='\0')

      break;

    U0DBUF = *data++;

    while(UTX0IF == 0);

    UTX0IF = 0;

  }

}

 

 

 

uint xor(uchar *data)

{

  uchar temp = 0;

  for(int i=0;i<4;i++)

    temp ^= *data++;

  if(temp == *data)

    return 1;

  else

    return 0;

}

 

 

uint FSM(uchar *buff)

{

uchar state = STATE1;

uchar data;

uint flag = 0;

 

while(1)

{

data = *buff++;

switch(state)

{

case STATE1:

if(data == 0xBF)

{

state = STATE2;

}

else

  flag = 1;

break;

case STATE2:

if(data == 0xAA)

{

state = STATE3;

}

else

  flag = 1;

break;

case STATE3:

if(data == 0x36)

{

state = STATE4;

}

else

  flag = 1;

break;

case STATE4:

state = STATE5;

break;

default:

break;

}

if(state == STATE5)

{

return 1;

}

if(flag == 1)

{

break;

}

}

 

return 0;

}

 

#define  on  '0'

#define  off  '1'

#define  toggle  '2'

void LED_Services(uchar code)

{

  switch(code)

  {

  case on:

      LED1 = 0;

      LED2 = 0;

      break;

  case off:

      LED1 = 1;

      LED2 = 1;

      break;

  case toggle:

      LED1 = !LED1;

      LED2 = !LED2;

      break;

  default:

      sendmsg("NO Command Code!");

      break;

  }

}

#pragma vector = URX0_VECTOR

__interrupt void UART0_ISR(void)

{

  URX0IF = 0; //清中斷標志

  Recdata[datanumber++] = U0DBUF;

}

實驗結果 

分別輸入BF AA 36 30 13 00BF AA 36 31 12 00BF AA 36 32 11 00,三個指令,顯示端口顯示Accept Sucess!Data Invalidled燈情況依次為發亮,熄滅,發亮,若指令出錯,則led燈無現象,顯示端口顯示Accept False!

實驗總結

這次實驗碰到的主要問題是包的設計以及CRC碼的計算,通過查詢可以了解到循環冗余校驗同其他差錯檢測方式一樣,通過在要傳輸的k比特數據D后添加(n-k)比特冗余位F形成n比特的傳輸幀T,再將其發送出去可以通過模二運算求得。還有一個便是FSM處理命令包的問題,經過查詢發現它的定義有點難以理解,我理解的就是將根據條件來判斷執行的命令的狀態整合到一個包中。

通過本次實驗加深我們對於CC2530串口的理解和掌握,也讓我們初步掌握CC2530串口編程方法,但通過這次實驗收獲最大的還是通過自學來處理面對的問題的能力,比如FSM包,CRC碼這些最開始老師沒提到,通過自己查找學習來完成實驗,也鍛煉了我們獨立思考,自我學習的能力。

附錄:

UxCSR

名稱

復位

R/W

描述

7

MODE

0

R/W

USART模式選擇

0SPI模式

1UART模式

6

RE

0

R/W

啟動UART接收器。注意UART完全配置之前不能接收。

0:禁止接收器

1:使能接收器

5

SLAVE

0

R/W

SPI主或者從模式選擇

0SPI主模式

1SPI從模式

4

FE

0

R/W0

UART幀錯誤狀態

0:無幀錯誤檢測

1:字節收到不正確停止位級別

3

FRR

0

R/W0

UART奇偶校驗錯誤狀態

0:無奇偶校驗檢測

1:字節收到奇偶錯誤

2

RX_BYTE

0

R/W0

接收字節狀態,UART模式和SPI從模式。當讀U0DBUF該位自動清零,通過寫0清除它,這樣有效丟棄U0BUF中的數據

0:沒有收到字節

1:接收字節就緒

1

TX_BYTE

0

R/W0

傳送字節狀態,UARTSPI主模式

0:字節沒有傳送

1:寫到數據緩存寄存器的最后字節已經傳送

0

ACTIVE

0

R

USART傳送/接收主動狀態

0USART空閑

1USART在傳送或者接收模式忙碌

 

UxUCR

名稱

復位

R/W

描述

7

FLUSH

0

R/W1

清除單元。當設置時,該事件將會立即停止當前操作並返回單元的空閑狀態

6

FLOW

0

R/W

UART硬件流使能。用RTSCTS引腳選擇硬件流控制的使用

0:流控制禁止

1:流控制使能

5

D9

0

R/W

UART奇偶校驗位。當使能奇偶校驗,寫入D9的值決定發送的第9位的值。如果收到的第9位不匹配收到的字節的奇偶校驗,接收報告ERR

0:奇校驗

1:偶校驗

4

BIT9

0

R/W

UART9位數據使能。當該位是1時,使能奇偶校驗位傳輸即第9位。如果通過PARITY使能奇偶校驗,第9位的內容是通過D9給出的。

08位傳輸

19位傳輸

3

PARITY

0

R/W

UART奇偶校驗使能。除了為奇偶校驗設置該位用於計算,必須使能9位模式

0:禁用奇偶校驗

1:使能奇偶校驗

2

SPB

0

R/W

UART停止位數。選擇要傳送的停止位的位數

01位停止位

12位停止位

1

STOP

0

R/W

UART停止位的電平必須不同於開始位的電平

0:停止位低電平

1:停止位高電平

0

START

0

R/W

UART起始位電平,閑置線的極性采用選擇的起始位級別的電平的相反的電平

0:起始位低電平

1:起始位高電平

 

UxDBUF

名稱

復位

R/W

描述

70

DATA[70]

0x00

R/W

USART接收和傳送數據。當寫這個寄存器的時候數據被寫到內部的傳送數據寄存器,當讀取該寄存器的時候,數據來自內部讀取的數據寄存器


各波特率下寄存器值

波特率(bps

UxBAUD.BAUD_M

UxGCR.BAUD_E

誤差(%

2400

59

6

0.14

4800

59

7

0.14

9600

59

8

0.14

14400

216

8

0.03

19200

59

9

0.14

28800

216

9

0.03

38400

59

10

0.14

57600

216

10

0.03

76800

59

11

0.14

115200

216

11

0.03

230400

216

12

0.03

 


免責聲明!

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



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