在网上看了些4*4矩阵键盘的程序,哥们自己也想写一个,首先是初始化就是P0口赋初值,这是数码管的I/O口,然后就是P3口的赋初值,这个是选通有几个数码管的,就是这个意思吧,最重要的是P1口这是连接键盘的I/O口。首先说说它的原理(我是依据我自己的图来写的,我的图是P1.0-P1.3是行,P1.4-P1.7是列扫描)。
先是令P1口 , P1=0xf0;高四位P1.4-P1.7全为高电平(为该列检测)如果有按键按下那么为低电平,这就能知道是那一列,然后在进行扫描,那么令P1.0-P1.3全为高电位
P1=0x0f进行行扫描。哥们其实都看出来,这样可以把P1的不同的值分别代入到函数,
该函数可以是一个unsigned char 类型的函数,这样P1分别代入的时候,就可以分别返回不同的值,进行相或,可以得到一个准确的值,这后面的事就好办了,把值代入到P0口进行显示了。
#include
#include
#define uchar unsigned char
#define uint unsigned int
unsigned char code disp_code[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf};
unsigned char code key_code[]={
0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,
0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77 };
void delayms(uint ms)
{
uchar t;
while(ms--)
{
for(t = 0; t < 120; t++);
}
}
uchar scanfdown(uchar P1)
{
uchar scanf1=0x00;
uchar b ;
b=((P1==0x70||P1==0xe0||P1==0xd0||P1==0xb0))?0xf0:0x0f;
//其实写这句话的时候就是为了列扫描的值与列为0x0f进行相与,埋下伏笔
//这样写是为了更加确定按键的值,防止该值的其他因素的改变,我不知道有什么因素可以改变,呵呵,都是浮云
//哥们在写这句话的时候出现了错误,我当时写的是b=(P1==(0x70||0xe0||0xd0||0xb0))
//后来我知道是这句话出错了,但是不知道哪里出错了,网上一哥们指出,C程序不能那样写后来一想是的,0x70||0xe0||0xd0||0xb0如果这样写的话就是判断真或者是假的,这样写都为真,没什么意义。
其实哥们的意思就是当P1等于其中一个的时候都成立。以后一定要注意,这些细节。
if (P1==0x70||P1==0xe0||P1==0xd0||P1==0xb0) //进行列扫描,只有四种可能
{
scanf1=P1;
}
else if (P1==0x07||P1==0x0e||P1==0x0d||P1==0x0b) //进行行扫描
{
scanf1=P1;
}
if ((scanf1&b)!=b)
{
delayms(5);
if ((scanf1&b)!=b)
{
scanf1=P1;
scanf1=scanf1&b;
return (scanf1);
}
}
else
{
return (100);
}
}
void main()
{
uchar scanf2=0x00; //列扫描的值
uchar value=0x00;
uchar scanf3=0x00; //行扫描的值
uchar scanf=0x00; //按键按下的值
uint i=0x00;
P3=0x7f; //选择有几个数码管
P0=0xfe; //初始化数码管的显示
while (1)
{
P1=0xf0;
scanf2= scanfdown(P1);
P1=0x0f;
scanf3=scanfdown(P1);
scanf=scanf2+scanf3;
for (i=0;i<=15;i++)
{
if (scanf==key_code[i])
{
value=i;
}
}
P0=disp_code[value];
}
}
在写这个程序的时候我是想用递归的方法来写,但是到最后没用递归用,因为我
在用递归写的同时,递归最重要的就是条件判断其函数中止,写到最后,我找不到这样
的条件,如果用递归写的话,我也只是递归一次。后来我就放弃用递归的想法,希望那个哥们用递归写出来,哥们我也学习。