今天上午一個人在實驗室,想到昨天學的鍵盤掃瞄可能不是很熟練,又嘗試自己寫一個。還是利用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;
}
}
|