Z-STACK 2.5.1A 之三 CC2530 之 z-stack LED处理
Z-STACK 2.5.1A LED处理
具体就是这样:
HalLedSet LED有设置一个动作模式(不包括开关)
HalLedOnOff LED开关动作模式
HalLedBlink LED闪烁
HalLedUpdate LED在事件处理函数中的处理(因为要闪烁,所以要不断地在事件中处理,直到停止闪烁)
头文件 hal_led.h 定义了几个宏和函数声明
/* LEDS- The LED number is the same as the bit position */
#defineHAL_LED_1 0x01
#defineHAL_LED_2 0x02
#defineHAL_LED_3 0x04
#defineHAL_LED_4 0x08
#defineHAL_LED_ALL (HAL_LED_1 | HAL_LED_2 |HAL_LED_3 | HAL_LED_4)
/*Modes */
#defineHAL_LED_MODE_OFF 0x00
#defineHAL_LED_MODE_ON 0x01
#defineHAL_LED_MODE_BLINK 0x02
#defineHAL_LED_MODE_FLASH 0x04
#defineHAL_LED_MODE_TOGGLE 0x08
/*Defaults */
#defineHAL_LED_DEFAULT_MAX_LEDS 4
#defineHAL_LED_DEFAULT_DUTY_CYCLE 5
#defineHAL_LED_DEFAULT_FLASH_COUNT 50
#defineHAL_LED_DEFAULT_FLASH_TIME 1000
externvoid HalLedInit( void );
externuint8 HalLedSet( uint8 led, uint8 mode );
externvoid HalLedBlink( uint8 leds, uint8 cnt, uint8 duty, uint16 time );
externvoid HalLedEnterSleep( void );
externvoid HalLedExitSleep( void );
externuint8 HalLedGetState ( void );
led.c
//LED控制结构体
/* LEDcontrol structure */
typedefstruct {
uint8 mode; /* Operation mode 操作模式*/
uint8 todo; /* Blink cycles left 剩余闪烁周期*/
uint8 onPct; /* On cycle percentage 开周期百分比*/
uint16 time; /* On/off cycle time (msec) 开关周期(毫秒)*/
uint32 next; /* Time for next change 下次改变时间*/
}HalLedControl_t;
typedefstruct
{
HalLedControl_t HalLedControlTable[HAL_LED_DEFAULT_MAX_LEDS];
uint8 sleepActive;
}HalLedStatus_t;
uint8HalLedSet (uint8 leds, uint8 mode)
{
#if(defined (BLINK_LEDS)) && (HAL_LED == TRUE)
uint8 led;
HalLedControl_t *sts;
switch (mode)
{
case HAL_LED_MODE_BLINK:
/* Default blink, 1 time, D% duty cycle*/
HalLedBlink (leds, 1,HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME);
break;
case HAL_LED_MODE_FLASH:
/* Default flash, N times, D% duty cycle*/
HalLedBlink (leds,HAL_LED_DEFAULT_FLASH_COUNT, HAL_LED_DEFAULT_DUTY_CYCLE,HAL_LED_DEFAULT_FLASH_TIME);
break;
case HAL_LED_MODE_ON:
case HAL_LED_MODE_OFF:
case HAL_LED_MODE_TOGGLE:
led = HAL_LED_1;
leds &= HAL_LED_ALL;
sts = HalLedStatusControl.HalLedControlTable;
while (leds)
{
if (leds & led)
{
if (mode != HAL_LED_MODE_TOGGLE)
{
sts->mode = mode; /* ON or OFF */
}
else
{
sts->mode ^= HAL_LED_MODE_ON; /* Toggle */
}
HalLedOnOff (led, sts->mode);
leds ^= led;
}
led <<= 1;
sts++;
}
break;
default:
break;
}
#elif(HAL_LED == TRUE)
LedOnOff(leds, mode);
#else
// HAL LED is disabled, suppress unusedargument warnings
(void) leds;
(void) mode;
#endif/* BLINK_LEDS && HAL_LED */
return ( HalLedState );
}
/***********************************************************************
* HalLedBlink LED闪烁模式,这个函数如果是ON,OFF就一次搞定,如果是闪烁,就还在其他地方周期性的处理LED
*
* @brief Blink the leds
*
* @param leds - bit mask value ofleds to be blinked
* numBlinks - number of blinks
* percent - the percentage ineach period where the led
* will be on
* period - length of each cyclein milliseconds
*
* @return None
***********************************************************************/
voidHalLedBlink (uint8 leds, uint8 numBlinks, uint8 percent, uint16 period)
{
#if(defined (BLINK_LEDS)) && (HAL_LED == TRUE)
uint8 led;
HalLedControl_t *sts;
if (leds && percent &&period)
{
if (percent < 100)
{
led = HAL_LED_1;
leds &= HAL_LED_ALL;
sts = HalLedStatusControl.HalLedControlTable;
while (leds)
{
if (leds & led)
{
/* Store the current state of the ledbefore going to blinking if not already blinking */
if(sts->mode <HAL_LED_MODE_BLINK )
preBlinkState|= (led & HalLedState);
sts->mode = HAL_LED_MODE_OFF; /* Stop previous blink */
sts->time = period; /* Time for oneon/off cycle */
sts->onPct = percent; /* % of cycle LEDis on */
sts->todo = numBlinks; /* Number of blinkcycles */
if (!numBlinks) sts->mode |=HAL_LED_MODE_FLASH; /* Continuous */
sts->next =osal_GetSystemClock(); /*Start now */
sts->mode |=HAL_LED_MODE_BLINK; /*Enable blinking */
leds ^= led;
}
led <<= 1;
sts++;
}
// Cancel any overlapping timer for blinkevents
osal_stop_timerEx(Hal_TaskID,HAL_LED_BLINK_EVENT);
osal_set_event (Hal_TaskID,HAL_LED_BLINK_EVENT);
}
else
{
HalLedSet (leds, HAL_LED_MODE_ON); /* >= 100%, turn on */
}
}
else
{
HalLedSet (leds, HAL_LED_MODE_OFF); /* No on time, turn off */
}
#elif(HAL_LED == TRUE)
percent = (leds & HalLedState) ?HAL_LED_MODE_OFF : HAL_LED_MODE_ON;
HalLedOnOff (leds, percent); /* Toggle */
#else
// HAL LED is disabled, suppress unusedargument warnings
(void) leds;
(void) numBlinks;
(void) percent;
(void) period;
#endif/* BLINK_LEDS && HAL_LED */
}
这里调用HalLedUpdate周期性的处理闪烁
uint16Hal_ProcessEvent( uint8 task_id, uint16 events )
{
uint8 *msgPtr;
(void)task_id; // Intentionally unreferenced parameter
if ( events & SYS_EVENT_MSG )
{
msgPtr = osal_msg_receive(Hal_TaskID);
while (msgPtr)
{
/* Do something here - for now, justdeallocate the msg and move on */
/* De-allocate */
osal_msg_deallocate( msgPtr );
/* Next */
msgPtr = osal_msg_receive( Hal_TaskID );
}
return events ^ SYS_EVENT_MSG;
}
if ( events & HAL_LED_BLINK_EVENT )
{
#if(defined (BLINK_LEDS)) && (HAL_LED == TRUE)
HalLedUpdate();//这里调用HalLedUpdate周期性的处理闪烁
#endif/* BLINK_LEDS && HAL_LED */
return events ^ HAL_LED_BLINK_EVENT;
}
if (events & HAL_KEY_EVENT)
{
#if(defined HAL_KEY) && (HAL_KEY == TRUE)
/* Check for keys */
HalKeyPoll();
/* if interrupt disabled, do next polling*/
if (!Hal_KeyIntEnable)
{
osal_start_timerEx( Hal_TaskID,HAL_KEY_EVENT, 100);
}
#endif// HAL_KEY
return events ^ HAL_KEY_EVENT;
}
#ifdefPOWER_SAVING
if ( events & HAL_SLEEP_TIMER_EVENT )
{
halRestoreSleepLevel();
return events ^ HAL_SLEEP_TIMER_EVENT;
}
#endif
#ifdefCC2591_COMPRESSION_WORKAROUND
if ( events & PERIOD_RSSI_RESET_EVT )
{
macRxResetRssi();
return (events ^ PERIOD_RSSI_RESET_EVT);
}
#endif
/* Nothing interested, discard the message */
return 0;
}
voidHalLedUpdate (void)
{
uint8 led;
uint8 pct;
uint8 leds;
HalLedControl_t *sts;
uint32 time;
uint16 next;
uint16 wait;
next = 0;
led =HAL_LED_1;
leds = HAL_LED_ALL;
sts = HalLedStatusControl.HalLedControlTable;
/* Check if sleep is active or not */
if (!HalLedStatusControl.sleepActive)
{
while (leds)
{
if (leds & led)
{
if (sts->mode &HAL_LED_MODE_BLINK)
{
time = osal_GetSystemClock();
if (time >= sts->next)
{
if (sts->mode &HAL_LED_MODE_ON)
{
pct = 100 - sts->onPct; /* Percentage of cycle for off*/
sts->mode &=HAL_LED_MODE_ON; /* Say it's noton */
HalLedOnOff (led,HAL_LED_MODE_OFF); /* Turn it off */
if (!(sts->mode &HAL_LED_MODE_FLASH))
{
sts->todo--; /* Not continuous,reduce count */
}
}
else if ( (!sts->todo)&& !(sts->mode & HAL_LED_MODE_FLASH) )
{
sts->mode ^=HAL_LED_MODE_BLINK; /* No moreblinks */
}
else
{
pct = sts->onPct; /* Percentage of cycle foron */
sts->mode |=HAL_LED_MODE_ON; /* Say it's on*/
HalLedOnOff (led,HAL_LED_MODE_ON); /* Turn it on */
}
if (sts->mode &HAL_LED_MODE_BLINK)
{
wait = (((uint32)pct *(uint32)sts->time) / 100);
sts->next = time + wait;
}
else
{
/* no more blink, no more wait */
wait = 0;
/* After blinking, set the LEDback to the state before it blinks */
HalLedSet (led, ((preBlinkState& led)!=0)?HAL_LED_MODE_ON:HAL_LED_MODE_OFF);
/* Clear the saved bit */
preBlinkState &= (led ^0xFF);
}
}
else
{
wait = sts->next - time; /* Time left */
}
if (!next || ( wait && (wait< next) ))
{
next = wait;
}
}
leds ^= led;
}
led <<= 1;
sts++;
}
if (next)
{
osal_start_timerEx(Hal_TaskID,HAL_LED_BLINK_EVENT, next); /* Scheduleevent */
}
}
}
voidHalLedOnOff (uint8 leds, uint8 mode)
{
if (leds & HAL_LED_1)
{
if (mode == HAL_LED_MODE_ON)
{
HAL_TURN_ON_LED1();
}
else
{
HAL_TURN_OFF_LED1();
}
}
if (leds & HAL_LED_2)
{
if (mode == HAL_LED_MODE_ON)
{
HAL_TURN_ON_LED2();
}
else
{
HAL_TURN_OFF_LED2();
}
}
if (leds & HAL_LED_3)
{
if (mode == HAL_LED_MODE_ON)
{
HAL_TURN_ON_LED3();
}
else
{
HAL_TURN_OFF_LED3();
}
}
if (leds & HAL_LED_4)
{
if (mode == HAL_LED_MODE_ON)
{
HAL_TURN_ON_LED4();
}
else
{
HAL_TURN_OFF_LED4();
}
}
/* Remember current state */
if (mode)
{
HalLedState |= leds;
}
else
{
HalLedState &= (leds ^ 0xFF);
}
}
#endif/* HAL_LED */
/**********************************************************************
* @fn HalGetLedState
*
* @brief Dim LED2 - Dim (set level) of LED2
*
* @param none
*
* @return led state
***********************************************************************/
uint8HalLedGetState ()
{
#if(HAL_LED == TRUE)
return HalLedState;
#else
return 0;
#endif
}
撇开ZSTACK的处理方式,也是可以的,如果我们只要一个LED亮灭,直接就可以用51的方法,给 1和0就OK
如果要闪烁一段时间,那最好注册一个事件,然后用定时器激活事件,这样在事件处理函数中处理。
感谢了,我想问一下,你们开发ZigBee是使用IAR embedded 还是Keil c51
IAR
好像开发ZigBee均推荐IAR,主要是ZigBee的协议栈在IAR中比较好用。
恩,TI就是用IAR写的。所以很少人去改。那麻烦。