ZStack-CC2530-2.5.1a开发(三)LED驱动学习

ZStack版本:ZStack-CC2530-2.5.1a
下载和调试器:SmartRF04EB
IDE开发软件:IAR Embedded Workbench IDE - 8051 10.20.1
开发平台:基于TI-CC2530的任意厂家的
一、简介
ZStack-CC2530-2.5.1a协议栈中的有非常完备的LED驱动。驱动除了实现基本的“亮”、“灭”功能之外,还可以通过改变参数,同时控制多个LED亮灭、指定LED可调占空比闪烁等等。

本文简单讲解一下ZStack-CC2530-2.5.1a协议栈LED的驱动原理,以及相关移植操作。
二、驱动分析
ZStack协议栈首先是从main()函数开始运行的,我们就从main函数进行分析,

int main( void )
{
  // Turn off interrupts
  osal_int_disable( INTS_ALL );

  // Initialization for board related stuff such as LEDs
  HAL_BOARD_INIT();

通过分析,我们发现,main函数的第一条语句是关中断,这个明显与LED没有关系。第二条语句从协议栈给出的注释就可以看是有关于LED的,所以我们进行HAL_BOARD_INIT()函数的定义里,继续分析:

#define HAL_BOARD_INIT()                                         \
{                                                                \
  uint16 i;                                                      \
                                                                 \
  SLEEPCMD &= ~OSC_PD;                       /* turn on 16MHz RC and 32MHz XOSC */                \
  while (!(SLEEPSTA & XOSC_STB));            /* wait for 32MHz XOSC stable */                     \
  asm("NOP");                                /* chip bug workaround */                            \
  for (i=0; i<504; i++) asm("NOP");          /* Require 63us delay for all revs */                \
  CLKCONCMD = (CLKCONCMD_32MHZ | OSC_32KHZ); /* Select 32MHz XOSC and the source for 32K clock */ \
  while (CLKCONSTA != (CLKCONCMD_32MHZ | OSC_32KHZ)); /* Wait for the change to be effective */   \
  SLEEPCMD |= OSC_PD;                        /* turn off 16MHz RC */                              \
                                                                 \
  /* Turn on cache prefetch mode */                              \
  PREFETCH_ENABLE();                                             \
                                                                 \
  HAL_TURN_OFF_LED1();                                           \
  LED1_DDR |= LED1_BV;                                           \
  HAL_TURN_OFF_LED2();                                           \
  LED2_DDR |= LED2_BV;                                           \
  HAL_TURN_OFF_LED3();                                           \
  LED3_DDR |= LED3_BV;  

通过逐句分析,我们发现有一条语句是HAL_TURN_OFF_LED1(); 从该函数的定义我们可以知道它是关闭LED1,那我们再跳转到HAL_TURN_OFF_LED1(); 这个函数的定义处分析;

#if defined (HAL_BOARD_CC2530EB_REV17) && !defined (HAL_PA_LNA) && !defined (HAL_PA_LNA_CC2590)

  #define HAL_TURN_OFF_LED1()       st( LED1_SBIT = LED1_POLARITY (0); )
  #define HAL_TURN_OFF_LED2()       st( LED2_SBIT = LED2_POLARITY (0); )
  #define HAL_TURN_OFF_LED3()       st( LED3_SBIT = LED3_POLARITY (0); )
  #define HAL_TURN_OFF_LED4()       HAL_TURN_OFF_LED1()

  #define HAL_TURN_ON_LED1()        st( LED1_SBIT = LED1_POLARITY (1); )
  #define HAL_TURN_ON_LED2()        st( LED2_SBIT = LED2_POLARITY (1); )
  #define HAL_TURN_ON_LED3()        st( LED3_SBIT = LED3_POLARITY (1); )
  #define HAL_TURN_ON_LED4()        HAL_TURN_ON_LED1()

我们发现这个文件里有大量关于LED的操作,该文件的名称是hal_board_cfg.h。通过分析该文件,发现LED的配置信息均在该文件中,如果需要移植LED驱动,只需要修改此文件即可。

ZStack-CC2530-2.5.1a的驱动里已经有了对LED的,亮,灭,闪烁灯功能的实现函数,这些功能都是通用的,不需要修改,对LED驱动的移植,唯一不同的是各个板子在设计时,LED的管脚位置,LED的个数,LED亮灯的逻辑电平不同而已。
在hal_board_cfg.h文件中,下面几条语句,刚好定义了LED的个数,管脚位置,点灯逻辑等信息,所以,不同板子,只需按照实际设计,修改下面信息即可。

/* ------------------------------------------------------------------------------------------------
 *                                       LED Configuration
 * ------------------------------------------------------------------------------------------------
 */

#if defined (HAL_BOARD_CC2530EB_REV17) && !defined (HAL_PA_LNA) && !defined (HAL_PA_LNA_CC2590)
  #define HAL_NUM_LEDS            3
#elif defined (HAL_BOARD_CC2530EB_REV13) || defined (HAL_PA_LNA) || defined (HAL_PA_LNA_CC2590)
  #define HAL_NUM_LEDS            1
#else
  #error Unknown Board Indentifier
#endif

#define HAL_LED_BLINK_DELAY()   st( { volatile uint32 i; for (i=0; i<0x5800; i++) { }; } )

/* 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

三、LED驱动移植
本人所使用的板子,总共有两个LED,LED1位于P1_2,LED2位于P1_3,两个LED都是低电平点亮。
所以,修改代码如下:

/* ------------------------------------------------------------------------------------------------
 *                                       LED Configuration
 * ------------------------------------------------------------------------------------------------
 */

#if defined (HAL_BOARD_CC2530EB_REV17) && !defined (HAL_PA_LNA) && !defined (HAL_PA_LNA_CC2590)
  #define HAL_NUM_LEDS            3
#elif defined (HAL_BOARD_CC2530EB_REV13) || defined (HAL_PA_LNA) || defined (HAL_PA_LNA_CC2590)
  #define HAL_NUM_LEDS            1
#else
  #error Unknown Board Indentifier
#endif

#define HAL_LED_BLINK_DELAY()   st( { volatile uint32 i; for (i=0; i<0x5800; i++) { }; } )

/* 1 - Green */
#define LED1_BV           BV(2)
#define LED1_SBIT         P1_2
#define LED1_DDR          P1DIR
#define LED1_POLARITY     ACTIVE_LOW

#if defined (HAL_BOARD_CC2530EB_REV17)
  /* 2 - Red */
  #define LED2_BV           BV(3)
  #define LED2_SBIT         P1_3
  #define LED2_DDR          P1DIR
  #define LED2_POLARITY     ACTIVE_LOW

  /* 3 - Yellow */
  #define LED3_BV           BV(3)
  #define LED3_SBIT         P1_3
  #define LED3_DDR          P1DIR
  #define LED3_POLARITY     ACTIVE_LOW
#endif

因为我们只有两个LED灯,所以在这我将LED3的配置修改成和LED2一样的配置,如果在程序中使用LED3,则实际操作的是LED2。如果你们的板子有多于3个LED,则只需在下面添加相关配置即可。

四、LED驱动API函数介绍
ZStack-CC2530-2.5.1a协议栈LED的API函数有两个:

/***************************************************************************************************
 * @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)

该API函数的可取值,见如下代码:

/* 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)

/* Modes */
#define HAL_LED_MODE_OFF     0x00
#define HAL_LED_MODE_ON      0x01
#define HAL_LED_MODE_BLINK   0x02
#define HAL_LED_MODE_FLASH   0x04
#define HAL_LED_MODE_TOGGLE  0x08

第二个API函数是:

/***************************************************************************************************
 * @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)

第一个参数和第一个API函数的第一个参数取值相同。
第二个参数是LED闪烁的次数,如果为0,则一直闪烁。
第三个参数是占空比。
第四个参数是闪烁的周期,单位是ms。

五、驱动测试
我们在上个串口通信工程中进行测试。
在uint16 GenericApp_ProcessEvent( uint8 task_id, uint16 events )事件处理函数的串口事件分支中,添加如下语句:

case CMD_SERIAL_MSG:
     HalLedBlink ( HAL_LED_1, 2, 50, 5000 );
     HalLedBlink ( HAL_LED_2, 4, 50, 5000 );
     HalUARTWrite(0,(((mtOSALSerialData_t *)MSGpkt)->msg)+1,*(((mtOSALSerialData_t *)MSGpkt)->msg));
 break;

重新编译工程,下载。通过串口给CC250发送信息,发现发送一次,LED1闪烁2次,LED2闪烁4次,实验成功。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值