其他的MCU,譬如ST的,NXP,大部分都会给出一个或者几个具有特定的WAKEUP功能的引脚。但是新唐就
做的比较特殊,它的大部分引脚都支持WAKEUP功能~
我们来看看,新唐的规格书自己是怎么说的:
可以看到,它在概述GPIO功能时,就提出了这个~
根据查看,我们知道当芯片进入空闲/关机模式时,gpio也可以作为芯片的唤醒源。
唤醒触发器条件的设置与gpio中断触发器相同 。
也就是我们配置PIN位外部中断模式,也就间接的具有了WAKUP功能!
还真是有点与众不同啊~
对与普通按键按下瞬间的抖动及噪音感染的问题,我们以往都选择延时,再检测电平的功能,
或者硬件去抖动的方案~
这里新唐给出了一种解决方案~
一个被称为去弹跳的功能~当gpiopin的进行中断输入采样,防止噪声引起的意外中断。
Gpio去弹跳功能仅支持边缘检测触发器类型,不支持断电模式。对于边缘触发条件,
通过设置选择:下降边缘触发、上升边缘触发。
当然想使用,得配置2个寄存器:
1)、gpiopin设置去弹跳启用控制寄存器px_dben。
2)、gpio_dbctl寄存器:
通过设置dbclksrc(gpio_dbctl[4])寄存器,去弹跳时钟源可以是hclk或lirc。
通过设置dbclksel(gpio_dbctl[3:0])寄存器可以控制采样周期。
这种功能,说白了,就是在检测按键时,在启动一个定时器,一直检测电平:
在其某一个周期间及后续一周期内(2周期为一个测试周期),发生电平转换,才认为是一次触发:
具体看图:
说白了也就是那么回事,那么其他的没有这种功能的MCU,我可不可以用这个方法来检测?
当然可以,就是得开销一个定时器~
下面看代码配置:
KEY.H
#ifndef __KEY_H_
#define __KEY_H_
#include "NuMicro.h"
#define KEY0 PH4
#define KEY0_EXTI_ENABLE 1 //允许外部中断
#define KEY0_WAKEUPLP_ENABLE 1 //允许唤醒LOWPOWER模式
void KEY_Init(void);
#endif
KEY.C
#include "key.h"
void KEY_Init(void)
{
CLK->AHBCLK |= CLK_AHBCLK_GPHCKEN_Msk;
GPIO_SetMode(PH, BIT4, GPIO_MODE_INPUT);
#if KEY0_EXTI_ENABLE
GPIO_EnableInt(PH, 4, GPIO_INT_FALLING);
NVIC_EnableIRQ(GPH_IRQn);
#if KEY0_WAKEUPLP_ENABLE
/* Enable interrupt de-bounce function and select de-bounce sampling cycle time is 1024 clocks of LIRC clock */
GPIO_SET_DEBOUNCE_TIME(GPIO_DBCTL_DBCLKSRC_LIRC, GPIO_DBCTL_DBCLKSEL_1024);
GPIO_ENABLE_DEBOUNCE(PH, BIT4);
#endif
#endif
}
void GPH_IRQHandler(void)
{
volatile uint32_t temp;
/* To check if PB.3 interrupt occurred */
if(GPIO_GET_INT_FLAG(PH, BIT4))
{
GPIO_CLR_INT_FLAG(PH, BIT4);
printf("PH.4 INT occurred.\n");
}
else
{
/* Un-expected interrupt. Just clear all PH interrupts */
temp = PH->INTSRC;
PH->INTSRC = temp;
printf("Un-expected interrupts.\n");
}
}
然后,我们在main函数的while循环里,让它进入LOW POWER模式。我们每按一下就会唤醒一次,然后接着进入LOW POWER模式,然后循环:
main函数while里面添加:
while(1)
{
//进入低功耗模式 PH4引脚中断可唤醒
printf("进入 Power-Down 模式,请按按键唤醒...\n");
PowerDownFunction();
printf("系统被唤醒了...\n\n");
}
下载,查看串口输出,按键按一次,唤醒一次:
好,那到这,我的简单的分享结束了!
大神勿喷!~谢谢观看~
|