[Zigbee] 8、ZigBee之UART剖析·二(串口收发)

[复制链接]
1566|35
 楼主| programmable 发表于 2020-1-11 17:21 | 显示全部楼层 |阅读模式
前言:上一节讲UART基本知识介绍完了,并深入剖析了一个串口发送工程,本节将进一步介绍串口收发!

1、初始化
在串口初始化部分,和上一节不同的地方是:
51     U0CSR |= 0x40;           //允许接收  52     IEN0 |= 0x84;            //开总中断允许接收中断  
第51行使能接收数据,上一节介绍的仅仅是发送,所以没有这一句配置:
第51行开总中断和UART0中断:

 楼主| programmable 发表于 2020-1-11 17:21 | 显示全部楼层
  1. /****************************************************************************
  2. * 文 件 名: main.c
  3. * 描    述: 设置串口调试助手波特率:115200bps 8N1
  4. *           串口调试助手给CC2530发字符串时,开发板会返回接收到的字符串
  5. ****************************************************************************/
  6. #include <ioCC2530.h>
  7. #include <string.h>

  8. typedef unsigned char uchar;
  9. typedef unsigned int  uint;

  10. #define UART0_RX    1
  11. #define UART0_TX    2
  12. #define SIZE       51

  13. char RxBuf;
  14. char UartState;
  15. uchar count;
  16. char RxData[SIZE];        //存储发送字符串

  17. /****************************************************************************
  18. * 名    称: DelayMS()
  19. * 功    能: 以毫秒为单位延时
  20. * 入口参数: msec 延时参数,值越大,延时越久
  21. * 出口参数: 无
  22. ****************************************************************************/
  23. void DelayMS(uint msec)
  24. {
  25.     uint i,j;
  26.    
  27.     for (i=0; i<msec; i++)
  28.         for (j=0; j<1070; j++);
  29. }

  30. /****************************************************************************
  31. * 名    称: InitUart()
  32. * 功    能: 串口初始化函数
  33. * 入口参数: 无
  34. * 出口参数: 无
  35. ****************************************************************************/
  36. void InitUart(void)
  37. {
  38.     PERCFG = 0x00;           //外设控制寄存器 USART 0的IO位置:0为P0口位置1
  39.     P0SEL = 0x0c;            //P0_2,P0_3用作串口(外设功能)
  40.     P2DIR &= ~0xC0;          //P0优先作为UART0
  41.    
  42.     U0CSR |= 0x80;           //设置为UART方式
  43.     U0GCR |= 11;                       
  44.     U0BAUD |= 216;           //波特率设为115200
  45.     UTX0IF = 0;              //UART0 TX中断标志初始置位0
  46.     U0CSR |= 0x40;           //允许接收
  47.     IEN0 |= 0x84;            //开总中断允许接收中断  
  48. }

  49. /****************************************************************************
  50. * 名    称: UartSendString()
  51. * 功    能: 串口发送函数
  52. * 入口参数: Data:发送缓冲区   len:发送长度
  53. * 出口参数: 无
  54. ****************************************************************************/
  55. void UartSendString(char *Data, int len)
  56. {
  57.     uint i;
  58.    
  59.     for(i=0; i<len; i++)
  60.     {
  61.         U0DBUF = *Data++;
  62.         while(UTX0IF == 0);
  63.         UTX0IF = 0;
  64.     }
  65. }

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


  76. /****************************************************************************
  77. * 程序入口函数
  78. ****************************************************************************/
  79. void main(void)
  80. {   
  81.     CLKCONCMD &= ~0x40;                        //设置系统时钟源为32MHZ晶振
  82.     while(CLKCONSTA & 0x40);                   //等待晶振稳定为32M
  83.     CLKCONCMD &= ~0x47;                        //设置系统主时钟频率为32MHZ   
  84.    
  85.     InitUart();                                //调用串口初始化函数   
  86.     UartState = UART0_RX;                      //串口0默认处于接收模式
  87.     memset(RxData, 0, SIZE);
  88.    
  89.     while(1)
  90.     {
  91.         if(UartState == UART0_RX)              //接收状态
  92.         {
  93.             if(RxBuf != 0)
  94.             {                 
  95.                 if((RxBuf != '#')&&(count < 50))//以'#'为结束符,一次最多接收50个字符            
  96.                     RxData[count++] = RxBuf;
  97.                 else
  98.                 {
  99.                     if(count >= 50)             //判断数据合法性,防止溢出
  100.                     {
  101.                         count = 0;              //计数清0
  102.                         memset(RxData, 0, SIZE);//清空接收缓冲区
  103.                     }
  104.                     else
  105.                         UartState = UART0_TX;  //进入发送状态
  106.                 }
  107.                 RxBuf  = 0;
  108.             }
  109.         }
  110.         
  111.         if(UartState == UART0_TX)              //发送状态
  112.         {                        
  113.             U0CSR &= ~0x40;                    //禁止接收
  114.             UartSendString(RxData, count);     //发送已记录的字符串。
  115.             U0CSR |= 0x40;                     //允许接收
  116.             UartState = UART0_RX;              //恢复到接收状态
  117.             count = 0;                         //计数清0
  118.             memset(RxData, 0, SIZE);           //清空接收缓冲区
  119.         }   
  120.     }
  121. }
 楼主| programmable 发表于 2020-1-11 17:22 | 显示全部楼层
2、中断回调函数

第77~82行是UART0中断处理函数,每次有数据从上位机发送下来都会触发该函数执行,在概述内将上位机发送来的数据保存在RxBuf中:

77 #pragma vector = URX0_VECTOR
78 __interrupt void UART0_ISR(void)
79 {
80     URX0IF = 0;       // 清中断标志
81     RxBuf = U0DBUF;                           
82 }
 楼主| programmable 发表于 2020-1-11 17:22 | 显示全部楼层
3、main函数流程

串口初始状态为接收状态,其中100-118行把中断处理函数中暂存的接收数据RxBuf转存到RxData数组中,接收过程中发现结束标志位则将状态转换为发送状态,则120~128行发送数据的代码段将被执行:

120         if(UartState == UART0_TX)              //发送状态
121         {                        
122             U0CSR &= ~0x40;                    //禁止接收
123             UartSendString(RxData, count);     //发送已记录的字符串。
124             U0CSR |= 0x40;                     //允许接收
125             UartState = UART0_RX;              //恢复到接收状态
126             count = 0;                         //计数清0
127             memset(RxData, 0, SIZE);           //清空接收缓冲区
128         }
 楼主| programmable 发表于 2020-1-11 17:22 | 显示全部楼层
这里要特别注意,发送的时候要禁止接收,发送完毕要使能接收,着也就是122行和124行代码的意图!
 楼主| programmable 发表于 2020-1-11 17:23 | 显示全部楼层
Zigbee系列**:

[ZigBee] 1、 ZigBee简介   https://bbs.21ic.com/icview-2894000-1-1.html

[ZigBee] 2、 ZigBee开发环境搭建   https://bbs.21ic.com/icview-2894002-1-1.html

[ZigBee] 3、ZigBee基础实验——GPIO输出控制实验-控制Led亮灭   https://bbs.21ic.com/icview-2894004-1-1.html

[ZigBee] 4、ZigBee基础实验——中断   https://bbs.21ic.com/icview-2894006-1-1.html

[ZigBee] 5、ZigBee基础实验——图文与代码详解定时器1(16位定时器)  https://bbs.21ic.com/icview-2894008-1-1.html

[ZigBee] 6、ZigBee基础实验——定时器3和定时器4(8 位定时器)  https://bbs.21ic.com/icview-2894896-1-1.html

[ZigBee] 7、ZigBee之UART剖析(ONLY串口发送)   https://bbs.21ic.com/icview-2894898-1-1.html
quickman 发表于 2020-1-12 17:42 | 显示全部楼层
Zigbee SerialApp 如何将UART通信改为SPI
jstgotodo 发表于 2020-1-12 17:42 | 显示全部楼层
zigbee 串口通信程序怎么编写
iamaiqiyi 发表于 2020-1-12 17:42 | 显示全部楼层
一般就是判断串口存在可用  
dzfansman 发表于 2020-1-12 17:42 | 显示全部楼层
单片机怎样和zigbee直接通信  
sanxingnote7 发表于 2020-1-12 17:42 | 显示全部楼层
zigbee协议与tcp/ip协议的异同?   
backlugin 发表于 2020-1-12 17:43 | 显示全部楼层
zigbee模块怎样和手机建立通信  
sdCAD 发表于 2020-1-12 17:43 | 显示全部楼层
有没有比ZigBee更先进的无线通讯方式?
fengm 发表于 2020-1-12 17:43 | 显示全部楼层
zigbee串口uart模式位置2如何设置参数
jkl21 发表于 2020-1-12 17:43 | 显示全部楼层
zigbee 模块能直接用FPGA的I/O口控制吗?
biechedan 发表于 2020-1-12 17:43 | 显示全部楼层
为什么选择zigbee协议的智能家居
jkl21 发表于 2020-1-12 17:44 | 显示全部楼层
spi与uart接口能否直接连接  
quickman 发表于 2020-1-12 17:44 | 显示全部楼层
zigbee串口透传 什么意思
fengm 发表于 2020-1-12 17:44 | 显示全部楼层
想让zigbee板子能和电脑串口进行通信
jstgotodo 发表于 2020-1-12 17:44 | 显示全部楼层
求简单好用的Zigbee转RS485方案?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

394

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部