Zigbee点灯3(串口)

USART0和USART1是串行通信接口,它们能够分别运行于异步UART模式或者同步SPI 模式。两个 USART具有同样的功能,可以设置在单独的 I/O 引脚。

1、UART模式

在这里插入图片描述

UART 发送
当 USART 收/发数据缓冲器、寄存器 UxBUF 写入数据时,该字节发送到输出引脚 TXDx。UxBUF 寄存器是双缓冲的。
当字节传送开始时,UxCSR.ACTIVE 位变为高电平,当字节传送结束时为低。
当传送结束时,UxCSR.TX_BYTE 位设置为 1。
当 USART 收/发数据缓冲寄存器就绪,准备接收新的发送数据时,就产生了一个中断请求。该中断在传送开始之后立刻发生,因此,当字节正在发送时,新的字节能够装入数据缓冲器。
UART 接收
当 1 写入 UxCSR.RE 位时,在 UART 上数据接收就开始了。
然后 UART 会在输入引脚 RXDx 中寻找有效起始位,并设UxCSR.ACTIVE 位为 1。
当检测出有效起始位时,收到的字节就传入到接收寄存器UxCSR.RX_BYTE 位设置为 1。
该操作完成时,产生接收中断。同时 UxCSR.ACTIVE 变为低电平。
通过寄存器 UxBUF 提供收到的数据字节。
当 UxBUF 读出时,UxCSR.RX_BYTE 位由硬件清 0

2、SPI模式

在这里插入图片描述
在这里插入图片描述
SPI 主模式操作
当寄存器 UxBUF 写入字节后,SPI 主模式字节传送就开始了。
USART 使用波特率发生器生成 SCK 串行时钟,而且传送发送寄存器提供的字节到输出引脚 MOSI。与此同时,接收寄存器从输入引脚 MISO
获取收到的字节。
当传送开始 UxCSR.ACTIVE 位变高,而当传送结束后,UxCSR.ACTIVE 位变低。当传送结束时,UxCSR.TX_BYTE 位设置为 1。
串行时钟 SCK 的极性由 UxGCR.CPOL 位选择,其相位由 UxCSR.CPHA 位选择。
字节传送的顺序由UxCSR.ORDER 位选择。
传送结束时,收到的数据字节由 UxBUF 提供读取。
当这个新的数据在 UxDBUF USART 接收/发送数据寄存器中准备好,就产生一个接收中断。
当单元就绪接收另一个字节用来发送时,发送中断产生。由于 UxBUF 是双缓冲,这个操作刚好在发送开始时就发生了。
注意数据不应写入 UxDBUF,直到 UxCSR.TX_BYTE 是 1。对于 DMA 传输这是自动处理的。
对于使用 DMA 的背对背传输,如果传输字节不能被损坏,UxGDR.CPHA 位必须设置为 0。对于需要设置UxGDR.CPHA 的系统,需要轮询UxCSR.TX_BYTE。
还要注意发送中断和接收中断的区别,因为前者比后者大约提前 8 位周期到达。如上所述的 SPI 主模式操作是一个 3 线接口。不选择输入用于使能主模式。如果外部从模式需要一个从模式选择信号,这可以使用一个通用 I/O 引脚通过软件实现。
SPI 从模式操作
SPI 从模式字节传送由外部系统控制。输入引脚 MISO 上的数据传送到接收寄存器,该寄存器由串行时钟SCK 控制。SCK 为从模式输入。与此同时,发送寄存器中的字节传送到输出引脚 MOSI。
当传送开始时 UxCSR.ACTIVE 位变高,而当传送结束后,UxCSR.ACTIVE 位变低。当传送结束时,UxCSR.RX_BYTE 位设置为 1,接收中断产生。
串行时钟 SCK 的极性由 UxCSR.CPOL 位选择,其相位由 UxGCR.CPHA 位选择。字节传送的顺序由UxGCR.ORDER 位选择。
传送结束时,收到的数据字节由 UxBUF 提供读取。
当 SPI 从模式操作开始时,发送中断。

3、SSN 从模式选择引脚

当 USART 运行在 SPI 模式,配置为 SPI 从模式,从模式选择(SSN)引脚使用一个 4 线接口来作为 SPI的输入(边沿控制)。
SSN 的下降沿,SPI 从模式活跃,在 MOSI 输入上接收数据,在 MOSI 输出上输出数据。
SSN 的上升沿,SPI 从模式不活跃,不接收数据。
还要注意 SSN 上升沿之后 MISO 输出不是三态。还要注意释 放 SSN(SSN 变为高电平)必须在字节接收或发送结束。如果在字节中间释放,下一个要接收的字节将不能正确接收,因为关于之前字节的信息在 SPI 系统中。USART 清除能用于删除这个信息。
在 SPI 主模式中,不使用 SSN 引脚。当 USART 运行在 SPI 主模式,外部 SPI 从模式设备需要提供一个从模式选择信号,然后一个通用 I/O 引脚应在软件方面作为从模式选择信号功能。

4、波特率

当运行在 UART 模式时,内部的波特率发生器设置 UART 波特率。
当运行在 SPI 模式时,内部的波特率发生器设置 SPI 主时钟频率。
由寄存器 UxBAUD.BAUD_M[7:0]和 UxGCR.BAUD_E[4:0]定义波特率。该波特率用于 UART 传送,也用于 SPI 传送的串行时钟速率。波特率由下式给出:
在这里插入图片描述
式中:F 是系统时钟频率,等于 16 MHz RCOSC 或者 32 MHz XOSC。
标准波特率所需的寄存器值如表 16-1 所列。该表适用于典型的 32 MHz 系统时钟。真实波特率与标准波特率之间的误差,用百分数表示。
当 BAUD_E 等于 16 且 BAUD_M 等于 0 时,UART 模式的最大波特率是 F/16 且 F 是系统时钟频率。
SPI 模式下的最大波特率见设备数据手册。
注意波特率必须通过 UxBAUD 和寄存器 UxGCR 在任何其他 UART 和 SPI 操作发生之前设置。这意味着使用这个信息的定时器不会更新,直到它完成它的起始条件,因此改变波特率是需要时间的.
在这里插入图片描述

5、USART寄存器

对于每个USART有五个寄存器
● UxCSR: USARTx 控制和状态;
● UxUCR: USARTx UART 控制;
● UxGCR: USARTx 通用控制
● UxBUF: USARTx 接收/发送数据缓冲
● UxBAUD:USARTx 波特率控制

配置串口的一些步骤
1、首先配置IO口,将IO口设定为外部设备的串口功能
2、再配置USART的相应的寄存器,U0CSR设置模式(UART、SPI主从模式,还有一些差错检验传输什么的)。U0GCR通用控制(一些时钟位,波特率)。U0BAUD小数部分的波特率的值。U0XTIF中断标志位。

U0CSR在这里插入图片描述
U0GCR
在这里插入图片描述
U0BUF
在这里插入图片描述
U0BAUD
在这里插入图片描述
U0UCR
在这里插入图片描述
UTX0IF
在这里插入图片描述
CLKCONCMD
在这里插入图片描述

实验1 串口调试 cc2530发送hello world

/***
*** 串口获取cc2530发送hello world
*** 波特率为115200bps 8N1
**/
#include <ioCC2530.h>
#include <string.h>


char TXData[20];  //存储要发送的字符串

/**********延时函数***********/
void Delayms(int ms)
{
  int i,j;
  for(i = 0;i < ms;i++)
    for(j = 0;j < 1070;j++);
}

/**********串口初始化函数***********/
void InitUart(void)
{
  CLKCONCMD &= ~0x40; //设置系统时钟源
  while(CLKCONSTA & 0x40); //等待晶振稳定
  CLKCONCMD &= ~0x47;  //设置系统主时钟频率
  
  PERCFG = 0x00; //使用备用位置1 P0_2 P0_3
  P0SEL = 0x0c;  //P0_2 P0_3用作外设
  U0CSR |= 0x80; //1000 0000 设置UART模式
  U0GCR |= 11;
  U0BAUD |= 216; //根据查表可以知道 波特率115200
  UTX0IF = 0;  //中断标志位置0
}

/****************串口发送字符串函数**********************/
void UartSendString(char *Data,int len)
{
  int i;
  for(i = 0;i<len;i++){
    U0DBUF = *Data++;
    while(UTX0IF == 0);
    UTX0IF = 0;
  }
}
/****************主函数*********************************/
void main(void)
{
  InitUart();
  
  strcpy(TXData,"hello world");
  while(1)
  {
    UartSendString(TXData,sizeof("hello world"));
    Delayms(1000);
  }
}

此时ZigBee的板子首先要连接模拟器把代码下进去,然后去掉模拟器用USB口连接。再打开串口助手。
在这里插入图片描述

实验2 从串口发送字符

控制学习板上的LED灯。发送1,LED1亮,发送2,LED2亮,发送3,LED1灭,发送4,LED2灭。以#字符结束。

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

typedef unsigned char uchar;
typedef unsigned int  uint;

#define UART0_RX    1
#define UART0_TX    2
#define CONTROL_LED 3
#define SIZE        3
#define LED1        P1_0   //定义P1.0口为LED1控制端
#define LED2        P1_1   //定义P1.1口为LED2控制端

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

/****************************************************************************
延时函数
****************************************************************************/
void DelayMS(uint msec)
{ 
    uint i,j;
    
    for (i=0; i<msec; i++)
        for (j=0; j<1070; j++);
}

/****************************************************************************
灯初始化
****************************************************************************/
void InitLed(void)
{
    P1DIR |= 0x03;               //P1.0和P1.1定义为输出口
}

/****************************************************************************
串口初始化
****************************************************************************/
void InitUart(void)
{ 
    CLKCONCMD &= ~0x40;                        //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);                   //等待晶振稳定为32M
    CLKCONCMD &= ~0x47;                        //设置系统主时钟频率为32MHZ   
    
  
    PERCFG = 0x00;           //外设控制寄存器 USART 0的IO位置:0为P0口位置1 
    P0SEL = 0x0c;            //P0_2,P0_3用作串口(外设功能)
    P0DIR &= ~0xC0;          //P0优先作为UART0
    
    U0CSR |= 0x80;           //设置为UART方式
    U0GCR |= 11;				       
    U0BAUD |= 216;           //波特率设为115200
    UTX0IF = 0;              //UART0 TX中断标志初始置位0
    U0CSR |= 0x40;           //允许接收 
    IEN0 |= 0x84;            //开总中断允许接收中断  
}

/****************************************************************************
串口发送函数
****************************************************************************/
void UartSendString(char *Data, int len)
{
    uint i;
    
    for(i=0; i<len; i++)
    {
        U0DBUF = *Data++;
        while(UTX0IF == 0);
        UTX0IF = 0;
    }
}

/****************************************************************************
* 名    称: UART0_ISR(void) 串口中断处理函数 
* 描    述: 当串口0产生接收中断,将收到的数据保存在RxBuf中
****************************************************************************/
#pragma vector = URX0_VECTOR 
__interrupt void UART0_ISR(void) 
{ 
    URX0IF = 0;       // 清中断标志 
    RxBuf = U0DBUF;                           
}


/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void)
{	
    InitLed();                                 //设置LED灯相应的IO口
    InitUart();                                //串口初始化函数   
    UartState = UART0_RX;                      //串口0默认处于接收模式
    memset(RxData, 0, SIZE);
    
    while(1)
    {
        if(UartState == UART0_RX)              //接收状态 
        { 
            if(RxBuf != 0) 
            {                 
                if((RxBuf != '#')&&(count < 2))//以'#'为结束符          
                    RxData[count++] = RxBuf; 
                else
                {
                    if(count >= 2)             //判断数据合法性,防止溢出
                    {
                        count = 0;              //计数清0
                        memset(RxData, 0, SIZE);//清空接收缓冲区
                    }
                    else
                        UartState = CONTROL_LED;//进入发送状态 
                }
                RxBuf  = 0;
            }
        }
        
        if(UartState == CONTROL_LED)            //控制LED灯 
        {
            //判断接收的数据合法性
            if((RxData[0]=='1'||RxData[0]=='2'))
            {
                if(RxData[0]=='1')
                    LED1 =0;               //低电平点亮
                else
                    LED2 =0;
            }
            else if((RxData[0]=='3'||RxData[0]=='4'))
            {
                if(RxData[0]=='3')
                {
                    LED1 = 1;
                    
                }
                else
                {
                    LED2 = 1;
                }
            }
            
            UartState = UART0_RX;
            count = 0;               
            memset(RxData, 0, SIZE);           //清空接收缓冲区
        }
    }
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值