没志青年
发布于 2026-01-05 / 15 阅读
0

z-stack 事件处理

zigbee 硬件层驱动

硬件适配层 HAL

硬件适配层(Hardware Adaptation Layer,HAL),用于适配各种各样的硬件,为上层提供统一的接口,从而方便开发者使用各种各样的硬件。本节课从文件结构和工程结构这两方面简单地讲解HAL的结构。

在安装好Z-Stack 3.0 后,HAL相关的源代码可以在Z-Stack 3.0的Components文件夹中找到,如图所示。

LED驱动

在 hal_led.h 中,有三个常用函数:

/*
 * 初始化LED
 */
extern void HalLedInit( void );
​
/*
 * 开关LED
 */
extern uint8 HalLedSet( uint8 led, uint8 mode );
​
/*
 * 闪烁LED
 */
extern void HalLedBlink( uint8 leds, uint8 cnt, uint8 duty, uint16 time );

HalLedInit()的作用是初始化LED。在上一章节中,我们讲解过在hal_drivers.c文件中的驱动程序初始化函数HalDriverInit()里面调用了这个函数。

在Z-Stack 3.0中,HAL默认支持了4个LED,LED的逻辑定义如下:

/* LEDS - The LED number is the same as the bit position */
#define HAL_LED_1     0x01
#define HAL_LED_2     0x02
#define HAL_LED_3     0x04
#define HAL_LED_4     0x08
#define HAL_LED_ALL   (HAL_LED_1 | HAL_LED_2 | HAL_LED_3 | HAL_LED_4)

HalLedSet( uint8 led, uint8 mode )用来设定LED的工作模式。其中的第1个参数led用于指定待设定的LED,第2个参数mode用于指定工作模式,这个工作模式有3种: (1)开启,对应的宏定义是HAL_LED_MODE_ON。 (2)关闭,对应的宏定义是HAL_LED_MODE_OFF。 (3)反转,对应的宏定义是HAL_LED_MODE_TOGGLE。 例如如果要开启第1盏LED,可以按这个方式调用:

HalLedSet(
    HAL_LED_1,//指定第1盏LED
    HAL_LED_MODE_ON);//开启

HalLedBlink( uint8 leds, uint8 cnt, uint8 duty, uint16 time )的作用是让LED闪烁。其中的第1个参数leds用于指定LED,第2个参数cnt用于指定闪烁的次数,第3个参数duty用于指定LED是开启状态时的占空比,第4个参数time用于指定每次闪烁的时间周期(单位:ms)。

举个例子说明一下使用方法,例如如果需要让第1盏LED闪烁10次,每次闪烁的时间周期是2000ms,而且在这2000ms中有60%的时间LED要处于开启状态,那么可以按照以下方式调用:

HalLedBlink(
    HAL_LED_1,//指定第1盏LED
    10,//指定闪烁次数是10次
    60,//指定60%的时间LED是处于开启状态
    2000);//指定1次闪烁的时间周期是2000ms,也就是在1次闪烁周期中,LED的开启时长是1200ms,关闭时长是800ms

但是 HAL并不知道你的LED连在了哪个 GPIO 上,因此需要进行物理映射,让HAL知道。

HAL -> Target -> CC2530EB -> Config -> hal_board_cfg.h

// LED1
#define LED1_BV           BV(0)           // 1 << 0
#define LED1_SBIT         P1_0            // 指定GPIO
#define LED1_DDR          P1DIR           // 指定方向寄存器
#define LED1_POLARITY    ACTIVE_HIGH      // 置1为高电平
​
#if defined (HAL_BOARD_CC2530EB_REV17)
  // LED2
  #define LED2_BV           BV(1)         // 1 << 1
  #define LED2_SBIT         P1_1
  #define LED2_DDR          P1DIR
  #define LED2_POLARITY    ACTIVE_HIGH
​
  // LED3
  #define LED3_BV           BV(4)
  #define LED3_SBIT         P1_4
  #define LED3_DDR          P1DIR
  #define LED3_POLARITY    ACTIVE_HIGH
​
    #ifdef ENABLE_LED4_DISABLE_S1
      //LED4
      #define LED4_BV             BV(1)
      #define LED4_SBIT           P0_1
      #define LED4_DDR            P0DIR
      #define LED4_POLARITY      ACTIVE_HIGH
      #define LED4_SET_DIR()     do {LED4_DDR |= LED4_BV;} while (0)
    #else
      #define LED4_SET_DIR()
    #endif
​
#endif

在讲解OSAL的章节中,自定义了一个SAMPLEAPP_TEST_EVT事件,并且编写了对应的事件处理代码,本节课把事件处理代码修改为闪烁LED。

回到应用层,在zcl_samplesw.c文件的事件处理函数zclSampleSw_event_loop()中修改自定义事件SAMPLEAPP_TEST_EVT的处理逻辑,代码如下:

示例代码

// 处理自定义的用户事件:SAMPLEAPP_TEST_EVT 
if ( events & SAMPLEAPP_TEST_EVT )
{
    printf("Blink LED!\r\n");
​
    HalLedBlink(
        HAL_LED_1,//指定第1盏LED
        10,//指定闪烁次数是10次
        50,//指定50%的时间LED是处于开启状态
        1000);//指定1次闪烁的时间周期是1000ms
​
    //消除已经处理的事件,然后返回未处理的事件
    return ( events ^ SAMPLEAPP_TEST_EVT );
}

按键驱动

串口驱动

定时器驱动

ADC驱动

LCD驱动