我正在为CC2541(基于8051的)MCU编写一些代码,这是TI的BTLE SOC,并且在启动基于定时器的中断时遇到问题。我已经成功配置了GPIO中断,甚至可以使用该中断来设置定时器中断标志(然后触发定时器中断)......但我无法让定时器本身在翻转时触发中断。
以下是我正在使用的一些基本代码:
/**************************************************************************************************
* 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包含的BTAL堆栈的小部分HAL代码,但我没有使用OSAL的任何部分。事实上,我根本没有使用芯片的BT方面。
答案 0 :(得分:0)
我仍然没有弄清楚为什么正常的定时器中断不起作用,但我确实设法让睡眠定时器工作(这是我需要将芯片拉出低功耗模式所需的)。
问题是定时器比较事件会抛出一个中断,但不会重置定时器(我假设它会这样)......并且因为它是一个24位定时器,运行频率为32 kHz,所以需要很长时间是时候翻身再次击中旧的设定点。
答案 1 :(得分:0)
问题是您需要读取寄存器,将时间添加到寄存器并写入比较寄存器。计数器无意重置。
答案 2 :(得分:0)
也许睡眠计时器由您导入代码的HAL部分使用。 您可以尝试使用其他定时器之一,而不是BLE堆栈使用的(我认为1,2和4可用)。
当然,您需要修改一组不同的寄存器,用于设置计数器值,以及启用中断。
对于timer1,请参阅T1IET和T1CC0L / H(在ioCC2541.h中定义,以及在CC2541的开发者手册中,ofc)