CC2530之串口

本次实验,主要与CC2530的串口相关。
串口电路图如下所示
PL2303.jpg
首先,先介绍一下CC2530的外设I/O引脚映射,如下图所示,每个外设单元对应两组可以选择的I/O引脚。而外设I/O位置的选择使用由寄存器PERCFG来控制,其中bit1和bit0决定UART1和UART0的位置,0表示外设位置1,1表示外设位置2.

PERCFG |= 0x00;//设置UART0为外设位置1
P0SEL |= 0x0c;//设置P0_2和P0_3作为串口

Peripheral IO Pin Mapping.jpg
PERCFG.jpg
由映射表可知,I/O映射可能存在冲突,可以通过设置优先级来解决冲突,与优先级设置相关的寄存器是P2SEL和P2DIR.

P2SEL |= 0x40; //端口1UART0优先
P2DIR &= ~0xc0;//端口0UART0为第1优先级

P2SEL.jpg
P2DIR.jpg

接下来介绍与UART0相关的寄存器

  1. USART0控制与状态寄存器。
U0CSR |= 0x80;//将USART模式选择为UART模式
U0CSR |= 0x40;//使能UART接收器

U0CSR.jpg

  1. USART0生成控制寄存器和USART0波特率控制寄存器两者共同决定串口的波特率。
//假设系统时钟为32MHz,设置串口波特率为115200
U0GCR |= 11;  
U0BAUD |= 216;

U0GCR.jpg
U0BAUD.jpg
Baud Rate.jpg
Baud-Rate Settings tables.jpg

  1. 时钟控制命令寄存器。
CLKCONCMD &= ~0x40; //设置系统时钟源为32MHz晶振
CLKCONCMD &= ~0x47; //设置系统时钟为32MHz

CLKCONCMD.jpg

  1. 时钟状态控制寄存器。
while(CLKCONCMD & 0x40);//等待晶振稳定为32MHz

CLKCONSTA.jpg

  1. USART0接收/发送数据缓冲寄存器
    U0DBUF.jpg

  2. 中断标志寄存器5
    bit2和bit1分别是USART1和USART0的中断标志位
    IRCON2.jpg

/*CC2530通过串口发送数据到PC端,由PC端的串口助手打印显示出来*/
#include <ioCC2530.h>
#include <string.h>

typedef unsigned char uchar;
typedef unsigned int uint;

#define TX_SIZE  15
#define TX_STRING "ZIGBEE IOT  "

char TX_DATA[TX_SIZE];

void delay_ms(uint ms)
{
  uint i,j;
  for(i=0;i<ms;i++)
    for(j=0;j<555;j++);
}

void USART0Init(void)
{
  PERCFG |= 0x00;//设置UART0为外设位置1
  P0SEL |= 0x0c;//设置P0_2和P0_3作为串口
  P2DIR &= ~0xc0;//端口0UART0为第1优先级
  U0CSR |= 0x80; //选择UART模式
  U0CSR |= 0x40; //使能接收器
  U0GCR |= 11;  
 //设置波特率为115200
  U0BAUD |= 216;
  UTX0IF = 0; //UART0 TX中断标志位初始化为0
}

//通过串口发送一串字符
void USART0_SendString(char *data,uint length) 
{
  uint i;
  for(i=0;i<length;i++)
  {
    U0DBUF = *data++;
    while(UTX0IF ==0);
    UTX0IF = 0;
  }
}

void main(void)
{
  CLKCONCMD &= ~0x40; //选择32MHz晶振为系统时钟源
  while(CLKCONSTA & 0x40); //等待晶振稳定为32MHz
  CLKCONCMD &= ~0x47;//设置系统时钟为32MHz

  USART0Init();
  memset(TX_DATA,0,TX_SIZE);  //将数组TX_DATA清0
  memcpy(TX_DATA,TX_STRING,sizeof(TX_STRING)); //将TX_STRING保存到数组TX_DATA

  while(1)
  {
    USART0_SendString(TX_DATA,sizeof(TX_STRING));
    delay_ms(1000);
  }
}
/*在USART0实现字符的收发,CC2530从PC端的串口助手接收数据,然后CC2530再将接受到的数据发送回PC端*/
#include <ioCC2530.h>
#include <string.h>

typedef unsigned char uchar;
typedef unsigned int uint;

#define UART0_RX  0  //接收状态
#define UART0_TX  1  //发送状态
#define RX_SIZE   100  //数据接收缓冲区大小

char RX_BUF; //单个数据接收缓冲区
char UART0_Status;  //USART0的状态标志量
char RX_DATA[RX_SIZE];  //数据接收缓冲区
uchar count;  //计数器

void delay_ms(uint ms)
{
  uint i,j;
  for(i=0;i<ms;i++)
    for(j=0;j<555;j++);
}

void USART0Init(void)
{
  PERCFG &= ~0x01; //设置USART0的IO位置为端口0的位置1
  P0SEL |= 0x0c; //将P0_2,P0_3设置为外设引脚,即USART0的引脚
  P2DIR &= ~0xc0; //将端口0的USART0设置位第1优先级

  U0CSR |= 0x80;//将USART设置为UART模式
  U0GCR |= 11;   //将波特率设置为115200
  U0BAUD |= 216;

  UTX0IF = 0; //将USART0 TX中断标志位初始化为0
  U0CSR |= 0x40; //使能接收器

  URX0IE = 1;  //使能USART0的接收中断
  EA = 1;   //打开总中断
}

/*发送字符串*/
void USART0_SendString(char *data,uint length)
{
  uint i;
  for(i=0;i<length;i++)
  {
    U0DBUF = *data++;  //将待发送字符加载到U0DBUF寄存器
    while(UTX0IF ==0); //等待该字节发送完成
    UTX0IF = 0;  //将中断标志重置为0
  }
}

/*UART RX中断*/
#pragma vector = URX0_VECTOR
__interrupt void UART0_ISR(void)
{
  URX0IF = 0;      //将接收中断标志重置为0
  RX_BUF = U0DBUF;  //将U0DBUF寄存器接受到的数据保存至RX_BUF
}

void main(void)
{
  CLKCONCMD &= ~0x40;//选择32MHz的晶振作为时钟源
  while(CLKCONSTA & 0x40);//等待晶振稳定
  CLKCONCMD &= ~0x47;//设置系统时钟为32MHz

  USART0Init();  //初始化串口
  UART0_Status = UART0_RX;

  memset(RX_DATA,0,RX_SIZE);
  while(1)
  {
    if(UART0_Status==UART0_RX)  //UART处于接收状态
    {
      if(RX_BUF != 0) 
      {
        if((RX_BUF != '!')&&(count < RX_SIZE))  //以'!'为结束符,一次最多接收RX_SIZE个字符
          RX_DATA[count++] = RX_BUF;
        else
        {
          if(count >= RX_SIZE)
          {
            count = 0;
            memset(RX_DATA,0,RX_SIZE);
          }else
          {
            UART0_Status = UART0_TX;
          }
        }    
        RX_BUF = 0;
       }
     }
    if(UART0_Status==UART0_TX) //UART处于发送状态
    {
      U0CSR &= ~0x40;  //禁用接收器
      USART0_SendString(RX_DATA,count);//发送字符串
      U0CSR |= 0x40;  //使能接收器
      UART0_Status = UART0_RX;
      count = 0; //重置计数器
      memset(RX_DATA,0,RX_SIZE);//数据接收缓冲区清0
    }
   } 
}
  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值