zoukankan      html  css  js  c++  java
  • [ZigBee] 8、ZigBee之UART剖析·二(串口收发)

    前言:上一节讲UART基本知识介绍完了,并深入剖析了一个串口发送工程,本节将进一步介绍串口收发!

    1、初始化

    在串口初始化部分,和上一节不同的地方是:

     51     U0CSR |= 0x40;           //允许接收 
     52     IEN0 |= 0x84;            //开总中断允许接收中断  

    第51行使能接收数据,上一节介绍的仅仅是发送,所以没有这一句配置:

    第51行开总中断和UART0中断:

      1 /****************************************************************************
      2 * 文 件 名: main.c
      3 * 描    述: 设置串口调试助手波特率:115200bps 8N1
      4 *           串口调试助手给CC2530发字符串时,开发板会返回接收到的字符串
      5 ****************************************************************************/
      6 #include <ioCC2530.h>
      7 #include <string.h>
      8 
      9 typedef unsigned char uchar;
     10 typedef unsigned int  uint;
     11 
     12 #define UART0_RX    1
     13 #define UART0_TX    2
     14 #define SIZE       51
     15 
     16 char RxBuf;
     17 char UartState;
     18 uchar count;
     19 char RxData[SIZE];        //存储发送字符串
     20 
     21 /****************************************************************************
     22 * 名    称: DelayMS()
     23 * 功    能: 以毫秒为单位延时
     24 * 入口参数: msec 延时参数,值越大,延时越久
     25 * 出口参数: 无
     26 ****************************************************************************/
     27 void DelayMS(uint msec)
     28 { 
     29     uint i,j;
     30     
     31     for (i=0; i<msec; i++)
     32         for (j=0; j<1070; j++);
     33 }
     34 
     35 /****************************************************************************
     36 * 名    称: InitUart()
     37 * 功    能: 串口初始化函数
     38 * 入口参数: 无
     39 * 出口参数: 无
     40 ****************************************************************************/
     41 void InitUart(void)
     42 { 
     43     PERCFG = 0x00;           //外设控制寄存器 USART 0的IO位置:0为P0口位置1 
     44     P0SEL = 0x0c;            //P0_2,P0_3用作串口(外设功能)
     45     P2DIR &= ~0xC0;          //P0优先作为UART0
     46     
     47     U0CSR |= 0x80;           //设置为UART方式
     48     U0GCR |= 11;                       
     49     U0BAUD |= 216;           //波特率设为115200
     50     UTX0IF = 0;              //UART0 TX中断标志初始置位0
     51     U0CSR |= 0x40;           //允许接收 
     52     IEN0 |= 0x84;            //开总中断允许接收中断  
     53 }
     54 
     55 /****************************************************************************
     56 * 名    称: UartSendString()
     57 * 功    能: 串口发送函数
     58 * 入口参数: Data:发送缓冲区   len:发送长度
     59 * 出口参数: 无
     60 ****************************************************************************/
     61 void UartSendString(char *Data, int len)
     62 {
     63     uint i;
     64     
     65     for(i=0; i<len; i++)
     66     {
     67         U0DBUF = *Data++;
     68         while(UTX0IF == 0);
     69         UTX0IF = 0;
     70     }
     71 }
     72 
     73 /****************************************************************************
     74 * 名    称: UART0_ISR(void) 串口中断处理函数 
     75 * 描    述: 当串口0产生接收中断,将收到的数据保存在RxBuf中
     76 ****************************************************************************/
     77 #pragma vector = URX0_VECTOR 
     78 __interrupt void UART0_ISR(void) 
     79 { 
     80     URX0IF = 0;       // 清中断标志 
     81     RxBuf = U0DBUF;                           
     82 }
     83 
     84 
     85 /****************************************************************************
     86 * 程序入口函数
     87 ****************************************************************************/
     88 void main(void)
     89 {    
     90     CLKCONCMD &= ~0x40;                        //设置系统时钟源为32MHZ晶振
     91     while(CLKCONSTA & 0x40);                   //等待晶振稳定为32M
     92     CLKCONCMD &= ~0x47;                        //设置系统主时钟频率为32MHZ   
     93    
     94     InitUart();                                //调用串口初始化函数   
     95     UartState = UART0_RX;                      //串口0默认处于接收模式
     96     memset(RxData, 0, SIZE);
     97     
     98     while(1)
     99     {
    100         if(UartState == UART0_RX)              //接收状态 
    101         { 
    102             if(RxBuf != 0) 
    103             {                 
    104                 if((RxBuf != '#')&&(count < 50))//以'#'为结束符,一次最多接收50个字符            
    105                     RxData[count++] = RxBuf; 
    106                 else
    107                 {
    108                     if(count >= 50)             //判断数据合法性,防止溢出
    109                     {
    110                         count = 0;              //计数清0
    111                         memset(RxData, 0, SIZE);//清空接收缓冲区
    112                     }
    113                     else
    114                         UartState = UART0_TX;  //进入发送状态 
    115                 }
    116                 RxBuf  = 0;
    117             }
    118         }
    119         
    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         }    
    129     }
    130 }

    2、中断回调函数

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

     77 #pragma vector = URX0_VECTOR 
     78 __interrupt void UART0_ISR(void) 
     79 { 
     80     URX0IF = 0;       // 清中断标志 
     81     RxBuf = U0DBUF;                           
     82 }

    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         }    

    这里要特别注意,发送的时候要禁止接收,发送完毕要使能接收,着也就是122行和124行代码的意图!

    Zigbee系列文章:

    [ZigBee] 1、 ZigBee简介

    [ZigBee] 2、 ZigBee开发环境搭建

    [ZigBee] 3、ZigBee基础实验——GPIO输出控制实验-控制Led亮灭

    [ZigBee] 4、ZigBee基础实验——中断

    [ZigBee] 5、ZigBee基础实验——图文与代码详解定时器1(16位定时器)(长文)

    [ZigBee] 6、ZigBee基础实验——定时器3和定时器4(8 位定时器)

    [ZigBee] 7、ZigBee之UART剖析(ONLY串口发送)

     

     

    PS:如果您觉得还不错,点个赞,让更多人受益~

    @beautifulzzzz 2016-07-16 continue~  
    e-mail:beautifulzzzz@qq.com 
    sina:http://weibo.com/beautifulzzzz?is_all=1

  • 相关阅读:
    java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header.
    spring-session-data-redis依赖冲突问题
    centos7启动iptables时报Job for iptables.service failed because the control process exited with error cod
    图片上传后台服务报内存溢出 Out Of Memory Java heap space
    mysql 数据库密码忘记重置 进行远程连接
    打Jar包
    Type interface com.innovationV2.mapper.UserMapper is not known to the MapperRegistry
    关于java基础类型Integer String的clone()
    clion使用clang编译
    token & refresh token 机制总结
  • 原文地址:https://www.cnblogs.com/zjutlitao/p/5676675.html
Copyright © 2011-2022 走看看