DA14580笔记(2)-------睡眠状态下按键唤醒

时间:2024-05-23 14:48:40

对于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();
		 

}

四、程序调用(根据官方代码),在主循环进入和退出睡眠时。实现如下

DA14580笔记(2)-------睡眠状态下按键唤醒

五、注意事项:

1、对于按键,单击一次会多出进入中断导致程序现象异常的情况。

解决方案:一定要初始化按键GPIO时才有上拉输入(INPUT_PULLUP)。还有硬件部分,按键的引脚最好直接接地,如果接入地的电阻过大也会有影响。这一点很重要。

2、关于初始化io状态能否保持的问题

DA14580 为了把功耗做的很低,在低功耗的模式的时候大部分外设都会关掉,包括IO口

DA14580笔记(2)-------睡眠状态下按键唤醒

系统唤醒之后要调用外设初始化,periph_init()获取IO口状态,然后重新设置

SetBits16(SYS_CTRL_REG, PAD_LATCH_EN, 1)  把引脚从锁死状态下 解开