|
今天上午一個(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;
}
}
|
|