CC2541 BLE_Bridge,调用HAL_SYSTEM_RESET()死机
现在CC2541 BLE_Bridge这个项目做得差不多了,但是还有一些问题:
在设置蓝牙名重启时,调用HAL_SYSTEM_RESET(),会因为看门狗而不能重启,进入死机状态。
#define WD_EN BV(3)
#define WD_MODE BV(2)
#define WD_INT_1900_USEC (BV(0) | BV(1))
#define WD_RESET1 (0xA0 | WD_EN | WD_INT_1900_USEC)
#define WD_RESET2 (0x50 | WD_EN | WD_INT_1900_USEC)
#define WD_KICK() st( halIntState_t _s; HAL_ENTER_CRITICAL_SECTION(_s); WDCTL = (0xA0 | WDCTL & 0x0F); WDCTL = (0x50 | WDCTL & 0x0F); HAL_EXIT_CRITICAL_SECTION(_s);)
#define WD_INIT_1000MS() st( WDCTL = 0x00; WDCTL |= 0x08; ) //间隔时间为1000MS的看门狗启动
/* disable interrupts, set watchdog timer, wait for reset */
#define HAL_SYSTEM_RESET() st( HAL_DISABLE_INTERRUPTS(); WDCTL = WD_RESET1; WDCTL = WD_RESET2; for(;;); )
在代码中,初始化看门狗用WD_INIT_1000MS()这个函数,在void osal_start_system( void )函数中,调用WD_KICK()来喂狗,但在执行HAL_SYSTEM_RESET()时会死机,麻烦分析一下问题何在?
论坛有类似问题,解答请看这边: http://www.deyisupport.com/question_answer/wireless_connectivity/bluetooth/f/103/t/108763.aspx?pi2132219853=1
我这种情况不一样,楼上帖子是因为连接有CC Debugger影响了CC2541的复位,所以不能重新启动,我也发现了这种情况,不过,我每次都是烧完程序拔掉仿真器的,出现死机的原因是因WatchDog没有激活,我是用1s的看门狗,swru191f第154页是这样描述的,00: Clock period × 32,768 (approximately 1 s) when running the 32-kHz XOSC,就是1s钟看门狗用的是 32-kHz XOSC,我的蓝牙没有外部 32-kHz XOSC,不过试了0.25s 也没激活看门狗,不知道怎么回事?
代码如下:
#define WD_EN BV(3)
#define WD_MODE BV(2)
//INT[1:0]=0x03
//00: Clock period × 32,768 (approximately 1 s) when running the 32-kHz XOSC
//01: Clock period × 8192 (approximately 0.25 s)
//10: Clock period × 512 (approximately 15.625 ms)
//11: Clock period × 64 (approximately 1.9 ms)
#define WD_INT_1900_USEC (BV(0) | BV(1))
#define WD_RESET1 (0xA0 | WD_EN | WD_INT_1900_USEC)
#define WD_RESET2 (0x50 | WD_EN | WD_INT_1900_USEC)
#define WD_KICK() st( halIntState_t _s; HAL_ENTER_CRITICAL_SECTION(_s); WDCTL = (0xA0 | WDCTL & 0x0F); WDCTL = (0x50 | WDCTL & 0x0F); HAL_EXIT_CRITICAL_SECTION(_s);)
//间隔时间为1000MS的看门狗启动
//#define WD_INIT_1000MS() st( WDCTL = 0x00; WDCTL |= 0x08; )
#define WD_INIT_1000MS() st( halIntState_t _s1; HAL_ENTER_CRITICAL_SECTION(_s1); WDCTL = 0x00; WDCTL |= 0x08; HAL_EXIT_CRITICAL_SECTION(_s1);)
#define WD_INIT_250MS() st( halIntState_t _s1; HAL_ENTER_CRITICAL_SECTION(_s1); WDCTL = 0x00; WDCTL |= 0x09; HAL_EXIT_CRITICAL_SECTION(_s1);)
/* disable interrupts, set watchdog timer, wait for reset */
#define HAL_SYSTEM_RESET() st( HAL_DISABLE_INTERRUPTS(); WDCTL = WD_RESET1; WDCTL = WD_RESET2; for(;;); )
初始化看门狗:
WD_INIT_1000MS() ;
喂狗:
WD_KICK()
函数 HAL_SYSTEM_RESET() 实际上是激看门狗,然后死循环等待,上电后如果将看门狗定时器设置为看门狗模式,就再也不能更改看门狗的定时周期,进入死循环也未重新启动,实际上是看门狗没激活,不知道是怎么回事?
解决了,是OSC_32KHZ这个定义有问题,默认的定义是0.