标题: 51单片机矩阵键盘不知道哪里写错了,求大佬看看 [打印本页]
作者: 曹大哥 时间: 2018-8-13 23:57
标题: 51单片机矩阵键盘不知道哪里写错了,求大佬看看
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0};
uchar num,temp,num1;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
int main()
{
P0=table[0];
P1=0xfe;
num=0;
while(1)
{
P3=0xfe;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
switch (temp)
{
case 0xe0:num=1;break;
case 0xd0:num=2;break;
case 0xb0:num=3;break;
case 0x70:num=4;break;
}
}
}
while(temp!=0xf0)
{
temp = P3;
temp=temp&0xf0;
}
P0=table[num];
P1=0xfe;
}
}
作者: wulin 时间: 2018-8-14 06:51
给你改了,对比一下就知道哪里错了。
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x0f};
uchar num,temp,num1;
bit sign=0;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
int main()
{
P0=table[0];
P1=0xfe;
num=0;
while(1)
{
P3=0xf0;
if(P3!=0xf0)
{
delay(5);
if((P3!=0xf0)&&(sign==0))
{
sign=1;
temp=P3;
temp|=0x0f;
P3=temp;
temp=P3;
switch (temp)
{
case 0xee: num= 1; break;
case 0xde: num= 2; break;
case 0xbe: num= 3; break;
case 0x7e: num= 4; break;
case 0xed: num= 5; break;
case 0xdd: num= 6; break;
case 0xbd: num= 7; break;
case 0x7d: num= 8; break;
case 0xeb: num= 9; break;
case 0xdb: num=10; break;
case 0xbb: num=11; break;
case 0x7b: num=12; break;
case 0xe7: num=13; break;
case 0xd7: num=14; break;
case 0xb7: num=15; break;
case 0x77: num=16; break;
}
}
}
else sign=0;
P0=table[num];
}
}
作者: HC6800-ES-V2.0 时间: 2018-8-14 08:07
因为不了解你的功能(可能是按键后数码管显示键值吧),和你的电路,所以没法说程序问题。程序本身是没有语法错误的。
给你一个矩阵键盘的例子吧,当然有对应电路了。
/*******************************************************************************
* 实 验 名 : 矩阵键盘实验
* 使用的IO : 数码管使用P0,键盘使用P3.0、P3.1、P3.2、P3.3
* 实验效果 : 按矩阵键盘分别显示在数码管上面显示十六进制的0到F。
* 注 意 :
*******************************************************************************/
#include<reg51.h>
#define GPIO_DIG P0
#define GPIO_KEY P1
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
unsigned char code DIG_CODE[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char KeyValue;
//用来存放读取到的键值
void Delay10ms(); //延时10ms
void KeyDown(); //检测按键函数
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main(void)
{
LSA=0; //给一个数码管提供位选
LSB=0;
LSC=0;
while(1)
{
KeyDown();
GPIO_DIG=DIG_CODE[KeyValue];
}
}
/*******************************************************************************
* 函 数 名 : KeyDown
* 函数功能 : 检测有按键按下并读取键值
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void KeyDown(void)
{
char a=0;
GPIO_KEY=0x0f;
if(GPIO_KEY!=0x0f)//读取按键是否按下
{
Delay10ms();//延时10ms进行消抖
if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
{
//测试列
GPIO_KEY=0X0F;
switch(GPIO_KEY)
{
case(0X07): KeyValue=0;break;
case(0X0b): KeyValue=1;break;
case(0X0d): KeyValue=2;break;
case(0X0e): KeyValue=3;break;
}
//测试行
GPIO_KEY=0XF0;
switch(GPIO_KEY)
{
case(0X70): KeyValue=KeyValue;break;
case(0Xb0): KeyValue=KeyValue+4;break;
case(0Xd0): KeyValue=KeyValue+8;break;
case(0Xe0): KeyValue=KeyValue+12;break;
}
while((a<50)&&(GPIO_KEY!=0xf0)) //检测按键松手检测
{
Delay10ms();
a++;
}
}
}
}
/*******************************************************************************
* 函 数 名 : Delay10ms
* 函数功能 : 延时函数,延时10ms
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Delay10ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}
-
1.jpg
(37.15 KB, 下载次数: 41)
-
2.jpg
(60.11 KB, 下载次数: 49)
-
3.jpg
(16.96 KB, 下载次数: 53)
作者: 曹大哥 时间: 2018-8-14 09:08
只有第一次按矩阵键盘的键,数码管才显示,,,第二次就不改变了,不过蛮感谢的
作者: 人中狼 时间: 2018-8-14 10:17
while(temp!=0xf0)
{
switch (temp)
{
case 0xe0:num=1;break;
case 0xd0:num=2;break;
case 0xb0:num=3;break;
case 0x70:num=4;break; default: break;
} temp=P3;
temp=temp&0xf0;
}
个人觉得增加红色部分应该就可以了,如果case里的break只是跳出switch,而不跳出while的话,那么temp的值没有改变,应该就会死循环了。
另外测试的时候要注意只有四个按键的值有效,毕竟程序里只检测了一列的四个按键,其他的按键会没显示的。
作者: wulin 时间: 2018-8-14 10:56
这个程序是用仿真确认过的,不知道你的电路与此是否相同。
作者: 曹大哥 时间: 2018-8-14 18:37
哦哦哦,谢谢了
作者: 曹大哥 时间: 2018-8-14 18:37
我参考参考
作者: zl2168 时间: 2018-8-23 16:49
本帖最后由 zl2168 于 2018-8-23 21:58 编辑
实例75 4×4矩阵式键盘
先Proteus仿真一下,确认有效。
以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil C和Proteus》清华大学出版社ISBN 978-7-302-41682-1.。书中电路和程序设计有详细说明,程序语句条条有注解。
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |