SeanLib系列函数库-MyInputPort

SeanLib系列函数库-MyInputPort
查看其它库函数说明请点击此处跳转到SeanLib主页1. 本篇内容本库提供了一种扩充外部中断的方法可管理单片机的输入端口实现消抖、检测长按的功能。实现原理为将要监测的输入引脚添加到一个专用链表中然后定时调用一个状态更新函数该函数会检查每个监测的引脚状态是否发生变化提供边沿、电平、电平维持时间等属性。2. 使用方法本库依赖SeanLib和MyList头文件。头文件中提供一个结构体存储要监测的输入引脚typedefstruct{unsignedPinAddr:32;//私有该端口的BITBAND地址unsignedIsON:1;//只读该端口状态是否为ONunsignedIsOFF:1;//只读该端口状态是否为OFFunsignedNow:1;//私有unsignedLast:1;//私有unsignedActiveLevel:1;//私有该端口的有效电平unsignedRising:1;//读写该端口是否出现了上升沿需要软件清除unsignedFalling:1;//读写该端口是否出现了下降沿需要软件清除unsignedReserve:9;//预留的unsignedTrigTime:16;//读写当端口在当前状态下持续达此时间时额外触发调用一次回调函数unsignedDuration:32;//读写该端口在当前状态下持续的时间}MyInput_t;用下面函数创建一个引脚/******************************************************************************* * 功 能: 创建一个输入端口 * 参 数: * PinAddr : 用BITBAND_ADDR指定端口的BitBand地址 * ActiveLevel: 端口的有效电平作为判断ON和OFF的标准 * TrigTime : 设置一个时间当端口在当前状态下持续达此时间时会额外触发调用一次回调函数 * 不使用该功能时设置为0即可 * 返回值: 创建成功返回端口指针否则返回空指针NULL *******************************************************************************/externMyInput_t*New_MyInput(unsignedintPinAddr,unsignedcharActiveLevel);示例MyInput_t*W5500_INTNew_MyInput(BITBAND_ADDR(GPIOB-IDR,12),0);同时本库也提供了一个简化的宏来创建一个输入引脚//创建一个输入端口参数Port端口、Pin序号有效电平#defineNEW_INPUT(port,num,level)New_MyInput(BITBAND_ADDR(port-IDR,num),level)示例MyInput_t*W5500_INTNEW_INPUT(GPIOB12,0);所有的端口都创建完成后定时调用下面的状态刷新函数/******************************************************************************* * 功 能: 状态定时刷新函数每调用一次该函数已创建的端口状态全部更新 * 参 数: 无 * 返回值: 无 *******************************************************************************/externvoidMyInput_Tick(void);调用频率越高实时性越好但CPU负担会越重因此需要结合项目的具体情况综合考虑。在不使用os的项目中可以将该函数放在Systick中断中执行有os的项目尽量不要使用如下voidSysTick_Handler(void){// USER CODE BEGIN SysTick_IRQn 0externvoidMyInput_Tick(void);MyInput_Tick();//放在此处// USER CODE END SysTick_IRQn 0HAL_IncTick();// USER CODE BEGIN SysTick_IRQn 1// USER CODE END SysTick_IRQn 1}到这一步端口状态将会定时更新下面是一些用法示例以及库中提供的两个简化宏//检测端口用于消抖或检测长按#defineCHECK_KEY(key,time)((key-IsON)(key-Duration(time)))//检测是否出现了双启动事件检测标准为两个输入端口变为有效的间隔时间不超过200ms#defineCHECK_DOUBLE(key1,key2)((key1-IsON)(key2-IsON)(key1-Duration200)(key2-Duration200))//检测端口是否为ONif(Key-IsON){...}//检测端口长按是否达到1sif(CHECK_KEY(Key,1000)){...}//输入端口50ms消抖if(CHECK_KEY(Key,50)){...}//检测端口是否出现下降沿if(Key-Falling){Key-Falling0;...}编写引脚变化回调函数非必需当端口状态发生变化时该函数会被调用voidMyInput_CallBack(MyInput_t*Input);可以该函数中执行少量的程序防止中断阻塞。另外本库提供了一个方法当端口变化到某个状态并持续一定时间时额外触发一次回调函数可通过设置 TrigTime 属性实现如MyInput_t*W5500_INTNEW_INPUT(GPIOB12,0);W5500_INT-TrigTime300;3. 端口变化检测原理Input-Now*(unsignedintvolatile*)(Input-PinAddr);if(Input-LastInput-Now)//端口无变化时持续时间增加{Input-Duration;if((Input-TrigTime0)(Input-DurationInput-TrigTime)){MyInput_CallBack(Input);//额外触发一次回调函数}}else//端口有变化时更新边沿信号{Input-IsONInput-NowInput-ActiveLevel;//状态与有效电平相同时设置ONInput-IsOFFInput-IsON0;Input-LastInput-Now;//更新前次的状态Input-RisingInput-IsON;//端口变为有效电平设置上升沿信号Input-FallingInput-Rising0;Input-Duration0;//清零持续时长MyInput_CallBack(Input);//调用端口变化的回调函数}