赞
踩
注:第一篇文章,如有不足之处,敬请谅解
本文是通过寄存器的方式实现4*4按键的输入,采用逐行扫描的方式,并编写实现单次点击或者长按只接受一次数据。
4*4按键驱动
/*****************************************************
头文件:
#ifndef __KEY_H
#define __KEY_H
#include "stm32f4xx.h"
extern u8 only;
void Key_Init(void);
int Key_Scan(void);
#endif
驱动代码:
#include "key.h"
u8 only; //一次按键只打印一次标志位
/*********************************************************************
*按键用的PC6-PC9,PC11,PB6,PE5,PE6
*PC6-PC9为推挽输出
*PC11,PB6,PE5,PE6为下拉输入
*********************************************************************/
void Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //使能C端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽式输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50MHZ
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //使能C端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //输入模式
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能B端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //输入模式
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); //使能E端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //输入模式
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
GPIO_Init(GPIOE, &GPIO_InitStructure); //初始化
}
/*********************************************************************
*函数说明: 按键扫描
*返回值 : 按键值
*参数 : void
**********************************************************************/
int Key_Scan(void)
{
int keyValue=99; //按键值
GPIO_Write(GPIOC,(GPIOC->ODR & 0xfc3f )| 0x0040);//让PC6-9输出0001,检测第四行
if((GPIOC->IDR & 0x0800) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOC->IDR & 0x0800) != 0x0000)
{
only = 1;
while((GPIOC->IDR & 0x0800) != 0x0000);
keyValue='D';
}
}
if((GPIOB->IDR & 0x0040) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOB->IDR & 0x0040) != 0x0000)
{
only = 1;
while((GPIOB->IDR & 0x0040) != 0x0000);
keyValue='#';
}
}
if((GPIOE->IDR & 0x0020) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOE->IDR & 0x0020) != 0x0000)
{
only = 1;
while((GPIOE->IDR & 0x0020) != 0x0000);
keyValue=0;
}
}
if((GPIOE->IDR & 0x0040) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOE->IDR & 0x0040) != 0x0000)
{
only = 1;
while((GPIOE->IDR & 0x0040) != 0x0000);
keyValue='*';
}
}
GPIO_Write(GPIOC,(GPIOC->ODR & 0xfc3f )| 0x0080);//让PC6-9输出0010,检测第三行
if((GPIOC->IDR & 0x0800) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOC->IDR & 0x0800) != 0x0000)
{
only = 1;
while((GPIOC->IDR & 0x0800) != 0x0000);
keyValue='C';
}
}
if((GPIOB->IDR & 0x0040) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOB->IDR & 0x0040) != 0x0000)
{
only = 1;
while((GPIOB->IDR & 0x0040) != 0x0000);
keyValue=9;
}
}
if((GPIOE->IDR & 0x0020) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOE->IDR & 0x0020) != 0x0000)
{
only = 1;
while((GPIOE->IDR & 0x0020) != 0x0000);
keyValue=8;
}
}
if((GPIOE->IDR & 0x0040) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOE->IDR & 0x0040) != 0x0000)
{
only = 1;
while((GPIOE->IDR & 0x0040) != 0x0000);
keyValue=7;
}
}
GPIO_Write(GPIOC,(GPIOC->ODR & 0xfc3f )| 0x0100);//让PC6-9输出0100,检测第二行
if((GPIOC->IDR & 0x0800) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOC->IDR & 0x0800) != 0x0000)
{
only = 1;
while((GPIOC->IDR & 0x0800) != 0x0000);
keyValue='B';
}
}
if((GPIOB->IDR & 0x0040) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOB->IDR & 0x0040) != 0x0000)
{
only = 1;
while((GPIOB->IDR & 0x0040) != 0x0000);
keyValue=6;
}
}
if((GPIOE->IDR & 0x0020) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOE->IDR & 0x0020) != 0x0000)
{
only = 1;
while((GPIOE->IDR & 0x0020) != 0x0000);
keyValue=5;
}
}
if((GPIOE->IDR & 0x0040) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOE->IDR & 0x0040) != 0x0000)
{
only = 1;
while((GPIOE->IDR & 0x0040) != 0x0000);
keyValue=4;
}
}
GPIO_Write(GPIOC,(GPIOC->ODR & 0xfc3f )| 0x0200);//让PC6-9输出1000,检测第一行
if((GPIOC->IDR & 0x0800) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOC->IDR & 0x0800) != 0x0000)
{
only = 1;
while((GPIOC->IDR & 0x0800) != 0x0000);
keyValue='A';
}
}
if((GPIOB->IDR & 0x0040) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOB->IDR & 0x0040) != 0x0000)
{
only = 1;
while((GPIOB->IDR & 0x0040) != 0x0000);
keyValue=3;
}
}
if((GPIOE->IDR & 0x0020) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOE->IDR & 0x0020) != 0x0000)
{
only = 1;
while((GPIOE->IDR & 0x0020) != 0x0000);
keyValue=2;
}
}
if((GPIOE->IDR & 0x0040) != 0x0000)
{
delay_ms(5);//延时消抖
if((GPIOE->IDR & 0x0040) != 0x0000)
{
only = 1;
while((GPIOE->IDR & 0x0040) != 0x0000);
keyValue=1;
}
}
return keyValue;
}
主函数
/************************************************************************
int main(void)
{
int id;
//设置NVIC分组(一个工程只能设置一个分组)
//第二分组;抢占优先组取值范围:0~3 响应先组取值范围:0~3
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Delay_Init();
Key_Init();
while(1)
{
id = Key_Scan();
delay_ms(50);
if(only == 1) //按一次打印一次
{
//这里写显示的方式,把接收显示出来
only = 0;
}
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。