STM32实验——4×4按键
实验要求:使用一个4×4键盘输入到单片机 单片机在通过USART端口输出到上位机。
第一部分:对按键的检测,原理具体通过百度可知。大体原理为通过4行输出低电平,分别检测四列的电平,确定按键在哪一列上。再通过对那一列输出高电平,检测在哪一个行上。
代码部分:
#include "4X4.h"
#include "delay.h"
#include "usart.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE); //使能PB,PE端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //LED0-->PB.5 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5
GPIO_SetBits(GPIOA,GPIO_Pin_8); //PB.5 输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1-->PE.5 端口配置, 推挽输出
GPIO_Init(GPIOD, &GPIO_InitStructure); //推挽输出 ,IO口速度为50MHz
GPIO_SetBits(GPIOD,GPIO_Pin_2); //PE.5 输出高
}
void LED_R_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB, ENABLE); //使能PB,PC端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PB0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB0
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PB1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //PB5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //PB6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PC9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOC9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PC8
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOC8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //PC7
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOC7
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //PC6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOC6
}
void LED_C_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB, ENABLE); //使能PB,PC端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PC9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉输入
GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOC9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PC8
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉输入
GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOC8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //PC7
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉输入
GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOC7
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //PC6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉输入
GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOC6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PB0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB0
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PB1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //PB5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //PB6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB6
}
char key;
u8 KEY_Scan(void)
{
uart_init(9600);
LED_R_Init();
GPIO_ResetBits(GPIOC,GPIO_Pin_9);
GPIO_ResetBits(GPIOC,GPIO_Pin_8);
GPIO_ResetBits(GPIOC,GPIO_Pin_7);
GPIO_ResetBits(GPIOC,GPIO_Pin_6);
delay_ms(10);
if(C1==0)
{
LED_C_Init();
GPIO_SetBits(GPIOB,GPIO_Pin_0);
delay_ms(10);
if(R2==1)
key= '4' ;
else if(R1==1)
key='1';
else if(R3==1)
key='7';
else if(R4==1)
key= '*';
else
key='z';
}
else if(C2==0)
{
LED_C_Init();
GPIO_SetBits(GPIOB,GPIO_Pin_1);
delay_ms(10);
if(R1==1)
key= '2';
else if(R2==1)
key= '5';
else if(R3==1)
key= '8';
else if(R4==1)
key= '0';
else
key='z';
}
else if(C3==0)
{
LED_C_Init();
GPIO_SetBits(GPIOB,GPIO_Pin_5);
delay_ms(10);
if(R1==1)
key= '3';
else if(R2==1)
key= '6';
else if(R3==1)
key= '9';
else if(R4==1)
key= '#';
else
key='z';
}
else if(C4==0)
{
LED_C_Init();
GPIO_SetBits(GPIOB,GPIO_Pin_6);
delay_ms(10);
if(R1==1)
key= 'A';
else if(R2==1)
key= 'B';
else if(R3==1)
key= 'C';
else if(R4==1)
key= 'D';
else
key='z';
}
else key='z';
return key;
}
这一部分的注释又可能有问题,并没有仔细检查。
附上.h文件
#ifndef __4X4_H
#define __4X4_H
#include "sys.h"
#define R1 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_9)
#define R2 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_8)
#define R3 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_7)
#define R4 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_6)
#define C1 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)
#define C2 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)
#define C3 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)
#define C4 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)
void LED_R_Init(void);//初始化
void LED_C_Init(void);//初始化
void LED_Init(void);
u8 KEY_Scan(void);
#endif
第二部分:主函数
主函数主要实现在键盘中读取数字字符后再转换成数字,并且可以输入一定长度的数字,其中(R4,C4)按键为确定键。例如输入三个数字‘1’,‘1’,‘3’,再按下确定键即可输出113数字到PC机上。按下按键的时候有LED灯提示。输出到PC上同样有LED灯提示。
/************************
名称:用4X4键盘来输入数据显示到PC
时间:2020.3.22
作者:L.J.W
变量作用:arr数组用来储存键盘输入的数据
D代表输入结束
i计数来统计一共输入多少个数据
add是最后显示的数据
按下按键led亮 输出数据另一个led亮
************************/
#include "4X4.h"
#include "usart.h"
#include "delay.h"
#include "math.h"
char t;
int main()
{
LED_Init(); //初始化与LED连接的硬件接口
uart_init(9600);
delay_init();
int arr[9];
int i;
int count=0;
int add=0;
int z;
while(1)
{
t=KEY_Scan();
if(t=='z')
t=t;
else
{
if(t=='D')
{
//用来把arr数组里的数转换到add
for(count=0;count<i;count++)
{
add+=arr[count]*(int)pow((float)10,(i-count-1));
}
printf("%d\n\r",add);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);//LED1输出低
delay_ms(300);
GPIO_SetBits(GPIOD,GPIO_Pin_2);//LED0输出高
add=0;//add清零
for(z=0;z<9;z++)
{
arr[z]=0;//数组清零
}
count=0;
i=0;//统计数据清零
}
else
{
//用来i计数并且写入arr数组
arr[i]=t-'0';
GPIO_ResetBits(GPIOA,GPIO_Pin_8); //LED0输出低
delay_ms(300);
GPIO_SetBits(GPIOA,GPIO_Pin_8);//LED1输出高
i++;
}
}
delay_ms(300);
}
}
这次按键代码除了0~9个数字键还有一个确认键之外,还有5个按键,但是代码部分并没有进行处理。由于新手写代码有很多疏漏的地方,多多包涵。
这是4X4代码压缩包
https://download.csdn.net/download/ljw__/12265113