(配套源码、软件、开发板等资源,可移步博客同名QQ群/TB店铺:拿破仑940911)
一、前言
关于Z-Stack协议栈中的LED控制,如果使用协议栈中自带的驱动,很简单就可以实现非常丰富的功能。除了基本的“亮”、“灭”之外,可以通过改变参数,同时控制多个LED亮灭、指定LED可调占空比闪烁等等。
本节将从详细讲述Z-Stack中LED的驱动原理,以及相关移植操作。
二、LED配置
相关代码全部位于hal_board_cfg.h文件中,这是我们唯一需要修改的文件,原版的代码如下:
/* 1 - Green */ #define LED1_BV BV(0) #define LED1_SBIT P1_0 #define LED1_DDR P1DIR #define LED1_POLARITY ACTIVE_HIGH #if defined (HAL_BOARD_CC2530EB_REV17) /* 2 - Red */ #define LED2_BV BV(1) #define LED2_SBIT P1_1 #define LED2_DDR P1DIR #define LED2_POLARITY ACTIVE_HIGH /* 3 - Yellow */ #define LED3_BV BV(4) #define LED3_SBIT P1_4 #define LED3_DDR P1DIR #define LED3_POLARITY ACTIVE_HIGH #endif从上述代码就可以看出,在TI的V1.7版本的官方评估板上,总共有3个LED,分别位于P1_0、P1_1、P1_4三个位置,并且都是高电平有效(即高电平亮,低电平灭)。对于一般应用来说,3个LED完全够用了,所以我们也不必再增加到LED4、LED5等,直接在这部分代码上修改即可。如果有特殊应用,需要增加LED,依葫芦画瓢即可。目前我手上使用的微雪的ZigBee开发板用的是ZB502底板,LED部分原理图如下:
正好和代码完全匹配,所以LED部分就不必做修改了,也就是不必做任何移植就可以直接使用。但为了演示,就假设我们要将LED3从原本的“P1_4 高电平有效”移植到“P0_5 低电平有效”,那么我们仅需要做细微的改动,修改后的代码如下:
#define LED3_BV BV(5) #define LED3_SBIT P0_5 #define LED3_DDR P0DIR #define LED3_POLARITY ACTIVE_LOW这样就OK了!与原版的代码简单对比即可完全理解!
三、LED初始化
相关代码先后位于两个位置,并且都不需要我们做任何修改:
hal_board_cfg.h文件中对应代码如下:
#define HAL_BOARD_INIT() \ { \ ...... HAL_TURN_OFF_LED1(); \ LED1_DDR |= LED1_BV; \ HAL_TURN_OFF_LED2(); \ LED2_DDR |= LED2_BV; \ HAL_TURN_OFF_LED3(); \ LED3_DDR |= LED3_BV; \ ...... }可见在实际初始化IO时,仅初始化了对应IO的PxDIR,并未初始化PxSEL。因为PxSEL默认值为0x00,Px_y本身就是工作在“普通IO”模式,所以就算不初始化PxSEL也并不会有影响。
hal_led.c文件中对应代码如下:
void HalLedInit (void) { #if (HAL_LED == TRUE) /* Initialize all LEDs to OFF */ HalLedSet (HAL_LED_ALL, HAL_LED_MODE_OFF); #endif /* HAL_LED */ #ifdef BLINK_LEDS /* Initialize sleepActive to FALSE */ HalLedStatusControl.sleepActive = FALSE; #endif }可见HalLedInit( )函数中只是将所有LED都设置为“熄灭”状态,并没有更多的操作;
四、LED驱动
Z-Stack中提供了丰富的LED控制接口,一般最常用的是HalLedSet( )和HalLedBlink( )两个函数,相关说明见hal_led.c文件:
/*************************************************************************************************** * @fn HalLedSet * * @brief Tun ON/OFF/TOGGLE given LEDs * * @param led - bit mask value of leds to be turned ON/OFF/TOGGLE * mode - BLINK, FLASH, TOGGLE, ON, OFF * @return None ***************************************************************************************************/ uint8 HalLedSet (uint8 leds, uint8 mode) { ...... }/*************************************************************************************************** * @fn HalLedBlink * * @brief Blink the leds * * @param leds - bit mask value of leds to be blinked * numBlinks - number of blinks * percent - the percentage in each period where the led * will be on * period - length of each cycle in milliseconds * * @return None ***************************************************************************************************/ void HalLedBlink (uint8 leds, uint8 numBlinks, uint8 percent, uint16 period) { ...... }
五、验证
本来这里最好的验证方式应该是通过按键点灯来实现,由于按键的讲解在后面,这里就以前面讲过的串口输入命令来实现“串口点灯”!
具体步骤很简单:
a、按照前面的讲述,完成LED驱动移植(若你用的也是微雪的ZB502底板,那可以直接跳过这一步);
b、编写测试代码,这里采取串口输入命令,CC2530根据判断不同的串口命令,实现不同的点灯功能,需要更改的只有Uart0_Handle( )函数:
void Uart0_Handle(void) { ...... else if(strstr((const char*)UART0_RX_BUFF,"led_1")) { HalLedSet(HAL_LED_1,HAL_LED_MODE_TOGGLE); } else if(strstr((const char*)UART0_RX_BUFF,"led_2")) { HalLedSet(HAL_LED_2,HAL_LED_MODE_TOGGLE); } else if(strstr((const char*)UART0_RX_BUFF,"led_3")) { HalLedSet(HAL_LED_3,HAL_LED_MODE_TOGGLE); } ...... }上述代码很好理解,编译下载到芯片中后,通过串口发送“led_1\r\n”、“led_2\r\n”、“led_3\r\n”即可分别实现对LED1、LED2、LED3的状态取反。
亲测成功!