找回密码
 立即注册

QQ登录

只需一步,快速开始

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

stm32键盘扫描简单实现

[复制链接]
跳转到指定楼层
楼主
ID:89763 发表于 2015-9-10 01:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天上午一个人在实验室,想到昨天学的键盘扫瞄可能不是很熟练,又尝试自己写一个。还是利用led的demo工程,实现按两个按键改变LED工作状态,硬件接线(简单的就不上图了)PA0接KEY3,PA1接KEY4,LED1接PA2,LED2接PB2,LED接PA3,按下KEY3灯从LED1至LED3依次点亮后熄灭,按下KEY4则LED1至LED3一起闪三下,按键不松开不响应(因为一直等待松开),在上一次响应完成前按键无效(因为这时候没有扫描),这是最简单的方式,供初学者参考指正stm32键盘扫描简单实现,其实很简单,GPIO配置少不了,把灯的IO配置为推挽输出,即GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP就可以了,键盘输入就将PA0和PA1设置为上拉输入,即GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU,那么问题来了,怎么读取键值呢?学过51的都知道,51的位操作非常方便,读取直接sbit key P1.0然后对key写入读取就和变量一样简单了,那么stm32怎么读入键值呢?会用到一个函数,就是GPIO_ReadInputDataBit(),一次读取一个IO口的值,用法也很简单,传入两个参数,一个IO口组,一个IO位置,比如读入PA0就是key=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0),这样就可以将PA0的状态赋值给key这个变量,由于只上拉输入,所以按键时读入为0;其他的就没什么了,用到了GPIO口就当然使能相应的时钟。
在网上看了一些实例,用宏定义可以减伤很多麻烦, 不用每次读入键值都打那么长一段,直接宏定义一下#define KEY3 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
这样就可以很方便地读取键值,和51一样有没有!stm32键盘扫描简单实现
有兴趣可以看一下,按键点灯最没有技术含量的实现,没中断没定时器,学过51就能写stm32键盘扫描简单实现除此之外没有别的文件和函数额,建好工程一添加就可以,固件库是V3.5
附上代码:
KEY.h:
#ifndef _KEY_H_       //避免重复引用
#define KEY_H_
#define KEY3 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)   //方便读入键值
#define KEY4 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)

#include"stm32f10x.h"
#include"stm32f10x_gpio.h"
void delay_ms(uint32_t nms);   //延时函数
void Key_Init(void);            //键盘初始化
uint32_t KeyScan(void);      //键盘扫描
#endif

KEY.c:
#include"KEY.h"
void Key_Init()                 
{
    GPIO_InitTypeDef GPIO_InitStructure;     //定义初始化结构体
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能GPIOA
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;           //设置PA0,PA1为上拉输入
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;    //这个无所谓,不要应该也可以
    GPIO_Init(GPIOA,&GPIO_InitStructure);     //调用初始化函数初始化PA0,PA1
}
uint32_t KeyScan()
{
    if(KEY3==0||KEY4==0)                 //若检测到按下某个键
    {
        delay_ms(10);                    //延时去抖
        if(KEY3==0)                      //若是按键3被按下
        {
            while(KEY3);                   //等待松开
            return 3;
        }
        else if(KEY4==0)
        {
            while(KEY4);
            return 4;
        }
        else return 0;
     }
     else return 0;
}
void delay_ms(uint32_t nms)             //延时函数
{
    uint32_t i;
    while(nms--!=0)
    {
        for(i=18000;i>0;i--);
    }
}

LED.h:

#ifndef _LED_H_
#define _LED_H_
#include"stm32f10x.h"
#include "stm32f10x_gpio.h"
void LEDInit(void);
void LEDLoop(void);
void delayms(uint32_t nms);
#endif


LED.c:


#include"LED.h"
void LEDInit()
{
    GPIO_InitTypeDef GPIO_InitStructure;          //定义初始化结构体
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);   //使能时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;       //推挽输出模式
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;      //响应速度50MHz
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3;   //PA2,PA3
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;          //PB2
    GPIO_Init(GPIOB,&GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);       //熄灭所有LED
    GPIO_SetBits(GPIOB,GPIO_Pin_2);
}
void LEDLoop()                                        //没用到,之前工程建的,抠代码用的
{
    GPIO_ResetBits(GPIOA,GPIO_Pin_2);
    delayms(500);
    GPIO_ResetBits(GPIOB,GPIO_Pin_2);
    delayms(500);
    GPIO_ResetBits(GPIOA,GPIO_Pin_3);
    delayms(500);

    GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
    GPIO_SetBits(GPIOB,GPIO_Pin_2);
    delayms(200);

    GPIO_ResetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
    GPIO_ResetBits(GPIOB,GPIO_Pin_2);
    delayms(200);
    GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
    GPIO_SetBits(GPIOB,GPIO_Pin_2);
    delayms(200);

    GPIO_ResetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
    GPIO_ResetBits(GPIOB,GPIO_Pin_2);
    delayms(200);
    GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
    GPIO_SetBits(GPIOB,GPIO_Pin_2);
    delayms(200);
    GPIO_ResetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
    GPIO_ResetBits(GPIOB,GPIO_Pin_2);
    delayms(200);
    GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
    GPIO_SetBits(GPIOB,GPIO_Pin_2);
    delayms(200);
}
void delayms(uint32_t nms)                   //延时函数
{
    uint32_t i=0;
    for(;nms!=0;nms--)
    {
        i=7200;
        while(i!=0) i--;
    }
}

main.c:
#include "stm32f10x.h"
//#include"stm32f10x_conf.h"
#include "stm32f10x_gpio.h"
#include"stdint.h"
#include"LED.h"
#include"KEY.h"
int main(void)
{
    uint32_t keyval;     //键值变量
LEDInit();           //初始化LED
    Key_Init();          //初始化按键
    while(1)
    {
        keyval=KeyScan();  //扫描一次键盘
        if(keyval==3)       //如果是KEY3按下
        {
            GPIO_ResetBits(GPIOA,GPIO_Pin_2);     //LED1至LED3依次点亮后熄灭
            delayms(500);
            GPIO_ResetBits(GPIOB,GPIO_Pin_2);
            delayms(500);
            GPIO_ResetBits(GPIOA,GPIO_Pin_3);
            delayms(500);
            GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
            GPIO_SetBits(GPIOB,GPIO_Pin_2);
            delayms(200);
         }
         else if(keyval==4)      //如果是KEY4按下
         {
            GPIO_ResetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);  //一起闪三下
            GPIO_ResetBits(GPIOB,GPIO_Pin_2);
            delayms(200);
            GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
            GPIO_SetBits(GPIOB,GPIO_Pin_2);
            delayms(200);
            GPIO_ResetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
            GPIO_ResetBits(GPIOB,GPIO_Pin_2);
            delayms(200);
            GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
            GPIO_SetBits(GPIOB,GPIO_Pin_2);
            delayms(200);
            GPIO_ResetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
            GPIO_ResetBits(GPIOB,GPIO_Pin_2);
            delayms(200);
            GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
            GPIO_SetBits(GPIOB,GPIO_Pin_2);
            delayms(200);
        }
        else continue;
}   
}


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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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