2013-12-22 97 views
2

我正在爲基於CC2541(8051的)MCU編寫一些代碼,這是TI的BTLE SOC,並且遇到了基於定時器的中斷觸發的問題。我已經成功配置了GPIO中斷,甚至可以使用該中斷來設置定時器中斷標誌(然後觸發定時器中斷)......但我無法讓定時器本身在發生翻轉時觸發中斷。基於8051 MCU的定時器基址中斷(CC2541)

下面是我使用一些基本代碼:

/************************************************************************************************** 
*           Includes 
**************************************************************************************************/ 
#include <ioCC2541.h> 
#include <hal_defs.h> 
#include <hal_board_cfg.h> 

unsigned int ISR_Counter = 0; 
uint16 loop_Counter = 0; 

void main(void) 
{ 

    HAL_BOARD_INIT(); 

    P1DIR |= BV(0); 
    P0DIR |= BV(4); 

    P1_0 = 1; 
    P0_4 = 1; 


/*****************************************************************************/ 
    //Configure sleep timer 

    IEN0 &= ~BV(5); //Disable interrupt 

    //Set timer compare value 
    ST2 = 0x00; 
    ST1 = 0xFF; 
    ST0 = 0x00; 

    IRCON &= ~0x80; //Clear flag 
    IEN0 |= BV(5); //Enable interrupt 

    EA = 1; //Enable all interrupts 

    while(1){ 

    if (loop_Counter == 0){ P0_4 ^= 1; } 
    loop_Counter++; 
    } 

} 
/************************************************************************************************** 
              CALL-BACKS 
**************************************************************************************************/ 


/*Sleep Timer interrupt */ 
_PRAGMA(vector=ST_VECTOR) 
__interrupt void SLEEP_ISR(void) 
{ 
    P1_0 ^= 1; // P1.0 = toggle 
    IRCON &= ~0x80; //Clear flag 
    ISR_Counter++; 
} 

的HAL_BOARD_INIT功能(及相關DEFS)是:

/* Setting Clocks */ 

// switch to the 16MHz HSOSC and wait until it is stable 
#define SET_OSC_TO_HSOSC()              \ 
{                    \ 
    CLKCONCMD = (CLKCONCMD & 0x80) | CLKCONCMD_16MHZ;       \ 
    while ((CLKCONSTA & ~0x80) != CLKCONCMD_16MHZ);       \ 
} 

// switch to the 32MHz XOSC and wait until it is stable 
#define SET_OSC_TO_XOSC()              \ 
{                    \ 
    CLKCONCMD = (CLKCONCMD & 0x80) | CLKCONCMD_32MHZ;       \ 
    while ((CLKCONSTA & ~0x80) != CLKCONCMD_32MHZ);       \ 
} 

// set 32kHz OSC and wait until it is stable 
#define SET_32KHZ_OSC()              \ 
{                    \ 
    CLKCONCMD = (CLKCONCMD & ~0x80) | OSC_32KHZ;         \ 
    while ((CLKCONSTA & 0x80) != OSC_32KHZ);         \ 
} 

#define START_HSOSC_XOSC()              \ 
{                    \ 
    SLEEPCMD &= ~OSC_PD;   /* start 16MHz RCOSC & 32MHz XOSC */   \ 
    while (!(SLEEPSTA & XOSC_STB)); /* wait for stable 32MHz XOSC */    \ 
} 

#define STOP_HSOSC()               \ 
{                    \ 
    SLEEPCMD |= OSC_PD;    /* stop 16MHz RCOSC */      \ 
} 
/* ----------- Board Initialization ---------- */ 

#define HAL_BOARD_INIT()           \ 
{                \ 
    /* Set to 16Mhz to set 32kHz OSC, then back to 32MHz */  \ 
    START_HSOSC_XOSC();           \ 
    SET_OSC_TO_HSOSC();           \ 
    SET_32KHZ_OSC();            \ 
    SET_OSC_TO_XOSC();           \ 
    STOP_HSOSC();             \ 
                   \ 
    /* Turn on cache prefetch mode */        \ 
    PREFETCH_ENABLE();            \ 
                   \ 
    /* set direction for GPIO outputs */       \ 
    LED1_DDR |= LED1_BV;           \ 
    LED2_DDR |= LED2_BV;           \ 
    GYRO_VDD_DDR |= GYRO_VDD_BV;         \ 
    DCDC_DDR |= DCDC_BV;  /* Set P0_7 as output */    \ 
    GYRO_VDD_SBIT = 1;  /* Gyro must be on for I2C to work */ \ 
    P0DIR |= BV(5);   /* Unused pin as output */   \ 
    P2DIR |= BV(0);   /* Unused pin as output */   \ 
    P1DIR |= 0x3C;   /* UART pins as output */    \ 
    P0INP = 0x4E;   /* Tri-state inputs */    \ 
} 

我已經通過調試運行它,可以看到,睡眠定時器寄存器正在改變,所以定時器實際上正在運行。就像我所說的,我也可以通過另一箇中斷處理程序手動設置中斷標誌,並且中斷觸發就像您期望的那樣。我已經嘗試配置其他定時器,以及UART中斷...都具有相同的結果。在這一點上,我不確定這是中斷本身還是與時鐘源配置有關的問題....無論如何,我確信這是一個愚蠢的做法,我做錯了。

我應該補充一點,我正在使用TI包含在他們的BTLE堆棧中的小部分HAL代碼,但我沒有使用OSAL的任何部分。事實上,我根本不使用芯片的BT方面。

+0

你可能缺少在寄存器中的一個的使能位。 –

+0

我想到了這一點,但對於我的生活,我無法找到它會是什麼。我甚至通過代碼搜索來實現基於定時器的中斷,並且找不到明顯的區別 – mjbeals

回答

0

我還沒有弄清楚爲什麼普通的定時器中斷不能正常工作,但我的確設法讓睡眠定時器工作(這正是我所需要的將芯片拉出低功耗模式)。

問題是,一個計時器比較事件拋出一箇中斷,但並沒有重置計時器(我認爲它會)...並且由於它是一個24位計時器,運行頻率爲32 kHz,因此需要一個非常很長一段時間才能翻轉並再次擊中舊的設定點。

0

問題是你需要讀取寄存器,增加你的時間,並寫入比較寄存器。計數器不打算重置。

0

也許睡眠定時器被您導入到代碼的HAL部分使用。 您可以嘗試使用其他定時器之一,而不是由BLE堆棧使用(我認爲1,2和4可用)。

當然,您需要修改一組不同的寄存器,設置計數器值並啓用中斷。

Timer1的,見T1IET和T1CC0L/H(中ioCC2541.h限定,並且在爲CC2541的顯影劑手冊,OFC)