找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4417|回复: 0
打印 上一主题 下一主题
收起左侧

STM32 GPIO按键检测技术(按键复用源码)

[复制链接]
跳转到指定楼层
楼主
自己刚刚学STM32一个礼拜,学完了GPIO,尝试自己写了按键的检测,最简单的单击,
能准确的识别每一次,再到双击(其实多击逻辑一样),长按等复用模式。
这里提一下按键复用的思想:其实在做产品的时候,有复用思想可以节约按键,降低后期产品的PCB体积大小
具体的STM32实现的功能我简述下,刚刚入门的萌新可以看下,写的一般。
(1)环境复用:这个简单,就是不同环境设置不同标志量即可
(2)组合复用:这里就是通过按两次实现一个组合的效果,当然你写复杂了有许多组合的效果,我这个小程序主要是在220ms内连续
按下两次,PC13口连接的LED会闪烁2.5s,间隔是50ms。
(3)时间复用:就是长按,通过按键时间的长短实现不同功能。(长按复位,其中STM32的复位必须先关闭中断,再调用NVIC中的复位函数
因为复位前有个延时,会影响复位的效果)
注:如果能用TIM(定时器)检测按键,实现按键效果,更加perfect
萌新们一定要学会自己建立STM32工程哟


这是我的通过按键来实现不同功能的灯亮的实验。
1.主要用到GPIO输入与输出的技术。
2.按键的复用功能
(1).环境复用:这个简单,不同标志下实现不同功能,这里就不做功能实现了。
(2).组合复用:连续两次按键(220ms连续按两次),实现Led亮灭2.5s,亮灭间隔为50ms。
(3).时间切换:单次按键实现的Led的亮灭,长按实现STM32MicroController系统的复位。

单片机源程序如下:
  1. #include <STM32F10X.H>
  2. #include <misc.h>

  3. #define PC14 GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_14)           //独C14按键的值
  4. #define PC15_On GPIO_SetBits(GPIOC,GPIO_Pin_15)                  //Set是置1
  5. #define PC15_Off GPIO_ResetBits(GPIOC,GPIO_Pin_15)               //Reset置0
  6. #define PC13_Off GPIO_SetBits(GPIOC,GPIO_Pin_13)                 //Set是置1
  7. #define PC13_On GPIO_ResetBits(GPIOC,GPIO_Pin_13)                //Reset置0

  8. u16 Led_Count=0,Button_Flag=0,time=0;
  9. void RCC_Configuration(void);     //复位与时钟寄存器初始化函数
  10. void Delay_ms(u16 n);             //延时函数ms
  11. void GPIO_Configuration(void);    //通用IO口初始化函数
  12. void System_Reset(void);          //系统复位函数
  13. void Led_Show(void);              //Led亮灭显示函数
  14. u16 Key_Mode(u16 time);           //时间复用模式
  15. void Group_Button(void);          //组合复用模式(双击,多击鼠标的检测函数)



  16. int main(void)
  17. {
  18.         RCC_Configuration();
  19.         GPIO_Configuration();
  20.         while(1)
  21.         {
  22.                 switch(Key_Mode(100))
  23.                 {
  24.                         case 0:break;
  25.                         case 1:Led_Show();break;
  26.                         case 2:System_Reset();break;
  27.                         default:break;
  28.                 }
  29.                 Group_Button();
  30.         }
  31. }
  32.         
  33. void RCC_Configuration(void)
  34. {
  35.         SystemInit();
  36. }

  37. void Delay_ms(u16 n)
  38. {
  39.         u16 i;
  40.         while(n--)
  41.         {
  42.                 i=12000;
  43.                 while(i--);
  44.         }
  45. }

  46. void GPIO_Configuration(void)
  47. {
  48.         //配置按键输出的工作模式,同组的同类型一次配置,同组不同类型分次配置
  49.         GPIO_InitTypeDef GPIO_InitStructure;
  50.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
  51.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_15;
  52.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
  53.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  54.         GPIO_Init(GPIOC,&GPIO_InitStructure);
  55.         
  56.         //配置按键输入的工作模式
  57.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_14;
  58.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
  59.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  60.         GPIO_Init(GPIOC,&GPIO_InitStructure);
  61.         
  62.         PC15_Off;PC13_Off;
  63. }

  64. void System_Reset(void)                                                //系统软件复位函数
  65. {
  66.         PC13_On;
  67.         Delay_ms(500);
  68.         __set_FAULTMASK(1);                                                        //首先先要关闭中断
  69.         NVIC_SystemReset();                                     //在进行软复位
  70. }

  71. u16 Key_Mode(u16 time)                        //独立按键函数
  72. {
  73.         u16 i=0;
  74.         if(PC14 == 0)
  75.         {
  76.                 Delay_ms(10);
  77.                 if(PC14 == 0)
  78.                 {
  79.                         while(!PC14)
  80.                         {
  81.                                 Delay_ms(10);i++;
  82.                         }
  83.                         Button_Flag++;
  84.                 }
  85.         }
  86.         if(i == 0)
  87.                 return 0;
  88.         else
  89.         {
  90.                 if(i < time)
  91.                         return 1;
  92.                 else
  93.                         return 2;
  94.         }
  95. }

  96. void Led_Show(void)
  97. {
  98.         Led_Count++;
  99.         if(Led_Count == 1)
  100.         PC15_On;
  101.         else
  102.         {
  103.                 PC15_Off;Led_Count=0;
  104.         }
  105. }

  106. void Group_Button(void)                                                                //双击鼠标和多击鼠标的模块写出来了,后期用定时器系统能干其他的事情
  107. {                                                                                                                                                        //其实单片机是单线程,所谓的中断无非是效率更高,其实主程序仍不能干其他事情
  108.         u16 i=0;
  109.         if(Button_Flag == 1)
  110.         {
  111.                 PC13_On;Delay_ms(1);time++;
  112.         }
  113.         else
  114.         {
  115.                 Button_Flag = 0;PC13_Off;
  116.                 if(time < 220 && time > 5)
  117.                 {
  118.                         time = 0;
  119.                         for(i=0;i<50;i++)
  120.                         {
  121.                                 if(i%2 == 0)
  122.                                 {PC13_On;Delay_ms(50);}
  123.                                 else
  124.                                 {PC13_Off;Delay_ms(50);}
  125.                         }
  126.                 }
  127.                 else time = 0;
  128.         }               
  129. }
复制代码

所有资料51hei提供下载:
DetectKey.7z (191.26 KB, 下载次数: 26)


评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表