对于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) 把引脚从锁死状态下 解开