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 );
}