感知层编程实验三

南昌航空大学实验报告

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

 

posted @   安良  阅读(903)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示