1、前言
本篇介绍的是基于STM32——寄存器版本的矩阵键盘控制5161as数码管显示数字的实例。我们赋予每一个按键从1到9的数字,当我们按下对应的数字按键时,程序会检测出被按下的是哪一个按键并在5261as数码管上显示相应的数字。
2、矩阵键盘
(1)原理
为了读取每一个按键的状态,最简单粗暴的方法就是给每一个按键都接一个引脚来读取按键状态。但对于一个3*3的键盘来说,就要占用9个I/O口。所以我们选择矩阵键盘。其本质就是用6条I/O线来进行9个按键的控制。用3条I/O线作为行线,三条I/O线作为列线,将按键放在行列线的交叉点上。当按下按键后对应的行列导通,通过扫描每行每列的方法来确定按键位置。其电路如图所示:
(2)实现方法
按键位置的读取有两种:逐行/逐列扫描和行列扫描。
本章使用的是逐行/逐列扫描的方法:先将每一列引脚设置为推免输出1(高电平),每一行引脚设置为0(输入下拉),当有按键被按下后行列导通,对应的行读入的引脚状态就会变为1(高电平),这样就确定了按键所在的行。再将行设置为推免输出,列设置为输入下拉用同样的方法读出按键所在的列。这样就确定了按键的具体位置。
3、5161as数码管
(1)原理
5261as数码管分为共阴极和共阳极,本章使用的是共阴极数码管,其原理如图所示:
5261as数码管由8个二极管组成一个数字8和一个小数点,这些二极管共用一个阴极。对应的10个引脚,除过两边中间的引脚是共阴极外,其他8个引脚分别控制八个不同位置的二极管,控制关系如图(a)所示。
(2)实现方法
对于共阴极数码管来说,将8个控制二极管的引脚分别接到不同的I/O端口上,两个共阴极的引脚接地。只要设置对应的I/O端口输出高电平,其他为低电平就能显示对应数字。比如要显示数字1,就可以将控制二极管e,f的引脚设置为推免输出高电平,其他为推免输出低电平,就可以只点亮e,f二极管。
4、硬件连接
我选择的键盘I/O接口是PB8-PB13,数码管I/O接口是PA0-PA7。实物连接如图所示:
5、程序设计
1、key.c中主要实现的是矩阵键盘逐行/逐列扫描。具体代码如下:
#include "key.h"
#include "delay.h"
#include "stm32f10x.h"
u8 KEY_Scan(void)
{
u8 i=0,j=0;//用来记录按键所在的行和列
RCC->APB2ENR |=1<<3;//使能时钟
GPIOB->CRH&=0XFF000000;
GPIOB->CRH|=0X00333888;//引脚PB8-PB10输入,PB11-PB13推免输出
GPIOB->ODR&=0X00000000;//将PB8-PB10设置为输入下拉
PBout(11)=1;//PB11-PB13推免输出高电平
PBout(12)=1;
PBout(13)=1;
PBin(8)=0;//初始化PBin的值
PBin(9)=0;
PBin(10)=0;
if(PBin(8)==1||PBin(9)==1||PBin(10)==1)//第一次判断
{
delay_ms(10);//去抖动
if(PBin(8)==1)//再次判断
{
i=1;
}else if(PBin(9)==1)
{
i=2;
}else if(PBin(10)==1)
{
i=3;
}else{
return 0;
}
}
//同上改变行列引脚状态
GPIOB->CRH&=0XFF000000;
GPIOB->CRH|=0X00888333;
GPIOB->ODR&=0X00000000;
PBout(8)=1;
PBout(9)=1;
PBout(10)=1;
PBin(11)=0;
PBin(12)=0;
PBin(13)=0;
if(PBin(11)==1||PBin(12)==1||PBin(13)==1)
{
delay_ms(10);//去抖动
if(PBin(11)==1)//行
{
j=1;
}else if(PBin(12)==1)
{
j=2;
}else if(PBin(13)==1)
{
j=3;
}else{
return 0;
}
}
//根据行列判断按键位置
if(j==1&&i==1)
return 1;
else if(j==1&&i==2)
return 2;
else if(j==1&&i==3)
return 3;
else if(j==2&&i==1)
return 4;
else if(j==2&&i==2)
return 5;
else if(j==2&&i==3)
return 6;
else if(j==3&&i==1)
return 7;
else if(j==3&&i==2)
return 8;
else if(j==3&&i==3)
return 9;
else
return 0;
}
2、led.c中主要控制5161as数码管各个引脚状态。具体代码如下:
#include "sys.h"
#include "led.h"
//初始化PA8和PD2为输出口.并使能这两个口的时钟
//LED IO初始化
void LED_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA时钟
GPIOA->CRL&=0X00000000;
GPIOA->CRL|=0X33333033;//PA0-7 推挽输出
JTAG_Set(SWD_ENABLE); //关闭JTAG,开启SWD
GPIOA->ODR&=0X00000000;//全部输出低电平
}
//设置每位数字输出的二极管状态
void LED_1(void)
{
PAout(1)=0;
PAout(0)=0;
PAout(5)=0;
PAout(6)=0;
PAout(7)=1;
PAout(3)=1;
PAout(4)=0;
}
void LED_2(void)
{
PAout(1)=1;
PAout(0)=1;
PAout(5)=0;
PAout(6)=1;
PAout(7)=1;
PAout(3)=0;
PAout(4)=1;
}
void LED_3(void)
{
PAout(1)=1;
PAout(0)=1;
PAout(5)=1;
PAout(6)=1;
PAout(7)=0;
PAout(3)=0;
PAout(4)=1;
}
void LED_4(void)
{
PAout(1)=0;
PAout(0)=1;
PAout(5)=1;
PAout(6)=0;
PAout(7)=0;
PAout(3)=1;
PAout(4)=1;
}
void LED_5(void)
{
PAout(1)=1;
PAout(0)=0;
PAout(5)=1;
PAout(6)=1;
PAout(7)=0;
PAout(3)=1;
PAout(4)=1;
}
void LED_6(void)
{
PAout(1)=1;
PAout(0)=0;
PAout(5)=1;
PAout(6)=1;
PAout(7)=1;
PAout(3)=1;
PAout(4)=1;
}
void LED_7(void)
{
PAout(1)=1;
PAout(0)=1;
PAout(5)=1;
PAout(6)=0;
PAout(7)=0;
PAout(3)=0;
PAout(4)=0;
}
void LED_8(void)
{
PAout(1)=1;
PAout(0)=1;
PAout(5)=1;
PAout(6)=1;
PAout(7)=1;
PAout(3)=1;
PAout(4)=1;
}
void LED_9(void)
{
PAout(1)=1;
PAout(0)=1;
PAout(5)=1;
PAout(6)=1;
PAout(7)=0;
PAout(3)=1;
PAout(4)=1;
}
3、text.c中主要进行按键的判断然后调用led.c中显示数字的代码,并打印在串口中,具体代码如下:
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "key.h"
#include "led.h"
int main(void)
{
vu8 t;
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
uart_init(72,9600); //初始化串口通信
LED_Init(); //初始化端口
printf("正常进入");
while(1)
{
t=KEY_Scan(); //得到键值
printf("t的值为:%d\n",t);
switch(t)
{
case 1:
printf("你按下了:1\r\n");//按键数值打印在串口
LED_1();//显示对应数字
break;
case 2:
printf("你按下了:2\r\n");
LED_2();
break;
case 3:
printf("你按下了:3\r\n");
LED_3();
break;
case 4:
printf("你按下了:4\r\n");
LED_4();
break;
case 5:
printf("你按下了:5\r\n");
LED_5();
break;
case 6:
printf("你按下了:6\r\n");
LED_6();
break;
case 7:
printf("你按下了:7\r\n");
LED_7();
break;
case 8:
printf("你按下了:8\r\n");
LED_8();
break;
case 9:
printf("你按下了:9\r\n");
LED_9();
break;
default:
printf("无按键按下\r\n");
delay_ms(1000);
break;
}
}
}
4、对应的头文件中为各个函数的定义,具体代码如下:
key.h:
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
u8 KEY_Scan(void); //按键扫描函数
#endif
led.h:文章来源:https://www.toymoban.com/news/detail-511134.html
#ifndef __LED_H
#define __LED_H
#include "sys.h"
//LED端口定义
//#define LED_a PAout(1)
//#define LED_b PAout(0)
//#define LED_c PAout(5)
//#define LED_d PAout(6)
//#define LED_e PAout(7)
//#define LED_f PAout(3)
//#define LED_g PAout(4)
void LED_Init(void); //初始化
void LED_1(void);
void LED_2(void);
void LED_3(void);
void LED_4(void);
void LED_5(void);
void LED_6(void);
void LED_7(void);
void LED_8(void);
void LED_9(void);
#endif
6、运行结果
1、串口运行结果
2、5161as数码管运行结果
文章来源地址https://www.toymoban.com/news/detail-511134.html
到了这里,关于STM32F103基础(寄存器)——(1)3*3矩阵键盘控制5161as数码管的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!