#include<reg52.h>
#define uchar unsigned char //数据类型的宏定义
#define uint unsigned int //数据类型的宏定义
sbit BEEP = P3^6; //蜂鸣器控制端口P36
unsigned char table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xBF};
//共阳数码管显示字型码数组
void delay(void)
{
unsigned char i,j;
for(i=0;i<20;i++)
for(j=0;j<250;j++);
}
/* 延时子程序*/
void delay1(uchar x)
{ uchar j;
while((x--)!=0)
{ for(j=0;j<125;j++)
{;}
}
}
//--------------------------------------------------
//--------------------------------------------------
void delay0(uchar x) //x*0.14MS
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++) {}
}
}
/*********************************************************/
void beep() //蜂鸣器响一声函数
{
unsigned char i;
for (i=0;i<100;i++)
{
delay0(4);
BEEP=!BEEP; //BEEP取反
}
BEEP=1; //关闭蜂鸣器
delay1(250); //延时
}
void display(unsigned char i)
{
P2=0x7f; //选通最有端的数码管显示
P0=table[i]; //显示i参数传来的字型码
}
void keyscan(void)
{
unsigned char temp;
//扫描第一行
P1=0xfe;
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
delay();
P1=0xfe;
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
beep();
switch(temp)
{
case(0xe0):display(0);break;
case(0xd0):display(1);break;
case(0xb0):display(2);break;
case(0x70):display(3);break;
}
}
}
//扫描第二行
P1=0xfd;
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
delay();
P1=0xfd;
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
beep();
switch(temp)
{
case(0xe0):display(4);break;
case(0xd0):display(5);break;
case(0xb0):display(6);break;
case(0x70):display(7);break;
}
}
}
//扫描第三行
P1=0xfb;
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
delay();
P1=0xfb;
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
beep();
switch(temp)
{
case(0xe0):display(8);break;
case(0xd0):display(9);break;
case(0xb0):display(10);break;
case(0x70):display(11);break;
}
}
}
//扫描第四行
P1=0xf7;
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
delay();
P1=0xf7;
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
beep();
switch(temp)
{
case(0xe0):display(12);break;
case(0xd0):display(13);break;
case(0xb0):display(14);break;
case(0x70):display(15);break;
}
}
}
}
void main(void)
{
display(16); //初始显示 -
while(1)
{
keyscan(); //执行按键扫描程序
}
}
这上面是K:\锐志电子资料\RZ-51V20 配套软件及资料\RZ-51V20 PDF配套教程\配套教程实例\RZ-SL7 4X4矩阵键盘实验 的整个代码,但对红色的部分不理解。
P1=0xfe;
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
{
delay();
P1=0xfe;
temp=P1;
temp&=0xf0;
if(temp!=0xf0)
上面将P1赋了值,然后马上用temp取值。疑问:这时temp那岂不是99%还是0xfe而不是按键后改变的值。(这两条语句之中大概几条汇编指令吧,这么短的时间按键的效果怎么就这么快就反映到IO口上?如果说是电流的传递速度的话(貌似线与(一个老副教授如是说这是线与的关系(坑人啊)) 还要什么什么门进行处理,这个处理放在芯片内部?那岂不是硬件的响应时间再次被托慢了?),那么?)我认为应该加个延时。不加延时根本就不会响应,但是这个程序原封不同的编译,然后烧到板上确实能够准确响应按键运行。这又是为何?难道类似于ARM中的IDR(输入缓冲寄存器)和ODR(输出缓冲寄存器)?赋值与接收 是放在不同的寄存器中?而P1 = 0xfe 只是向其输出寄存器中赋值? Temp = P1是从其输入缓冲器中取值????内部结构到底是怎么样呢??(一个IO口配套的寄存器 又是怎么协调工作的呢?)
问题得以解决,听另一个年轻老师说这里并不是 线与的关系,线与 常用在总线上,是得益于一个单片机电路图,若按下为0后 不管你赋值什么都是不起作用的,因为一端已经接地,你把高电平接上,端口收到的还是低电平。所以这代码是没有问题的,不用加什么延时,相关电路图 待会儿 传上。
看电路图只有个锁存器,没有什么缓存器。
