当前位置: 首页 > news >正文

网站被人做跳转恺英网络公司最新消息

网站被人做跳转,恺英网络公司最新消息,做体彩网站怎么做,商城模板网站今天来分享一个使用EXIT外部中断加TIM计时器实现按键长短按以及双击操作#xff0c;不过笔者在双击上有点瑕疵#xff0c;就是当你按下双击第一下停顿几秒按第二下依然会识别为双击操作#xff0c;笔者猜测只要板子不停电即便到第二天按下第二下依旧会识别双击操作#xff…今天来分享一个使用EXIT外部中断加TIM计时器实现按键长短按以及双击操作不过笔者在双击上有点瑕疵就是当你按下双击第一下停顿几秒按第二下依然会识别为双击操作笔者猜测只要板子不停电即便到第二天按下第二下依旧会识别双击操作正常来说2秒内如果没有按下第二下会认为双击操作失败重新开始不过整体使用效果还可以解决这个问题的方案笔者抽时间在好好想想。 下面为大家介绍以下大体思路我们知道每个I/O端口都会对应一个EXIT中断由此我们可以使用EXIT的双边沿触发来实现TIM定时器的开启关闭当检测按下时开启TIM定时器当检测松开按键时关闭TIM定时器从而记录按键按下的时间根据按键按下的时间长短不同可以判断按键的长短按另外需要设定标志位来判断双击下面开始上代码。 首先是TIM计时器的代码笔者使用的是TIM2计时器大家找一个板子上没用到的计时器即可。 time2.h /*********** Author : 桃杬* describe : TIM2计时器在此处主要用来实现计时操作* Data : 2024.06.06 ***************/#ifndef _TIME2_H #define _TIME2_H#include stm32f10x.hextern uint16_t Time_Count; //外部声明让Time_Count成为全局变量void TIME2_Init(uint16_t arr,uint16_t psc);#endif 下面是time.c的代码具体解释笔者在里面都有备注需要注意的是笔者设置每次发生溢出的时间为10ms即Time_Count每10ms都会计数加1实际时间 Time_Count * 10单位ms。 time2.c #include time2.h/******** TIM溢出次数 Tout(溢出时间) (arr1)/(psc1)/Tclk(时钟分割)* 当 arr 10000, psc 72 时10ms溢出一次 *******/ uint16_t Time_Count;void TIME2_Init(uint16_t arr,uint16_t psc) {//定义TIM结构体TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定义NVIC嵌套向量中断NVIC_InitTypeDef NVIC_InitStrucure;//使能时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);TIM_InternalClockConfig(TIM2); //配置TIM2内部时钟可以不配置默认是一直开着的//配置TIMTIM_TimeBaseStructure.TIM_ClockDivision TIM_CKD_DIV1; //不用时钟分割TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up; //向上计数方式TIM_TimeBaseStructure.TIM_Period arr - 1; //自动装载值TIM_TimeBaseStructure.TIM_Prescaler psc - 1; //预分频系数TIM_TimeBaseStructure.TIM_RepetitionCounter 0; //周期计数器值这个是高级定时器基本通用定时器不用开启TIM_TimeBaseInit(TIM2,TIM_TimeBaseStructure);TIM_ClearFlag(TIM2,TIM_FLAG_Update); //清除TIM的挂起标志TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //使能指定TIM中断寻去中断更新//配置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置优先级分组NVIC_InitStrucure.NVIC_IRQChannel TIM2_IRQn; //中断源NVIC_InitStrucure.NVIC_IRQChannelCmd ENABLE; //使能中断通道NVIC_InitStrucure.NVIC_IRQChannelPreemptionPriority 2; //抢占优先级NVIC_InitStrucure.NVIC_IRQChannelSubPriority 1; //子优先级(也是响应优先级)NVIC_Init(NVIC_InitStrucure); }void TIM2_IRQHandler(void) {if(TIM_GetITStatus(TIM2,TIM_IT_Update) SET){//进入中断表示定时器计数(CNT)溢出, 自增(10ms溢出一次, 可通过配置ARR, PSC和Tclk自定义溢出时间)Time_Count;TIM_ClearITPendingBit(TIM2,TIM_IT_Update); //清除定时器溢出中断} } 接下来便是key.h代码如果需要移植的话只需要修改每个按键定义以及中断部分其他部分不需要修改笔者这里使用了四个按键如果大家是少于四个按键可以将按键启用的值改为0即可即禁用不需要的按键如将isEnableKey4 该为 0就会禁用按键4。如果大家的按键大于4个可以按照笔者写的格式增加按键下面可以参考笔者写的代码。 key.h /*********** Author : 桃杬* describe : 实现按键长短按 双击操作* Data : 2024.06.06 ***************/#ifndef _KEY_H #define _KEY_H#include stm32f10x.h/**** 是否启用按键* 根据个人需求修改* 1 启用按键 0 失能按键* 默认都启用 ****/ #define isEnableKey1 1 #define isEnableKey2 1 #define isEnableKey3 1 #define isEnableKey4 1#if isEnableKey1 //定义KEY1按键引脚以及中断 #define KEY1_GPIO_CLK RCC_APB2Periph_GPIOC //使能时钟端口 #define KEY1_GPIO_PORT GPIOC //KEY1端口 #define KEY1_GPIO_PIN GPIO_Pin_1 //KEY1引脚 #define KEY1_GPIO_EXTI_PORT_SOURCE GPIO_PortSourceGPIOC //外部中断源端口 #define KEY1_GPIO_EXTI_PIN_SOURCE GPIO_PinSource1 //外部中断源引脚 #define KEY1_EXTI_LINE EXTI_Line1 //EXTI事件线 #define KEY1_IRQN EXTI1_IRQn //中断源 #endif#if isEnableKey2 //定义KEY2按键引脚以及中断 #define KEY2_GPIO_CLK RCC_APB2Periph_GPIOC //使能时钟端口 #define KEY2_GPIO_PORT GPIOC //KEY2端口 #define KEY2_GPIO_PIN GPIO_Pin_5 //KEY2引脚 #define KEY2_GPIO_EXTI_PORT_SOURCE GPIO_PortSourceGPIOC //外部中断源端口 #define KEY2_GPIO_EXTI_PIN_SOURCE GPIO_PinSource5 //外部中断源引脚 #define KEY2_EXTI_LINE EXTI_Line5 //EXTI事件线 #define KEY2_IRQN EXTI9_5_IRQn //中断源 #endif#if isEnableKey3 //定义KEY3按键引脚以及中断 #define KEY3_GPIO_CLK RCC_APB2Periph_GPIOC //使能时钟端口 #define KEY3_GPIO_PORT GPIOC //KEY3端口 #define KEY3_GPIO_PIN GPIO_Pin_4 //KEY3引脚 #define KEY3_GPIO_EXTI_PORT_SOURCE GPIO_PortSourceGPIOC //外部中断源端口 #define KEY3_GPIO_EXTI_PIN_SOURCE GPIO_PinSource4 //外部中断源引脚 #define KEY3_EXTI_LINE EXTI_Line4 //EXTI事件线 #define KEY3_IRQN EXTI4_IRQn //中断源 #endif#if isEnableKey4 //定义KEY4按键引脚以及中断 #define KEY4_GPIO_CLK RCC_APB2Periph_GPIOA //使能时钟端口 #define KEY4_GPIO_PORT GPIOA //KEY4端口 #define KEY4_GPIO_PIN GPIO_Pin_0 //KEY4引脚 #define KEY4_GPIO_EXTI_PORT_SOURCE GPIO_PortSourceGPIOA //外部中断源端口 #define KEY4_GPIO_EXTI_PIN_SOURCE GPIO_PinSource0 //外部中断源引脚 #define KEY4_EXTI_LINE EXTI_Line0 //EXTI事件线 #define KEY4_IRQN EXTI0_IRQn //中断源 #endif//定义读取按键状态 #if isEnableKey1 #define KEY1 GPIO_ReadInputDataBit(KEY1_GPIO_PORT,KEY1_GPIO_PIN) //读取按键 LEFT #endif#if isEnableKey2 #define KEY2 GPIO_ReadInputDataBit(KEY2_GPIO_PORT,KEY2_GPIO_PIN) //读取按键 RIGHT #endif#if isEnableKey3 #define KEY3 GPIO_ReadInputDataBit(KEY3_GPIO_PORT,KEY3_GPIO_PIN) //读取按键 DOWN #endif#if isEnableKey4 #define KEY4 GPIO_ReadInputDataBit(KEY4_GPIO_PORT,KEY4_GPIO_PIN) //读取按键 WAKEUP #endif/******** 定义返回值状态 **********/ #if isEnableKey1 //KEY1返回值 #define KEY1_ShortPress_Value 0x0001 //短按 #define KEY1_LongPress_Value 0x0002 //长按 #define KEY1_DoubleClick_Value 0x0004 //双击 #endif#if isEnableKey2 //KEY2返回值 #define KEY2_ShortPress_Value 0x0010 //短按 #define KEY2_LongPress_Value 0x0020 //长按 #define KEY2_DoubleClick_Value 0x0040 //双击 #endif#if isEnableKey3 //KEY3返回值 #define KEY3_ShortPress_Value 0x0100 //短按 #define KEY3_LongPress_Value 0x0200 //长按 #define KEY3_DoubleClick_Value 0x0400 //双击 #endif#if isEnableKey4 //KEY4返回值 #define KEY4_ShortPress_Value 0x1000 //短按 #define KEY4_LongPress_Value 0x2000 //长按 #define KEY4_DoubleClick_Value 0x4000 //双击 #endif/**************** 函数部分 ********************/ void Key_Init(void); //初始化按键 void Key_Scan(void); //检测按键是否按下 uint16_t GetKeyNum(void); //返回按键值#endif 注意的是delay.h中是笔者写的简单的延迟函数自行使用大家的延迟函数即可只在消抖处用到了延时函数其余部分没用用到。其次中断处理双击中又嵌套了两个if else时间上有点大有点屎山代码的味道了目前能想到的是开一个定时器每当符合双击第一次时开启计数器当检测到双击第二次时停止计数器在2s内算是符合双击操作否则丢弃当然这只是笔者目前的想法后续笔者会完善以下。 key.c #include key.h #include delay.h #include time2.h/*** 最终返回状态值 长按 短按 ***/ uint16_t Key_Value 0x0000;/*** 记录上次最终返回状态值 ***/ uint16_t Old_Key_Value 0x0000;//初次进入中断标志位 uint8_t Key_IT_Flag 0;//初级进入双击标志位 uint8_t DoubleClickFlag 0;//记录上次按键的值 uint16_t Old_KeyNum 0x0000;/***按键按下宏定义***/ #if isEnableKey1 static uint8_t Key1_Press 0; #endif#if isEnableKey2 static uint8_t Key2_Press 0; #endif#if isEnableKey3 static uint8_t Key3_Press 0; #endif#if isEnableKey4 static uint8_t Key4_Press 0; #endif/***** * func : Key_Init(void) * describe : 初始化按键 外部中断 以及嵌套向量中断控制器 * param : void * return : void * note : 移植时除了控制优先级和子优先级在此处需改外其他不需要修改这里 *****/ void Key_Init(void) {//定义GPIO结构体GPIO_InitTypeDef GPIO_InitStructure;//定义外部中断EXTI机构体EXTI_InitTypeDef EXTI_InitStructure;//定义嵌套向量中断控制器NVIC结构体NVIC_InitTypeDef NVIC_InitStructure;//使能时钟#if isEnableKey1RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK,ENABLE); //key1所在的时钟#endif#if isEnableKey2RCC_APB2PeriphClockCmd(KEY2_GPIO_CLK,ENABLE); //key2所在的时钟#endif#if isEnableKey3RCC_APB2PeriphClockCmd(KEY3_GPIO_CLK,ENABLE); //key3所在的时钟#endif#if isEnableKey4RCC_APB2PeriphClockCmd(KEY4_GPIO_CLK,ENABLE); //key4所在的时钟#endifRCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//配置KEYGPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU;#if isEnableKey1GPIO_InitStructure.GPIO_Pin KEY1_GPIO_PIN;GPIO_Init(KEY1_GPIO_PORT,GPIO_InitStructure);#endif#if isEnableKey2GPIO_InitStructure.GPIO_Pin KEY2_GPIO_PIN;GPIO_Init(KEY2_GPIO_PORT,GPIO_InitStructure);#endif#if isEnableKey3GPIO_InitStructure.GPIO_Pin KEY3_GPIO_PIN;GPIO_Init(KEY3_GPIO_PORT,GPIO_InitStructure);#endif#if isEnableKey4GPIO_InitStructure.GPIO_Pin KEY4_GPIO_PIN;GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPD;GPIO_Init(KEY4_GPIO_PORT,GPIO_InitStructure);#endif#if isEnableKey1//配置KEY1外部中断及嵌套向量中断控制器GPIO_EXTILineConfig(KEY1_GPIO_EXTI_PORT_SOURCE,KEY1_GPIO_EXTI_PIN_SOURCE); //选择EXTI的信号源EXTI_InitStructure.EXTI_Line KEY1_EXTI_LINE; //选择EXTI事件线EXTI_InitStructure.EXTI_Mode EXTI_Mode_Interrupt; //EXTI中断模式EXTI_InitStructure.EXTI_Trigger EXTI_Trigger_Rising_Falling; //双边沿中断EXTI_InitStructure.EXTI_LineCmd ENABLE; //使能中断EXTI_Init(EXTI_InitStructure);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置优先级分组NVIC_InitStructure.NVIC_IRQChannel KEY1_IRQN; //中断源NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; //使能中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 2; //抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority 1; //子优先级NVIC_Init(NVIC_InitStructure);#endif#if isEnableKey2//配置KEY2外部中断及嵌套向量中断控制器GPIO_EXTILineConfig(KEY2_GPIO_EXTI_PORT_SOURCE,KEY2_GPIO_EXTI_PIN_SOURCE); //选择EXTI的信号源EXTI_InitStructure.EXTI_Line KEY2_EXTI_LINE; //选择EXTI事件线EXTI_InitStructure.EXTI_Mode EXTI_Mode_Interrupt; //EXTI中断模式EXTI_InitStructure.EXTI_Trigger EXTI_Trigger_Rising_Falling; //双边沿中断EXTI_InitStructure.EXTI_LineCmd ENABLE; //使能中断EXTI_Init(EXTI_InitStructure);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置优先级分组NVIC_InitStructure.NVIC_IRQChannel KEY2_IRQN; //中断源NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; //使能中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 2; //抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority 1; //子优先级NVIC_Init(NVIC_InitStructure);#endif#if isEnableKey3//配置KEY3外部中断及嵌套向量中断控制器GPIO_EXTILineConfig(KEY3_GPIO_EXTI_PORT_SOURCE,KEY3_GPIO_EXTI_PIN_SOURCE); //选择EXTI的信号源EXTI_InitStructure.EXTI_Line KEY3_EXTI_LINE; //选择EXTI事件线EXTI_InitStructure.EXTI_Mode EXTI_Mode_Interrupt; //EXTI中断模式EXTI_InitStructure.EXTI_Trigger EXTI_Trigger_Rising_Falling; //双边沿中断EXTI_InitStructure.EXTI_LineCmd ENABLE; //使能中断EXTI_Init(EXTI_InitStructure);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置优先级分组NVIC_InitStructure.NVIC_IRQChannel KEY3_IRQN; //中断源NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; //使能中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 2; //抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority 1; //子优先级NVIC_Init(NVIC_InitStructure);#endif#if isEnableKey4//配置KEY4外部中断及嵌套向量中断控制器GPIO_EXTILineConfig(KEY4_GPIO_EXTI_PORT_SOURCE,KEY4_GPIO_EXTI_PIN_SOURCE); //选择EXTI的信号源EXTI_InitStructure.EXTI_Line KEY4_EXTI_LINE; //选择EXTI事件线EXTI_InitStructure.EXTI_Mode EXTI_Mode_Interrupt; //EXTI中断模式EXTI_InitStructure.EXTI_Trigger EXTI_Trigger_Rising_Falling; //双边沿中断EXTI_InitStructure.EXTI_LineCmd ENABLE; //使能中断EXTI_Init(EXTI_InitStructure);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置优先级分组NVIC_InitStructure.NVIC_IRQChannel KEY4_IRQN; //中断源NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; //使能中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 2; //抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority 1; //子优先级NVIC_Init(NVIC_InitStructure);#endif }/***** * func : Key_Scan(void) * describe : 检测按键状态 * param : void * return : void * note : 1 按下按键 0 松开按键 *****/ void Key_Scan(void) {#if isEnableKey1if(KEY1 RESET) //检测到按键1{delay_ms(20); //消抖if(KEY1 RESET) //再次检测按键1{Key1_Press 1; //记录此时按键状态}}elseKey1_Press 0;#endif#if isEnableKey2if(KEY2 RESET) //检测到按键2{delay_ms(20); //消抖if(KEY2 RESET) //再次检测按键2Key2_Press 1; //记录此时按键状态}elseKey2_Press 0;#endif#if isEnableKey3if(KEY3 RESET) //检测到按键3{delay_ms(20); //消抖if(KEY3 RESET) //再次检测按键3Key3_Press 1; //记录此时按键状态}elseKey3_Press 0;#endif#if isEnableKey4if(KEY4 SET) //检测到按键4 注意的是按键四是高电平检测到按键按下{delay_ms(20); //消抖if(KEY4 SET) //再次检测按键4Key4_Press 1; //记录此时按键状态}elseKey4_Press 0;#endif }/***** * func : GetKeyNum(void) * describe : 返回按键值 * param : void * return : 按键值 * ret : 11 按键1短按; 12 按键1长按; 13 按键1双击 * ret : 21 按键2短按; 22 按键2长按; 23 按键2双击 * ret : 31 按键3短按; 32 按键3长按; 33 按键3双击 * ret : 41 按键4短按; 42 按键4长按; 43 按键4双击 * note : 返回值如 xx 形式 * 其十位代表按键几 个位则代表长短双击, 1 短按 2 长按 3 双击 *****/ uint16_t GetKeyNum(void) {//最终返回值static uint8_t keyNum 0;Key_Scan();if(!Key_IT_Flag){switch(Key_Value){#if isEnableKey1case 0x0001:keyNum 11; //按键1短按Old_Key_Value Key_Value;Key_Value 0x0000;break;case 0x0002:keyNum 12; //按键1长按Old_Key_Value Key_Value;Key_Value 0x0000;break;case 0x0004:keyNum 14; //按键1双击Old_Key_Value 0x0000;Key_Value 0x0000;break;#endif#if isEnableKey2case 0x0010:keyNum 21; //按键2短按Old_Key_Value Key_Value;Key_Value 0x0000;break;case 0x0020:keyNum 22; //按键2长按Old_Key_Value Key_Value;Key_Value 0x0000;break;case 0x0040:keyNum 24; //按键2双击Old_Key_Value 0x0000;Key_Value 0x0000;break;#endif#if isEnableKey3case 0x0100:keyNum 31; //按键3短按Old_Key_Value Key_Value;Key_Value 0x0000;break;case 0x0200:keyNum 32; //按键3长按Old_Key_Value Key_Value;Key_Value 0x0000;break;case 0x0400:keyNum 34; //按键3双击Old_Key_Value 0x0000;Key_Value 0x0000;break;#endif#if isEnableKey4case 0x1000:keyNum 41; //按键4短按Old_Key_Value Key_Value;Key_Value 0x0000;break;case 0x2000:keyNum 42; //按键4长按Old_Key_Value Key_Value;Key_Value 0x0000;break;case 0x4000:keyNum 44; //按键4双击Old_Key_Value 0x0000;Key_Value 0x0000;break;#endifdefault:keyNum 0;Key_Value 0x0000;break;}}return keyNum; }#if isEnableKey1 /***** * func : EXTI1_IRQHandler() * describe : 中断函数 * param : void * return : void * note : 中断需要的处理的操作在此处执行 *****/ void EXTI1_IRQHandler() {static uint8_t Key1State 0; //静态按键1状态 0 松开 1按下if(EXTI_GetITStatus(KEY1_EXTI_LINE) ! RESET){if(Key1_Press Key1State) //松开按键{Key1State 0; //松开标志Key_IT_Flag 0; //退出中断标志位TIM_Cmd(TIM2,DISABLE); //关闭时钟if(Time_Count 0 Time_Count 20) //短按时间判断{if(!DoubleClickFlag) //第一次双击按下{DoubleClickFlag 1; //改变标志位Old_KeyNum | KEY1_DoubleClick_Value; //记录按下值Old_Key_Value Old_KeyNum; //记录上次返回的状态值}else {Old_KeyNum 0x0000; //清除记录Old_KeyNum | KEY1_DoubleClick_Value; //更新上一次的值if(Old_Key_Value ! Old_KeyNum) //上次最终返回的状态值与记录第一次双击按下值不一致Old_Key_Value Old_KeyNum; //更新最后返回状态值 else{DoubleClickFlag 0; //重置双击按下标志位Old_Key_Value 0x0000; //重置最后返回状态Old_KeyNum 0x0000; //重置按下值Key_Value | KEY1_DoubleClick_Value; //双击返回状态值}}}else if(Time_Count 20 Time_Count 40) //短按时间判断Key_Value | KEY1_ShortPress_Value; //短按时间返回状态值else if(Time_Count 40) //长按时间判断Key_Value | KEY1_LongPress_Value; //长按时间返回状态值// printf(Time_Count : %d\n,Time_Count); //测试时使用} else if(!Key_IT_Flag !Key1State) //按下按键{Key1State 1; //按下标志位Key_IT_Flag 1; //已进入中断标志位Time_Count 0; //每次按下从0开始计时TIM_Cmd(TIM2,ENABLE); //开启时钟}EXTI_ClearITPendingBit(KEY1_EXTI_LINE); //清除中断标志位} }#endif#if isEnableKey2 /***** * func : EXTI9_5_IRQHandler() * describe : 中断函数 * param : void * return : void * note : 中断需要的处理的操作在此处执行 *****/ void EXTI9_5_IRQHandler() {static uint8_t Key2State 0; //静态按键1状态 0 松开 1按下if(EXTI_GetITStatus(KEY2_EXTI_LINE) ! RESET){if(Key2_Press Key2State) //松开按键{Key2State 0; //松开标志Key_IT_Flag 0; //退出中断标志位TIM_Cmd(TIM2,DISABLE); //关闭时钟if(Time_Count 0 Time_Count 20) //短按时间判断{if(!DoubleClickFlag) //第一次双击按下{DoubleClickFlag 1; //改变标志位Old_KeyNum | KEY2_DoubleClick_Value; //记录按下值Old_Key_Value Old_KeyNum; //记录上次返回的状态值}else {Old_KeyNum 0x0000; //清除记录Old_KeyNum | KEY2_DoubleClick_Value; //更新上一次的值if(Old_Key_Value ! Old_KeyNum) //上次最终返回的状态值与记录第一次双击按下值不一致Old_Key_Value Old_KeyNum; //更新最后返回状态值 else{DoubleClickFlag 0; //重置双击按下标志位Old_Key_Value 0x0000; //重置最后返回状态Old_KeyNum 0x0000; //重置按下值Key_Value | KEY2_DoubleClick_Value; //双击返回状态值}}}else if(Time_Count 20 Time_Count 40) //短按时间判断Key_Value | KEY2_ShortPress_Value; //短按时间返回状态值else if(Time_Count 40) //长按时间判断Key_Value | KEY2_LongPress_Value; //长按时间返回状态值// printf(Time_Count : %d\n,Time_Count); //测试时使用} else if(!Key_IT_Flag !Key2State) //按下按键{Key2State 1; //按下标志位Key_IT_Flag 1; //已进入中断标志位Time_Count 0; //每次按下从0开始计时TIM_Cmd(TIM2,ENABLE); //开启时钟}EXTI_ClearITPendingBit(KEY2_EXTI_LINE); //清除中断标志位} }#endif#if isEnableKey3 /***** * func : EXTI4_IRQHandler() * describe : 中断函数 * param : void * return : void * note : 中断需要的处理的操作在此处执行 *****/ void EXTI4_IRQHandler() {static uint8_t Key3State 0; //静态按键1状态 0 松开 1按下if(EXTI_GetITStatus(KEY3_EXTI_LINE) ! RESET){if(Key3_Press Key3State) //松开按键{Key3State 0; //松开标志Key_IT_Flag 0; //退出中断标志位TIM_Cmd(TIM2,DISABLE); //关闭时钟if(Time_Count 0 Time_Count 20) //短按时间判断{if(!DoubleClickFlag) //第一次双击按下{DoubleClickFlag 1; //改变标志位Old_KeyNum | KEY3_DoubleClick_Value; //记录按下值Old_Key_Value Old_KeyNum; //记录上次返回的状态值}else {Old_KeyNum 0x0000; //清除记录Old_KeyNum | KEY3_DoubleClick_Value; //更新上一次的值if(Old_Key_Value ! Old_KeyNum) //上次最终返回的状态值与记录第一次双击按下值不一致Old_Key_Value Old_KeyNum; //更新最后返回状态值 else{DoubleClickFlag 0; //重置双击按下标志位Old_Key_Value 0x0000; //重置最后返回状态Old_KeyNum 0x0000; //重置按下值Key_Value | KEY3_DoubleClick_Value; //双击返回状态值}}}else if(Time_Count 20 Time_Count 40) //短按时间判断Key_Value | KEY3_ShortPress_Value; //短按时间返回状态值else if(Time_Count 40) //长按时间判断Key_Value | KEY3_LongPress_Value; //长按时间返回状态值// printf(Time_Count : %d\n,Time_Count); //测试时使用} else if(!Key_IT_Flag !Key3State) //按下按键{Key3State 1; //按下标志位Key_IT_Flag 1; //已进入中断标志位Time_Count 0; //每次按下从0开始计时TIM_Cmd(TIM2,ENABLE); //开启时钟}EXTI_ClearITPendingBit(KEY3_EXTI_LINE); //清除中断标志位} }#endif#if isEnableKey4 /***** * func : EXTI0_IRQHandler() * describe : 中断函数 * param : void * return : void * note : 中断需要的处理的操作在此处执行 *****/ void EXTI0_IRQHandler() {static uint8_t Key4State 0; //静态按键1状态 0 松开 1按下if(EXTI_GetITStatus(KEY4_EXTI_LINE) ! RESET){if(Key4_Press Key4State) //松开按键{Key4State 0; //松开标志Key_IT_Flag 0; //退出中断标志位TIM_Cmd(TIM2,DISABLE); //关闭时钟if(Time_Count 0 Time_Count 20) //短按时间判断{if(!DoubleClickFlag) //第一次双击按下{DoubleClickFlag 1; //改变标志位Old_KeyNum | KEY4_DoubleClick_Value; //记录按下值Old_Key_Value Old_KeyNum; //记录上次返回的状态值}else {Old_KeyNum 0x0000; //清除记录Old_KeyNum | KEY4_DoubleClick_Value; //更新上一次的值if(Old_Key_Value ! Old_KeyNum) //上次最终返回的状态值与记录第一次双击按下值不一致Old_Key_Value Old_KeyNum; //更新最后返回状态值 else{DoubleClickFlag 0; //重置双击按下标志位Old_Key_Value 0x0000; //重置最后返回状态Old_KeyNum 0x0000; //重置按下值Key_Value | KEY4_DoubleClick_Value; //双击返回状态值}}}else if(Time_Count 20 Time_Count 40) //短按时间判断Key_Value | KEY4_ShortPress_Value; //短按时间返回状态值else if(Time_Count 40) //长按时间判断Key_Value | KEY4_LongPress_Value; //长按时间返回状态值// printf(Time_Count : %d\n,Time_Count); //测试时使用} else if(!Key_IT_Flag !Key4State) //按下按键{Key4State 1; //按下标志位Key_IT_Flag 1; //已进入中断标志位Time_Count 0; //每次按下从0开始计时TIM_Cmd(TIM2,ENABLE); //开启时钟}EXTI_ClearITPendingBit(KEY4_EXTI_LINE); //清除中断标志位} }#endif 最后main函数代码进行测试大家注意的是需要对printf函数进行重写。 main.c #include stm32f10x.h #include sys.h #include usart.h #include key.h #include time2.hint main() {uint16_t keyNum 0;USART1_Init(115200); //初始化USARTTIME2_Init(10000,72); //初始TIM2Key_Init(); //按键初始化while(1){keyNum GetKeyNum();switch(keyNum){case 11:printf(按键1短按\n);printf(短按返回值 keyNum %2d\n,keyNum);puts();break;case 12:printf(按键1长按\n);printf(长按返回值 keyNum %2d\n,keyNum);puts();break;case 14:printf(按键1双击\n);printf(双击返回值 keyNum %2d\n,keyNum);puts();break;case 21:printf(按键2短按\n);printf(短按返回值 keyNum %2d\n,keyNum);puts();break;case 22:printf(按键2长按\n);printf(长按返回值 keyNum %2d\n,keyNum);puts();break;case 24:printf(按键2双击\n);printf(双击返回值 keyNum %2d\n,keyNum);puts();break;case 31:printf(按键3短按\n);printf(短按返回值 keyNum %2d\n,keyNum);puts();break;case 32:printf(按键3长按\n);printf(长按返回值 keyNum %2d\n,keyNum);puts();break;case 34:printf(按键3双击\n);printf(双击返回值 keyNum %2d\n,keyNum);puts();break;case 41:printf(按键4短按\n);printf(短按返回值 keyNum %2d\n,keyNum);puts();break;case 42:printf(按键4长按\n);printf(长按返回值 keyNum %2d\n,keyNum);puts();break;case 44:printf(按键4双击\n);printf(双击返回值 keyNum %2d\n,keyNum);puts();break;default:break;}} } 最后的最后献上测试截图感谢大家的观看。
http://www.tj-hxxt.cn/news/139751.html

相关文章:

  • 网页制作与网站建设宝典扫描版pdf百万网站建设报价
  • 常州微信网站建设咨询东莞网站建站推广
  • 长沙免费建站模板专业柳州网站建设哪家便宜
  • 干净简约的网站怎么做网站支付
  • 电子商务网站建设特点网上商城网站建设报价
  • ps网站导航条素材seo怎么做网站优秀案例
  • 做自媒体都有什么网站下载黑龙江建设网官网网站
  • 国内免费推广网站如何做网站改版
  • wordpress阿里云云存储绵阳做网站优化
  • 盘锦做网站选哪家已有备案号新增网站备案要关闭原先的站点吗
  • 烟台网站排名优化一级造价工程师报名时间
  • 漳浦县城乡规划建设局官方网站松原市建设局网站投诉中心
  • 电子商务网站与建设课件开发一个app需要什么条件
  • 网站内容编写方法企业为什么做网站素材
  • 襄樊市网站建设公司安徽手机网站建设
  • 网站的二级目录怎么做招聘简历模板
  • 广东省住房城乡建设厅网站爱站网工具包
  • 危险网站提示wordpress 获取当前文章栏目链接
  • apple私人免费网站怎么下载深圳网络推广培训中心
  • 如何把网站放到域名上台州建设质量监督网站
  • 高校精神文明建设网站做网站会员功能
  • 北京建网站公司飞沐wordpress dropship
  • php网站投票源码网站集约化建设标准
  • 皮具网站建设服装网站外包加工网会员
  • 石碣东莞网站建设wordpress3.8
  • wordpress哪个版本 最快怎样优化网站自然排名
  • 软件下载网站如何履行安全管理义务建设银行网站可以查询存折吗
  • 怎么做外国网站公司网络推广培训
  • 专科网站开发简历郑州艾特软件 网站建设
  • 南宁学做网站微信引流的十个方法