文章目录
Arduino驱动4X4矩阵薄膜按键
-
参考网站:
-
那天看到别人的51有个4 * 4矩阵,想到按键自己还有一个4 * 4***矩阵薄膜按键***,于是就想要玩一下
-
其实挺简单的!
原理图
我的薄膜按键
接线按自己的宏定义将行引脚连续接,列引脚连续接。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ebWmIWFu-1580626011386)(C:\Users\fengyun323\Documents\Tencent Files\1920922256\FileRecv\MobileFile\IMG_20190716_104758.jpg)]
按键上拉
Arduino的ATmega328P芯片由内部上拉功能,但没有下拉功能,内部电路如图:
上拉电阻介绍
在数字电路中,上拉电阻(英语:Pull-up resistors)是当某输入端口未连接设备或处于高阻抗的情况下,一种用于保证输入信号为预期逻辑电平的电阻元件。他们通常在不同的逻辑器件之间工作,提供一定的电压信号。
上拉电阻作用
在上拉电阻所连接的导线上,如果外部组件未启用,上拉电阻将“微弱地”将输入电压信号“拉高”。当外部组件未连接时,对输入端来说,外部“看上去”就是高阻抗的。这时,通过上拉电阻可以将输入端口处的电压拉高到高电平。如果外部组件启用,它将取消上拉电阻所设置的高电平。通过这样,上拉电阻可以使引脚即使在未连接外部组件的时候也能保持确定的逻辑电平。
例程
void setup ()
{
pinMode(2,INPUT_PULLUP); //将2号管脚设置为输入并且内部上拉模式
pinMode(12,OUTPUT);
}
void loop()
{
int n =digitalRead(2); //创建一个变量n,将4号数字口的状态采集出来赋值给他。
if (n==LOW) //判断n是否为低电平,如果是执行下面的语句,不是则跳过。
{
delay(1000);
digitalWrite(12,HIGH);
delay(5000);
digitalWrite(12,LOW);
}
}
pinMode(2,INPUT_PULLUP);
定义了2号引脚为INPUT_PULLUP模式意味着该引脚为输入模式,并且被拉高,这就是为什么按键接到了GND
当按键按下时,2号管脚变为GND,这样就完成了按键的功能
因为ATmega328P单片机管脚默认是高电平,所以我们通常设定低电平有效,这样就可以避免误触发
我的想法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ojgnZnqw-1580626011387)(C:\Users\fengyun323\AppData\Roaming\Typora\typora-user-images\1563247741759.png)]
上图可见我已成功实现矩阵按键检测功能!!!
我的代码(老)
char key[4][4] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
int symbol = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
for(int i=2;i<=5;i++){
pinMode(i,INPUT_PULLUP);
}
for(int i=6;i<=9;i++){
pinMode(i,OUTPUT);
}
}
void loop() {
// put your main code here, to run repeatedly:
for(int j=6;j<=9;j++){
for(int i=6;i<=9;i++){
digitalWrite(i,HIGH);
}
digitalWrite(j,LOW);
symbol = 0;
for(int i=0;i<5000;i++){
for(int k=2;k<=5;k++){
if(digitalRead(k) == 0){
for(int t=0;t<100;t++){}
if(digitalRead(k) == 0)
symbol = k;
}
}
if(symbol != 0){
Serial.print(symbol-2);
Serial.print(' ');
Serial.println(j-6);
break;
}
}
}
}
后续
4 * 4按键矩阵一些全局变量及宏定义
#define keyboard_line 2
#define keyboard_row 6
char key[4][4] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};//保存矩阵字符
int symbol_line = 0;
int symbol_row = 0;
扫描矩阵函数封装
函数功能:反馈矩阵对应的字符
char keyboard_scan(void)
{
for(symbol_row=keyboard_row;symbol_row<keyboard_row+4;symbol_row++)
{
for(int i=keyboard_row;i<keyboard_row+4;i++)
digitalWrite(i,HIGH);
digitalWrite(symbol_row,LOW);
symbol_line = 0;
for(int i=0;i<500;i++){
for(int k=keyboard_line;k<keyboard_line+4;k++)
{
if(digitalRead(k) == 0)
{
while(1)
{
if(digitalRead(k) == 1){
symbol_line = k;
break;
}
}
}
}
if(symbol_line != 0)
return key[symbol_line-2][symbol_row-6];
}
}
if(symbol_line == 0)
return 0;
}
最后改进的代码(完整版)
#define keyboard_line 2
#define keyboard_row 6
char key[4][4] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
int symbol_line = 0;
int symbol_row = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println('W');
for(int i=keyboard_line;i<keyboard_line+4;i++){
pinMode(i,INPUT_PULLUP);
}
for(int i=keyboard_row;i<keyboard_row+4;i++){
pinMode(i,OUTPUT);
}
}
void loop() {
// put your main code here, to run repeatedly:
char dri = 0;
dri = keyboard_scan();
if(dri!=0){
Serial.println(dri);}
}
char keyboard_scan(void)
{
for(symbol_row=keyboard_row;symbol_row<keyboard_row+4;symbol_row++)
{
for(int i=keyboard_row;i<keyboard_row+4;i++)
digitalWrite(i,HIGH);
digitalWrite(symbol_row,LOW);
symbol_line = 0;
for(int i=0;i<500;i++){
for(int k=keyboard_line;k<keyboard_line+4;k++)
{
if(digitalRead(k) == 0)
{
while(1)
{
if(digitalRead(k) == 1){
symbol_line = k;
break;
}
}
}
}
if(symbol_line != 0)
return key[symbol_line-2][symbol_row-6];
}
}
if(symbol_line == 0)
return 0;
}