最近一个基于LPC23xx的项目要通过一个按键同时实现复位和恢复出厂设置(类似于有些ADSL和路由器上用细针顶一下孔)。我是通过外部中断来实现的,分享下我的思路和方案,算是抛砖引玉吧。
【需求】
通过一个按键同时实现复位(短按)和恢复出厂设置(长按两秒)
【实现方案】
产品基于LPC23xx的开发板。(其它NXP ARM7实现方法也相似)
把按键接到LPC23xx的外部中断管脚(我这里使用EINT3即P2.13管脚),按下按键则触发中断,中断处理中发出重启系统操作。系统重启时候把P2.13设为GPIO输入,判断P2.13管脚输入电平。如果持续2秒为低电平(按键长按)则发起恢复出厂设置。设置完然后把P2.13改为外部中断3。整体流程如下图:
【关键源码】
主函数main()部分
PINSEL4 &= ~0x0C000000; //设置P2.13为GPIO
FIO2DIRL &= ~(1<<13); //GPIO方向为输入
if(!(FIO2PINL & (1<<13))) //P2.13为低电平输入,按钮仍按下
{
mS_Delay(2000);//等2秒再看
if(!(FIO2PINL & (1<<13))) //2秒后还是按下的,可以恢复出厂设置了
{
while(!(FIO2PINL & (1<<13))) //等待按键松开后再开始恢复出厂设置
{
}
//开始恢复出厂设置
SetFactory(); //调用恢复出厂设置函数
}else{ //不足两秒,判断为重启操作
printf("Device has rebooted...
");
}
}
///处理完复位/恢复出厂设置后
//设置P2.13为EINT3
EInt3_init();
外部中断处理部分
//初始化中断
void EInt3_init()
{
EXTINT = 0x08; //先清除中断3
EXTMODE &= ~0x08; //设置外部中断3触发模式为电平触发
EXTPOLAR &= ~0x08; //设置电平触发极性为低电平触发中断
VICIntEnable |= (1<<17); //向量表中使能外部中断3
VICVectAddr17 = (unsigned long)factory_reset_irq; //设置外部中断3的中断处理函数
VICVectPriority17 = 4; //设置优先级
PINSEL4 |= 0x04000000; //Set P2.13 as INT3
}
//中断处理函数
void factory_reset_irq (void) __irq
{
EXTINT = 0x08; //Clear Ext Int
SoftReboot(); //重启
VICVectAddr = 0; //中断处理结束,写一下VICAddress
}
重启系统
//软复位其实就是让程序从main()处重新运行,即把程序指针PC移到0地址处。
//使用函数指针实现
void SoftReboot()
{
((void(*)())0x0)(); //函数指针指向把地址0,然后调用它
}