對於DA14580的喚醒,其主要有兩個喚醒源。
1、一個是同步喚醒源,來源於BLE的內部定時器(默認10秒)和BLE事件;
2、一個是異步喚醒源,即喚醒中斷,可以配置爲任意引腳喚醒,其即使用cortex M0指定的WIC技術。
WIC(wakeup interruptcontroller)是獨立於CPU和中斷控制工作的,但WIC檢測到電平變化(也可以計數到指定數值時)即會提醒PMU給CPU供電,並啓動內部RC震盪電路提供時鐘,並維持中斷信號給CPU中斷部分,這樣CPU可以從睡眠中喚醒。
那麼,對於DA14580的喚醒,需要注意什麼呢?
1)BLE的喚醒定時器設置
2)DA14580的外部喚醒設置
本實驗採用的是外部按鍵喚醒功能,睡眠模式爲擴展睡眠模式,因爲需要一直要間隔兩秒廣播,按鍵觸發改變廣播數據,
動態改變廣播數據,一定要先停止廣播。這部分可以參考官方文檔。
一、初始化按鍵喚醒
////P24
// 1 0000 0000 0000 0000 0000
void app_button_enable(void)
{
wkupct_register_callback(ext_wakeup_cb); //註冊喚醒回調函數
if(GPIO_GetPinStatus(BUTTON_GPIO_PORT,BUTTON_GPIO_PIN))
{
wkupct_enable_irq(0x100000, 0x100000, 1, 0); //初始化按鍵中斷喚醒
}
}
二、失能按鍵喚醒功能
/**
****************************************************************************************
* @brief Disable external wake up GPIO Interrupt. Used on self wakup.
*
* @return void.
****************************************************************************************
*/
void app_wakeup_disable(void)
{
SetWord16(WKUP_RESET_IRQ_REG, 1); // Acknowledge it
SetBits16(WKUP_CTRL_REG, WKUP_ENABLE_IRQ, 0); // No more interrupts of this kind
}
三、在喚醒回調函數實現自定義功能等
void ext_wakeup_cb(void)
{
if(GetBits16(SYS_STAT_REG, PER_IS_DOWN))
{
periph_init(); //初始化外設,最好把外設初始化寫在這個函數內
}
if(!GPIO_GetPinStatus( BUTTON_GPIO_PORT, BUTTON_GPIO_PIN))
{
Delay_Ms();
if(!GPIO_GetPinStatus( BUTTON_GPIO_PORT, BUTTON_GPIO_PIN))
{
app_adv_stop(); //檢查按鍵按下停止廣播,去更新廣播數據
}
}
// SetBits32(GP_CONTROL_REG, BLE_WAKEUP_REQ, 1);
app_button_enable();
}
四、程序調用(根據官方代碼),在主循環進入和退出睡眠時。實現如下
五、注意事項:
1、對於按鍵,單擊一次會多出進入中斷導致程序現象異常的情況。
解決方案:一定要初始化按鍵GPIO時纔有上拉輸入(INPUT_PULLUP)。還有硬件部分,按鍵的引腳最好直接接地,如果接入地的電阻過大也會有影響。這一點很重要。
2、關於初始化io狀態能否保持的問題
DA14580 爲了把功耗做的很低,在低功耗的模式的時候大部分外設都會關掉,包括IO口
系統喚醒之後要調用外設初始化,periph_init()獲取IO口狀態,然後重新設置
SetBits16(SYS_CTRL_REG, PAD_LATCH_EN, 1) 把引腳從鎖死狀態下 解開