找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6389|回復(fù): 0
收起左側(cè)

stm32鍵盤掃描簡單實(shí)現(xiàn)

[復(fù)制鏈接]
ID:89763 發(fā)表于 2015-9-10 01:24 | 顯示全部樓層 |閱讀模式
今天上午一個(gè)人在實(shí)驗(yàn)室,想到昨天學(xué)的鍵盤掃瞄可能不是很熟練,又嘗試自己寫一個(gè)。還是利用led的demo工程,實(shí)現(xiàn)按兩個(gè)按鍵改變LED工作狀態(tài),硬件接線(簡單的就不上圖了)PA0接KEY3,PA1接KEY4,LED1接PA2,LED2接PB2,LED接PA3,按下KEY3燈從LED1至LED3依次點(diǎn)亮后熄滅,按下KEY4則LED1至LED3一起閃三下,按鍵不松開不響應(yīng)(因?yàn)橐恢钡却砷_),在上一次響應(yīng)完成前按鍵無效(因?yàn)檫@時(shí)候沒有掃描),這是最簡單的方式,供初學(xué)者參考指正stm32鍵盤掃描簡單實(shí)現(xiàn),其實(shí)很簡單,GPIO配置少不了,把燈的IO配置為推挽輸出,即GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP就可以了,鍵盤輸入就將PA0和PA1設(shè)置為上拉輸入,即GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU,那么問題來了,怎么讀取鍵值呢?學(xué)過51的都知道,51的位操作非常方便,讀取直接sbit key P1.0然后對(duì)key寫入讀取就和變量一樣簡單了,那么stm32怎么讀入鍵值呢?會(huì)用到一個(gè)函數(shù),就是GPIO_ReadInputDataBit(),一次讀取一個(gè)IO口的值,用法也很簡單,傳入兩個(gè)參數(shù),一個(gè)IO口組,一個(gè)IO位置,比如讀入PA0就是key=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0),這樣就可以將PA0的狀態(tài)賦值給key這個(gè)變量,由于只上拉輸入,所以按鍵時(shí)讀入為0;其他的就沒什么了,用到了GPIO口就當(dāng)然使能相應(yīng)的時(shí)鐘。
在網(wǎng)上看了一些實(shí)例,用宏定義可以減傷很多麻煩, 不用每次讀入鍵值都打那么長一段,直接宏定義一下#define KEY3 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
這樣就可以很方便地讀取鍵值,和51一樣有沒有!stm32鍵盤掃描簡單實(shí)現(xiàn)
有興趣可以看一下,按鍵點(diǎn)燈最沒有技術(shù)含量的實(shí)現(xiàn),沒中斷沒定時(shí)器,學(xué)過51就能寫stm32鍵盤掃描簡單實(shí)現(xiàn)除此之外沒有別的文件和函數(shù)額,建好工程一添加就可以,固件庫是V3.5
附上代碼:
KEY.h:
#ifndef _KEY_H_       //避免重復(fù)引用
#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);   //延時(shí)函數(shù)
void Key_Init(void);            //鍵盤初始化
uint32_t KeyScan(void);      //鍵盤掃描
#endif

KEY.c:
#include"KEY.h"
void Key_Init()                 
{
    GPIO_InitTypeDef GPIO_InitStructure;     //定義初始化結(jié)構(gòu)體
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能GPIOA
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;           //設(shè)置PA0,PA1為上拉輸入
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;    //這個(gè)無所謂,不要應(yīng)該也可以
    GPIO_Init(GPIOA,&GPIO_InitStructure);     //調(diào)用初始化函數(shù)初始化PA0,PA1
}
uint32_t KeyScan()
{
    if(KEY3==0||KEY4==0)                 //若檢測到按下某個(gè)鍵
    {
        delay_ms(10);                    //延時(shí)去抖
        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)             //延時(shí)函數(shù)
{
    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;          //定義初始化結(jié)構(gòu)體
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);   //使能時(shí)鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;       //推挽輸出模式
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;      //響應(yīng)速度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)                   //延時(shí)函數(shù)
{
    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依次點(diǎn)亮后熄滅
            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;
}   
}


回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表