BasicRF 简析(二:halBoardInit())

/***********************************************************************************

* @fn      halBoardInit

*

* @brief   Set up board. Initialize MCU, configure I/O pins and user interfaces

*

* @param   none

*

* @return  none

*/

电路板的初始化,主要初始化MCU,配置I/O及用户应用接口:LEDS、按键、JoyStickLCD。其中,初始化MCU主要为两个时钟的初始化。

void halBoardInit(void)

{

    halMcuInit();       //初始化时钟;

 

     //可以根据自己需要对LEDS、按键、JoyStickLCD代码段进行修改或删除;

    // LEDs

#ifdef SRF05EB_VERSION_1_3

    // SmartRF05EB rev 1.3 has only one accessible LED

    MCU_IO_DIR_OUTPUT(HAL_BOARD_IO_LED_1_PORT, HAL_BOARD_IO_LED_1_PIN);

    HAL_LED_CLR_1();

#else

    MCU_IO_DIR_OUTPUT(HAL_BOARD_IO_LED_1_PORT, HAL_BOARD_IO_LED_1_PIN);

    HAL_LED_CLR_1();

    MCU_IO_DIR_OUTPUT(HAL_BOARD_IO_LED_2_PORT, HAL_BOARD_IO_LED_2_PIN);

    HAL_LED_CLR_2();

    MCU_IO_DIR_OUTPUT(HAL_BOARD_IO_LED_3_PORT, HAL_BOARD_IO_LED_3_PIN);

    HAL_LED_CLR_3();

    MCU_IO_DIR_OUTPUT(HAL_BOARD_IO_LED_4_PORT, HAL_BOARD_IO_LED_4_PIN);

    HAL_LED_CLR_4();

#endif

 

    // Buttons

    MCU_IO_INPUT(HAL_BOARD_IO_BTN_1_PORT, HAL_BOARD_IO_BTN_1_PIN, MCU_IO_TRISTATE);

 

    // Joystick push input

    MCU_IO_INPUT(HAL_BOARD_IO_JOY_MOVE_PORT, HAL_BOARD_IO_JOY_MOVE_PIN, \

    MCU_IO_TRISTATE);

 

    // Analog input

    MCU_IO_PERIPHERAL(HAL_BOARD_IO_JOYSTICK_ADC_PORT, HAL_BOARD_IO_JOYSTICK_ADC_PIN);

 

 

    halLcdSpiInit();

    halLcdInit();

 

halIntOn();

}

 

halBoardInit()中,关于LED等外设的修改相对容易不做过多介绍;

由于在per_test丢包率测试程序时,在修改连续发送数据包的时间间隔时卡在这好长时间,因此主要解读下在该项目文件关于MCU的晶振设置;

  

halMcuInit()中主要调用了clockSetMainSrc()和clockSelect32k()其功能代码如下:

 

/******************************************************************************

* @fn  clockSetMainSrc

*

* @brief  Function for setting the main system clock source.

*         The function turns off the clock source that is not being used.

*         TICKSPD is set to the same frequency as the source.

*

* @param  uint8 source (one of CLOCK_SRC_HFRC or CLOCK_SRC_XOSC)

*

* @return void

*

******************************************************************************/

void clockSetMainSrc(uint8 source)

{

    //32K的晶振 设置为 RCOSC

  register uint8 osc32k_bm = CLKCONCMD & CLKCON_OSC32K_BM;

 

    // Source can have the following values:

    // CLOCK_SRC_XOSC   0x00  High speed Crystal Oscillator (XOSC)

    // CLOCK_SRC_HFRC   0x01  Low power RC Oscillator (HFRC)

    

    

 //2430中开启16M和32M晶振,Ti论坛上的解释是2430的移植代码,这部分在2430中是手动来控制,2530中已经变成自动控制;

 //相关链接见文章末尾;

  SLEEPCMD &= ~SLEEP_OSC_PD_BM;       // power up both oscillators

 

    while (!CC2530_IS_HFRC_STABLE() || ((SLEEPSTA & SLEEP_OSC_PD_BM)!=0));// wait until the oscillator is stable

    NOP();

 

     //设置主时钟源,并将TICKSPD CLKSPD 跟时钟源一致;

    if (source == CLOCK_SRC_HFRC){

        CLKCONCMD = (osc32k_bm | CLKCON_OSC_BM | TICKSPD_DIV_2 | CLKCON_CLKSPD_BM);

    }

    else if (source == CLOCK_SRC_XOSC){

        CLKCONCMD = (osc32k_bm | TICKSPD_DIV_1);

    }

//通过查询CLKCONSTA来确定修改后的时钟源是否达到稳定;

CC2530_WAIT_CLK_UPDATE();

 

    SLEEPCMD |= SLEEP_OSC_PD_BM;        // power down the unused oscillator

}

 

/******************************************************************************

* @fn  clockSelect32k

*

* @brief  Function for selecting source for the 32kHz oscillator

*

* @param  uint8 source (one of CLOCK_32K_XTAL or CLOCK_32K_RCOSC)

*

* @return uint8 - SUCCESS or FAILED

*

******************************************************************************/

uint8 clockSelect32k(uint8 source)

{

    // System clock source must be high frequency RC oscillator before

   // changing 32K source.

   //在改变32K时钟源之前 16M RCOSC必须处于活动状态;

 //作为芯片初始化开始,删掉是可以的,这样处理为了代码的性能?模仿吧:)

    if( !(CLKCONSTA & CLKCON_OSC_BM) )

      return FAILED;

   

     //选择不同的32K时钟源

    if (source == CLOCK_32K_XTAL){

        CLKCONCMD &= ~CLKCON_OSC32K_BM;

    }

    else if (source == CLOCK_32K_RCOSC){

        CLKCONCMD |= CLKCON_OSC32K_BM;

}

 

//通过查询CLKCONSTA来确定修改后的时钟源是否达到稳定;

    CC2530_WAIT_CLK_UPDATE();

   

    return SUCCESS;

}

 

/***********************************************************************************

* @fn halMcuInit

*

* @brief Set Main Clock source to XOSC

*

* @param none

*

* @return none

*/

void halMcuInit(void)

{

// if 32k clock change fails, set system clock to HF RC and try again

//32K时钟源选择位  主系统时钟工作在 16M RCOSC 下才能设置有效;

//若第一次设置无效,则进行第二次设置,若二次设置失败,则指示灯亮;

//关键部分进行二次检验性设置?后面CCA启用过程中也是进行二次检验,稍有差别;

//如此处理,函数的可移植性大大增强,可以任何时候调用来进行时钟的设置;

if(clockSelect32k(CLOCK_32K_XTAL) != SUCCESS) {

clockSetMainSrc(CLOCK_SRC_HFRC);

if(clockSelect32k(CLOCK_32K_XTAL) != SUCCESS) {

HAL_ASSERT(FALSE);

}

}

//设置或回复 系统主时钟源为 32M XOSC 

clockSetMainSrc(CLOCK_SRC_XOSC);

}


总结:

1. 32K XTAL时钟源的选择操作进行两次的问题,猜测可能是由于 “对于OSC32K 寄存器操作有效主时钟必须工作在16M RCOSC时钟源下”,因此首先操作一次,如果失败 创造条件再进行第二次操作,最后恢复系统主时钟源(对于一定条件下才能进行的操作 都可参考这种程序设计结构?);

2. 时刻关注寄存器或变量的初始值 及相关修改位置,如:CLKCONCMD。另外,可在此时来修改TICKSPD的值来进行定时器的时间的调整。

 参考链接:http://e2e.ti.com/support/low_power_rf/f/156/t/74054.aspx#269288

http://e2e.ti.com/support/low_power_rf/f/158/t/98362.aspx#343868

猜你喜欢

转载自blog.csdn.net/z_hualin/article/details/79010259