CC2530串口通讯的实现

一、串口通讯简介

        同步通信:在发送数据信号的时候,会同时送出一根同步时钟信号, 用来同步发送方和接收方的数据采样频率。

        异步通信:数据发送方和数据接收方没有同步时钟,只有数据信号线,只不过发送端和接收端会按照协商好的协议(固定频率)来进行数据采样。

        USART:  全称Universal Synchronous Asynchronous Receiver and Transmitter(通用同步异步收发器)是一个串行通信设备,可以灵活地与外部设备进行全双工数据交换。

        UART: 与USART裁剪掉了同步的功能,只要采用相同的帧格式和波特率,就能在未共享时钟信号的情况下,仅用两根信号线(Rx和Tx) 就可以完成通信过程,因此也称为异步串行通信。

串口通讯帧格式:

① 空闲位:当线路上没有数据的时候,电平处于逻辑'1'。
② 起始位:发送一位逻辑'0',数据开始传输
③ 数据位:常见的是8位的数据,数据低位在前。
④ 校验位:校验位通常存在于数据位的下一位,当数据位加上这一位后,如果是奇校验则1的位数是奇数,相反则1的位数为偶数。
⑤ 停止位:是一个字符数据的结束位,通常是1位、1.5位或者2位的高电平。

二、 CC2530串口寄存器介绍

        ① U0CSR:控制和状态寄存器

        Bit7: 设置为1,为UART模式
        Bit6: 设置为1,接收器使能

        ② U0UCR:控制寄存器

        Bit6: 设置为0,禁止流控 
        Bit4: 设置为0,传输数据长度为8位
        Bit3: 设置为0,禁用奇偶校验功能
        Bit2: 设置为0,1位停止位

        ③ U0BUF:接收/传送数据缓存寄存器

        ④ U0GCR、U0BAUD:通用控制核波特率控制寄存器 

        U0GCR寄存器的低5位和U0BAUD寄存器的8位共同决定通讯的波特率大小,下面给出常用波特率配置表:

        ⑤ PERCFG:外设控制寄存器 

        通过该寄存器的Bit0可以决定串口0使用的管脚位置。

        ⑥ P2DIR:外设优先级控制

        P0优先作为UART0,所以设置bite[7:6]为00

三、代码实现     

#include <ioCC2530.h>
#include <string.h>


typedef unsigned char uchar;
typedef unsigned int  uint;


#define UART0_RX    1
#define UART0_TX    2
#define SIZE       51

char RxBuf;
char UartState;
uchar count;
char RxData[SIZE];        //存储发送字符串

//32MHZ晶振ms延时函数
void DelayMS(uint msec)
{ 
    uint i,j;
    
    for (i=0; i<msec; i++)
        for (j=0; j<1070; j++);
}

//串口寄存器初始化
void InitUart(void)
{
  PERCFG = 0x00;       //外设控制寄存器 USART 0的IO位置:0为P0口位置1 
  P0SEL = 0x0c;        //P0_2,P0_3用作(外设功能)
  P2DIR &= ~0xC0;// 1100 0000 将外设设置为串口0优先
  U0UCR = 0x00; //禁止流控制 8位数据传输 禁止奇偶校验 1位停止位
  U0CSR |= 0x80;           //设置为UART模式
  
  U0GCR |= 11;	//设置数据LSB和波特率
  U0BAUD |= 216;           //波特率设为115200
  
  UTX0IF = 0;              //UART0 TX中断标志初始置位0
  U0CSR |= 0x40;           //允许接收 
  IEN0 |= 0x84;            //开总中断允许接收中断
}

//串口发送函数
//string:发送的字符串
//len:发送的数据长度
void UartSend_string(char *Data, int len)
{
  uint i;
  for(i = 0;i < len;i++) {
   U0DBUF = *Data++; 
   while(UTX0IF == 0);//等待发送完成
   UTX0IF = 0;  //发送中断标志位置0
  }
  
}

//接收中断处理函数
#pragma vector = URX0_VECTOR 
__interrupt void UART0_ISR(void) 
{ 
    URX0IF = 0;       // 清中断标志 
    RxBuf = U0DBUF;                           
}


void main(void)
{	
	
    CLKCONCMD &= ~0x40;                        //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);                   //等待晶振稳定为32M
    CLKCONCMD &= ~0x47;                        //设置系统主时钟频率为32MHZ   
   
    InitUart();                                //调用串口初始化函数   
    UartState = UART0_RX;                      //串口0默认处于接收模式
    memset(RxData, 0, SIZE);
    
    while(1)
    {
        if(UartState == UART0_RX)              //接收状态 
        { 
            if(RxBuf != 0) 
            {                 
                if((RxBuf != '#')&&(count < 50))//以'#'为结束符,一次最多接收50个字符            
                    RxData[count++] = RxBuf; 
                else
                {
                    if(count >= 50)             //判断数据合法性,防止溢出
                    {
                        count = 0;              //计数清0
                        memset(RxData, 0, SIZE);//清空接收缓冲区
                    }
                    else
                        UartState = UART0_TX;  //进入发送状态 
                }
                RxBuf  = 0;
            }
        }
        
        if(UartState == UART0_TX)              //发送状态 
        {                         
            U0CSR &= ~0x40;                    //禁止接收 
            UartSend_string(RxData, count);     //发送已记录的字符串。
            U0CSR |= 0x40;                     //允许接收 
            UartState = UART0_RX;              //恢复到接收状态 
            count = 0;                         //计数清0
            memset(RxData, 0, SIZE);           //清空接收缓冲区
        }    
    }
}

        代码流程:

① 初始化晶振模式
② 串口寄存器初始化
③ 将串口设置为接收模式,进入while循环
④  串口接收主机发送的数据,并且数据长度不超过50,并且数据以#结尾将串口设置为发送模式,并把数据发送给主机。
⑤ 如果接收数据异常,则清空接收缓冲区。

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值