• 11.Z-Stack协议栈使用


    f8wConfig.cfg文件

    选择信道、设置PAN ID

    image-20231024164646941

    选择信道

    #define DEFAULT_CHANLIST 0x00000800

    DEFAULT_CHANLIST 表明Zigbee模块要工作的网络,当有多个信道参数值进行或操作之后,把结果作为 DEFAULT_CHANLIST

    对于路由器、终端、协调器的意义:

    • 路由器和终端:
      • 可以在参与或操作的这些信道上选择一个相对于我来说最佳的网络,加入进去
    • 协调器
      • 可以在参与或操作的这些信道上选择一个最佳的信道并在这个信道上创建自己的Zigbee网络

    选择PAN ID

    • 非0xFFFF

      • 路由器和终端:必须要加入到PANID为参数值这样一个Zigbee无线局域网
      • 协调器:要创建一个网络,并且把这个参数值作为这个网络的PANED
    • 为0xFFFF

      • 路由器和终端:在加入网络的时候没有PANID的限制
      • 协调器:可以随机生成一个值,把这个随机值作为这个网络的PANED

    当2个模块下载相同的协调器代码,并且指定的PANID参数值为非0xffff时,

    先上电的模块可以创建0xFFF8这样一个Zigbee网络,后上电的模块创建一个在0xFFF8基础上加1的网络。

    响应任务事件

    硬件层 :硬件操作相关

    网络层 :网络相关的代码

    应用层:自己写应用程序部分

    • 几乎每一个层都是一个任务,系统为每一个任务分配一个,一个字节的唯一数值编号,每一个任务都能处理一些他们能够处理的事物
    • 任务ID:这个数值编号叫做
    • 事件:它他们能够处理的事物
    /*
    *task_id:任务ID
    *event_flag:任务事件
    */
    uint8 osal_set_event( uint8 task_id, uint16 event_flag )
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在工程中进行测试

    1. TestAPP.c文件中,找到UINT16 TestAPP_ProcessEvent( byte task_id, UINT16 events )函数
    2. 在之前写的三种模式的测试代码下添加如下语句
    osal_set_event(TestAPP_TaskID,TestAPP_SEND_MSG_EVT);
    
    • 1

    image-20231024173151722

    1. 在该函数中进行向下找,看到对TestAPP_SEND_MSG_EVT事件的响应代码,进行如下处理:
          P0DIR |= 0X02;
          P0_1 = 0;
    
    • 1
    • 2

    image-20231024172856825

    1. P0DIR语句前 LS164_BYTE(11)语句前打断点,然后再路由器的工程下进行编译,然后烧录代码,下载后全速执行、单步调试
    2. 实验现象:跳到TestAPP_SEND_MSG_EVT事件的响应代码,LED2亮

    软件定时器响应事件

    /*
    *taskID:任务ID
    *event_id:任务事件
    *timeout_value:超时时间(毫秒),多长时间处理一次 
    */
    uint8 osal_start_timerEx( uint8 taskID, uint16 event_id, uint16 timeout_value )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    实验验证

    osal_start_timerEx(TestAPP_TaskID,TestAPP_SEND_MSG_EVT,2000);
    
    • 1
    1. 注释掉刚才写的osal_set_event函数,将osal_start_timerEx函数写在下面

    image-20231024173632873

    1. 编译下载,观察实验现象
    2. 延时2秒后亮

    定义事件

    格式为 #define 事件名 0x000? ?可以是十六进制的数,最多定义16个时间 0 ~ F

    必须保证3个0,位置随意

    实验验证

    1. TestAPP.h文件中,定义事件

    格式为 #define 事件名 0x000? ?可以是十六进制的数,最多定义16个时间 0 ~ F

    必须保证3个0,位置随意

    //格式为 #define 事件名 0x000?  ?可以是十六进制的数,最多定义16个时间 0 ~ F
    //必须保证3个0,位置随意
    #define TestAPP_EVT                0x0002   
    
    • 1
    • 2
    • 3
    1. 如下

    image-20231024174750798

    1. TestAPP.c文件中,找到刚才的UINT16 TestAPP_ProcessEvent( byte task_id, UINT16 events )函数,在最后一个事件响应代码下,添加新的事件响应代码
      if ( events & TestAPP_EVT ){
         //初始化要全面,因为使用的是TI官方代码移植的,他官方例程中可能也配置了这个IO口,我们在这里重新配置的时候必须要全面配置,否则这个IO口可能默认不是通用IO
         P0SEL &=0XEF;//1110 1111 
         P0DIR |= 0X10;
         P0_4 = 0;
         
         return (events ^ TestAPP_EVT);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    image-20231024175336520

    1. 添加本事件的响应事件函数

    image-20231024180249010

    1. 编译,下载,灯亮

    初始化要全面,因为使用的是TI官方代码移植的,他官方例程中可能也配置了这个IO口,我们在这里重新配置的时候必须要全面配置,否则这个IO口可能默认不是通用IO

    消息

    在ZSTACK里,任务事件定义的特点决定了,每一个任务最多只能处理16种不同的事件,而系统在运行时候有许多事务需要处理,如果每一个实物处理都定义成1个事件,那么16种事件肯定是不够用,所有引入消息。
    消息的处理事务的原理:
    定义了一个事件#define SYS_EVENT_MSG 0x8000 // A message is waiting event
    当需要应用层任务来处理某个事务的时候,首先给应用层任务发送一个消息
    掉osal_set_event(SDApp_TaskID,SYS_EVENT_MSG);
    那么这样一来,应用层就会进入SYS_EVENT_MSG处理,在这个事件处理里判断到底刚刚引发我们产生SYS_EVENT_MSG事件是哪一种类型的消息,然后根据消息的类型做相应的处理。
    而消息的类型可以自己定义,这样一来消息的类可以很多,那么应用层任务处理的事物种类就很多了。

    实验验证

    1. TestAPP.c文件中的void TestAPP_HandleKeys( byte shift, byte keys )函数下的所有内容清空,然后调用数码管显示函数

    image-20231024185914125

    1. TestAPP_ProcessEvent函数注释掉之前调用的osal_start_timerEx,将下面的函数添加到下面
    // 定义一个名为keyChange_t的结构体指针msgPtr
    keyChange_t *msgPtr;
                  
    //定义按键响应消息
    msgPtr = (keyChange_t *)osal_msg_allocate( sizeof(keyChange_t) );
                  
    if ( msgPtr ){
    	// 将消息头部的事件设置为KEY_CHANGE
     	msgPtr->hdr.event = KEY_CHANGE;
    	// 将键值设置为3
    	msgPtr->keys=3;
                      
    	//将发送给TestAPP_TaskID任务的消息压入消息队列,并响应系统事件osal_set_event(TestAPP_TaskID,SYS_EVENT_MSG);
    	osal_msg_send( TestAPP_TaskID, (uint8 *)msgPtr );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    image-20231024185449983

    1. 编译,下载,数码管显示按键数字,表示无误

    按键实验(协议栈实现)

    1. 添加封装好的代码到工程中

    Key.c

    根据自己的实际情况,更改里面的文件名和事件名

    #include
    #include "TestApp.h" 
    #include "OSAL_Timers.h"
    extern unsigned char TestAPP_TaskID;
    void delay()
    {
       int i,j;
       for(i=0;i<1000;i++)
         for(j=0;j<30;j++);
    }
    void KeysIntCfg()
    {//Key3  Key4   Key5
         
         P1SEL &=~0X02;
         P1DIR &=~0X02;
         IEN2|=0x10;//开P1IE组中断
         P1IEN|=0x02;//开Key3组内中断
         PICTL|=0x02;//设置P1_1为下降沿
         
         P2SEL &=~0X01;
         P2DIR &=~0X01;
         IEN2|=0x02;
         P2IEN|=0x01;
         PICTL|=0x08;//设置P2_0为下降沿
         
         P0SEL &=~0X20;
         P0DIR &=~0X20;
         P0IE=1;//或者写成 IEN1|=0x20
         P0IEN|=0x20;
         PICTL|=0x01;//设置P0_5为下降沿
         
         
         EA=1;      //开总中断
    }
    
    #pragma vector=P1INT_VECTOR
    __interrupt void Key3_ISR() //P1_1
    {
         
         if(P1IFG & 0X02)
         {
            osal_start_timerEx(TestAPP_TaskID,TestAPP_EVT,25);
         }
         P1IFG =0;
         P1IF=0;
    }
    #pragma vector=P2INT_VECTOR
    __interrupt void Key4_ISR()//P2_0
    {
    
         if(P2IFG & 0X01)
         { 
            osal_start_timerEx(TestAPP_TaskID,TestAPP_EVT,25);
         }
         P2IFG =0;
         P2IF=0;
    }
    #pragma vector=P0INT_VECTOR
    __interrupt void Key5_ISR()//P0_5
    {
    
        if(P0IFG & 0X20)
        {
           osal_start_timerEx(TestAPP_TaskID,TestAPP_EVT,25);
        }
         P0IFG =0;
         P0IF=0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    Key.h

    #ifndef KEY_H
    #define KEY_H
    void KeysIntCfg();
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 引用头文件,初始化。【初始化函数一定要放到osal_start_system();之前】

    image-20231024190443721

    image-20231024190533982

    1. 屏蔽官方例程中的中断函数。【hal-target-CC2530EB-drivers】里面的HAL_ISR_FUNCTION( halKeyPort2Isr, P2INT_VECTOR )HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )

    image-20231024190935761

    1. TestAPP.c文件中的之前定义的TestAPP_EVT事件响应进行修改,如下所示
      if ( events & TestAPP_EVT ){
         
         P0SEL &=0XEF;//1110 1111 
         P0DIR |= 0X10;
         P0_4 ^= 1;
         
         if(0==P1_1){/*按钮3按下*/LS164_BYTE(3);}
         if(0==P2_0){/*按钮4按下*/LS164_BYTE(4);}
         if(0==P0_5){/*按钮5按下*/LS164_BYTE(5);}
          
         return (events ^ TestAPP_EVT);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. 下载,实验现象:按下按键灯亮灭交替,数码管显示按键编号

    使用协议栈生成hex文件注意

    1. 配置项目工程,可以生成hex,之前在生成工程里面说过如何设置

    2. f8w2530.xc文件中,将下面两行的注释去掉

    image-20231024192040722

  • 相关阅读:
    VScode+esp-idf:例程(esp32-web-camera)保存视频到sd卡
    Excel2010打开独立窗口显示的方法
    重新认识mysql事务
    java毕业设计校园便利店信息系统开发源码+lw文档+mybatis+系统+mysql数据库+调试
    Java Spring 通过 AOP 实现方法参数的重新赋值、修改方法参数的取值
    第12讲:DQL数据查询语句的执行顺序以及语句汇总
    洛谷C++简单题小练习day11—字母转换,分可乐两个小程序
    11.0 堆参数调优入门之堆参数调整
    Kotlin 协程调度切换线程是时候解开真相了
    论文阅读_异常检测综述
  • 原文地址:https://blog.csdn.net/qq_61228493/article/details/134192244