ZIGBEE通讯-6.串口数据收发

UART 模式提供异步串行接口。在 UART 模式中,接口使用 2 线或者含有引脚 RXD、TXD、可选 RTS 和CTS 的 4 线。UART 模式的操作具有下列特点:

  • 8 位或者 9 位负载数据
  • 奇校验、偶校验或者无奇偶校验
  • 配置起始位和停止位电平
  • 配置 LSB 或者 MSB 首先传送
  • 独立收发中断
  • 独立收发 DMA 触发
  • 奇偶校验和帧校验错误状态

UART 模式提供全双工传送,接收器中的位同步不影响发送功能。传送一个 UART 字节包含 1 个起始位、 8个数据位、1 个作为可选项的第 9 位数据或者奇偶校验位,再加上 1 个或 2 个停止位。注意,虽然真实的数据包含 8 位或者 9 位,但是,数据传送只涉及字节。UART操作由USART控制和状态寄存器UxCSR以及UART控制寄存器UxUCR 来控制。这里的 x是USART的编号,其数值为 0或 1。

当 UxCSR.MODE 设置为 1 时,就选择了 UART 模式。

1、UART 发送

当 USART 收/发数据缓冲器、寄存器 UxDBUF 写入数据时,该字节发送到输出引脚 TXDx。UxDBUF寄存器是双缓冲的。

当字节传送开始时,UxCSR.ACTIVE 位变为高电平,而当字节传送结束时为低。当传送结束时,UxCSR.TX_BYTE位设置为 1。当 UxDBUF寄存器就绪,准备接收新的传输数据时,就产生了一个中断请求。该中断在传送开始之后立刻发生,因此,当字节正在发送时,新的字节能够装入数据缓冲器。

2、UART接收

当 1 写入 UxCSR.RE 位时,在 UART 上数据接收就开始了。然后 UART 会在输入引脚 RXDx 中寻找有效起始位,并且设置 UxCSR.ACTIVE 位为 1。当检测出有效起始位时,收到的字节就传入到接收寄存器,UxCSR.RX_BYTE位设置为 1。该操作完成时,产生接收中断。同时 UxCSR.ACTIVE 变为低电平。

通过寄存器 UxDBUF 提供收到的数据字节。当 UxDBUF 读出时,UxCSR.RX_BYTE位由硬件清 0。

3、UART硬件流控制

当 UxUCR.FLOW 位设置为 1,硬件流控制使能。然后,当接收寄存器为空而且接收使能时,RTS 输出变低。在 CTS 输入变低之前,不会发生字节传送。

4、UART特征格式

如果寄存器 UxUCR 中的 BIT9 和奇偶校验位设置为 1,那么奇偶校验产生而且检测使能。奇偶校验计算出来,作为第 9 位来传送。在接收期间,奇偶校验位计算出来而且与收到的第 9 位进行比较。如果奇偶校验出错 ,则 UxCSR.ERR 位设置为高电平。当读取 UxCSR 时,该位清除。

要传送的停止位的数量设置为 1 或者 2,这取决于寄存器位 UxUCR. SPB。接收器总是要核对一个停止位 。如果在接收期间收到的第一个停止位不是期望的停止位电平,就通过设置寄存器位 UxCSR.FE 为高电平,发出帧出错信号。当读取 UxCSR 时,UxCSR.FE 位清除,当 UxCSR.SPB 设置为 1 时,接收器将核对两个停止位。注意当检测到第一个停止位正确时,将设置 RX 中断。如果第二个停止位不正确,设置帧误码位UxCSR.FE时将有一个延迟 。这个延迟与波特率有关(位持续时间)。

5、波特率产生

当运行在 UART 模式时,内部的波特率发生器设置 UART 波特率。当运行在 SPI 模式时,内部的波特率发生器设置 SPI 主时钟频率。

由寄存器 UxBAUD.BAUD_M[7:0]和 UxGCR.BAUD_E[4:0]定义波特率。该波特率用于 UART 传送,也用于 SPI 传送的串行时钟速率。波特率由下式给出:

在公式中f 是系统时钟频率,等于 16 MHz RCOSC 或者 32 MHz XOSC。标准波特率所需的寄存器值如图2-6-2 所示。该图适用于典型的 32 MHz 系统时钟。真实波特率与标准波特率之间的误差,用百分数表示。

当 BAUD_E 等于 16 且 BAUD_M 等于 0 时,UART 模式的最大波特率是 f/16 且 f 是系统时钟频率。

注意波特率必须通过 UxBAUD 和寄存器 UxGCR 在任何其他 UART 和 SPI 操作发生之前设置。这意味着使用这个信息的定时器不会更新,直到它完成它的起始条件,因此改变波特率是需要时间的。

 6、清除USART

通过设置寄存器位 UxUCR.FLUSH 可以取消当前的操作。这一事件会立即停止当前操作并且清除全部数据缓冲器。应注意在 TX/RX 位中间设置清除位,清除将不会发生,直到这个位结束(缓冲将被立即清除但是知道位持续时间的定时器不会被清除)。因此使用清除位应符合 USART 中断,或在 USART 可以接收更新的数据或配置之前,使用当前波特率的等待时间位。

7、USART中断

每个 USART 都有两个中断:RX 完成中断(URXx)和 TX 完成中断(UTXx)。当传输开始触发 TX 中断,且数据缓冲区被卸载。

USART的中断使能位在寄存器 IEN0 和寄存器 IEN2 中,中断标志位在寄存器 TCON和寄存器 IRCON2 中 。关于这些寄存器的详细信息见 数据手册2.5 节。中断使能和标志总结如下。

中断使能:

  • USART0 RX: IEN0.URX0IE
  • USART1 RX: IEN0.URX1IE
  • USART0 TX: IEN2.UTX0IE
  • USART1 TX: IEN2.UTX1IE

中断标记:

  • USART0 RX: TCON.URX0IF
  • USART1 RX: TCON.URX1IF
  • USART0 TX: IRCON2.UTX0IF
  • USART1 TX: IRCON2.UTX1IF

8、USART  DMA 触发

有两个 DMA 触发与每个 USART 相关。DMA 触发由事件 RX 或者 TX 完成激活,也就是说,与USART的中断请求事件相同。可以配置 DMA 通道使用 USART 收/发缓冲器即 UxDBUF作为它的源地址或者目标地址。

CC2530芯片有两个串行接口UART0和UART1:

UART0对应RXD(P02)、TXD(P03);

UART1对应RXD(P04)、TXD(P05);

根据开发板硬件原理图确定开发板用到的是哪个串口,如图所示。

 从图中可以看出,USART的发送与接收引脚分别是核心板的6、7引脚上,J22中引脚编号与核心板引脚对应编号为1-12对应13-24,下面继续查看引脚对照表,确定所用USART所用IO口。

 根据引脚对照表,确定USART的发送引脚为P0.3,接收引脚为P0.2。也就是说,开发板的串口用到的是USART0。想要使用USART0,需要配置相应的寄存器,使用到的寄存器如图所示。

PERCFG (0xF1) –外设控制寄存器

位0配置USART0的备用位置

P0SEL (0xF3)–端口0功能选择寄存器

0:通用IO;1:外设功能

U0CSR (0x86) - USART 0 控制和状态寄存器

位7配置UART模式

位6配置接收器使能

U0UCR (0xC4) - USART 0 UART 控制寄存器

使用经典串口配置,默认值

U0GCR (0xC5) - USART 0 通用控制寄存器

位4:0配置波特率指数值BAUD_E

U0BAUD (0xC2) - USART 0 波特率控制寄存器

配置波特率小数部分的值

IEN0 (0xA8) – 中断使能 0

位7配置总中断使能

位2配置USART0接收中断使能

根据实验原理,在32MHz系统时钟下将串口波特率配置位115200,打开串口接收中断,在中断中接收数据,并将就收到的数据发送出去。在main.c中编写如下代码,实现串口收发。

#include <ioCC2530.h>

/****************************
//32M时钟频率实现函数
*****************************/
void System_Clock_32M()
{
    CLKCONCMD &= ~0x40; // 1011 1111 让32M晶振工作
    while(CLKCONSTA & 0x40); // 0100 0000  等待晶振稳定
    CLKCONCMD &= ~0x07; // 1111 1000   不分频的供给CPU
}

/****************************
//串口初始化实现函数
*****************************/
void UART_Init()
{
  PERCFG &= ~0x01; // 1111 1110 把零位清零 选择备用位置1 即P0_2  P0_3
  P0SEL |= 0x0C; // 0000 1100 设置P0_2 P0_3为片上外设模式 
  U0CSR |= 0xC0; // 1100 0000 设置为UART模式 使能接收器
  U0UCR |= 0; // 串口0 典型配置,禁用流控、禁止奇偶校验位、8位数据位、1位停止位
  U0GCR = 11; // 设置BAUD_E为11
  U0BAUD = 216;// 设置BAUD_M为216 得出波特率为115200
  IEN0 |= 0x84; // 1000 0100 开总中断 接收中断
}

/****************************
//串口发送数据实现函数
*****************************/
void UART_Send(char* buf, int length)
{
  for(int i=0; i<length; i++)
  {
    U0DBUF = buf[i];  // 把收数据放入发送寄存器
    while( UTX0IF==0 ); // 等待发送完成
    UTX0IF = 0; // 清发送完成标志
  }    
}

void main(void)
{
  char string[] = "hello world!";
  System_Clock_32M(); // 将系统时钟切换为32M
  UART_Init(); // 串口初始化  
  UART_Send(string, sizeof(string)); // 发送字符串
  while(1);
}

#pragma vector=URX0_VECTOR
__interrupt void uart0()
{
    URX0IF = 0; // 清中断接收标志
    char data = U0DBUF; // 从数据缓冲器拿到数据
    U0DBUF = data;  // 把收到的数据通过串口再返回发出去
    while( UTX0IF==0 ); // 等待发送完成
    UTX0IF = 0; // 清发送完成标志
}

 

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值