打印
[STM32F1]

STM32F103ZET6【标准库函数开发】--按键输入

[复制链接]
368|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
1.硬件电路如下
  
如图,因为key0,key1,key2通过开关和GND连接在一起,所以对应的PE4,PE3,PE2要设置为上拉输入;同理,WK_UP通过开关和VCC3.3连接在一起,所以对应的PA0要设置为下拉输入。想要实现的功能就是通过按键控制led亮灭。


2.知识储备:STM32有四种输出模式和四种输入模式


3.代码编写
3.1宏定义
//宏定义
#define KEY0    GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)//读取按键0 GPIOE.4
#define KEY1    GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)//读取按键1 GPIOE.3
#define KEY2    GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)//读取按键2 GPIOE.2
#define WK_UP   GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键3(WK_UP)   GPIOA.0

#define KEY0_PRES         1        //KEY0按下
#define KEY1_PRES        2        //KEY1按下
#define KEY2_PRES        3        //KEY2按下
#define WKUP_PRES   4        //KEY_UP按下(即WK_UP/KEY_UP)

void KEY_Init(void);//IO初始化
u8 KEY_Scan(u8);          //按键扫描函数                                            
#endif
3.2定义子函数
//按键初始化函数
void KEY_Init(void) //IO初始化
{
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//使能PORTA,PORTE时钟
       
    //初始化KEY0,KEY1,KEY2--->PE4,PE3,PE2  上拉输入       
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;//选择引脚
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
        GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4

        //初始化 WK_UP-->GPIOA.0          下拉输入
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;//选择引脚
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉          
        GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0
}
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,KEY0按下
//2,KEY1按下
//3,KEY2按下
//4,KEY3按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2>KEY3!!
u8 KEY_Scan(u8 mode)
{         
        static u8 key_up=1;//按键按松开标志
        if(mode)key_up=1;  //支持连按                  
        if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
        {
                delay_ms(10);//去抖动
                key_up=0;
                if(KEY0==0)return KEY0_PRES;
                else if(KEY1==0)return KEY1_PRES;
                else if(KEY2==0)return KEY2_PRES;
                else if(WK_UP==1)return WKUP_PRES;
        }else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;             
        return 0;// 无按键按下
}
3.3主函数
 //主函数
int main(void)
{
        vu8 key=0;       
        delay_init();                     //延时函数初始化          
        LED_Init();                             //LED端口初始化
        KEY_Init();                   //初始化与按键连接的硬件接口
        while(1)
        {
                key=KEY_Scan(0);        //得到键值
                   if(key)
                {                                                  
                        switch(key)
                        {                                 
                                case WKUP_PRES:        //控制LED0翻转
                                        LED0=!LED0;
                                        break;
                                case KEY2_PRES:        //控制LED1翻转
                                        LED1=!LED1;
                                        break;
                                case KEY1_PRES:        //LED0,LED1点亮         
                                        LED0=0;
                                        LED1=0;
                                        break;
                                case KEY0_PRES:        //LED0,LED熄灭
                                        LED0=1;
                                        LED1=1;
                                        break;
                        }
                }else delay_ms(10);
        }         
}
PS:1.按键处理函数是正点原子历程里面的,封装的极好,可以当作一个库,直接来调用
2.这个按键处理函数是有优先级的,KEY0>KEY1>KEY2>KEY3,也就是说假如同时按下KEY0,KEY1,KEY2,KEY3,执行的谁KEY0,因为在执行判断语句的时候,KEY0在最前面。

使用特权

评论回复
沙发
捉虫天师| | 2020-11-4 21:21 | 只看该作者
标准库挺好用的啊

使用特权

评论回复
板凳
王小琪|  楼主 | 2020-11-4 21:25 | 只看该作者

见仁见智吧,熟练度起来了用寄存器/标准库/HAL库都好用,但熟练的这个过程很痛苦。

使用特权

评论回复
地板
捉虫天师| | 2020-11-4 21:38 | 只看该作者
王小琪 发表于 2020-11-4 21:25
见仁见智吧,熟练度起来了用寄存器/标准库/HAL库都好用,但熟练的这个过程很痛苦。 ...

是的,听说最新的是LL库

使用特权

评论回复
5
王小琪|  楼主 | 2020-11-4 21:42 | 只看该作者
捉虫天师 发表于 2020-11-4 21:38
是的,听说最新的是LL库

LL库没用过,我只用过标准库,最近在学习HAL库,因为可以用CUBEMX生成,而且新的片子都不支持标准库了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

227

主题

578

帖子

6

粉丝