希望大侠能多多拍砖,我这是第一次在这人论坛发贴.一直都很喜欢这个论坛,只是一直都没有勇气(因为实在很菜)..今天我终于鼓起勇气来,向你表达:
/******************32个按键扫描控制4进8出信号**************************
************************编译器: Keil**********************************
************************作者: Action**********************************
************************开始日期: 2008-01-08**************************
************************完成日期: 2008-01-21**************************/
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit SH = P3^0;
sbit DS = P3^1;
sbit ST = P3^2;
sbit one_h = P3^4;
sbit two_h = P3^5;
sbit three_h = P3^6;
sbit four_h = P3^7;
void key (void);//按键识别
uchar key_out (void);
void driver(uchar out_data,add);//595发送数据
void delay(uchar H);
void key (void)
{
uchar out_add;
one_h = 0;
if(P1 != 0xff)
{
delay(10);
if(P1 != 0xff) //当确定有第一列有键按下时,查询为哪个按键按下。并发送给595 driver程序.
{
out_add=key_out();
driver(0,out_add);
}
}
one_h = 1;
two_h = 0;
if(P1 != 0xff)
{
delay(10);
if(P1 != 0xff)
{
out_add=key_out();
driver(1,out_add);
}
}
two_h = 1;
three_h = 0;
if(P1 != 0xff)
{
delay(10);
if(P1 != 0xff)
{
out_add=key_out();
driver(2,out_add);
}
}
three_h = 1;
four_h = 0;
if(P1 != 0xff)
{
delay(10);
if(P1 !=0xff)
{
out_add=key_out();
driver(3,out_add);
}
}
four_h = 1;
}
uchar key_out (void) //判断哪一行有键按下
{
uchar out;
switch(P1)
{
case 0xFE: out=0;break;
case 0xFD: out=2;break;
case 0xFB: out=4;break;
case 0xF7: out=6;break;
case 0xEF: out=8;break;
case 0xDF: out=10;break;
case 0xBF: out=12;break;
case 0x7F: out=14;break;
break;
}
return out;
}
void driver(uchar out_data,add)
{
uint data_16,tmep,aaa;
uchar i;
data_16 = 0xFFFF;
data_16 &= (out_data<<add);
switch (add)
{
case 0: data_16|= 0xFFFC;aaa |=0x3; aaa &= data_16;break;
case 2: data_16|= 0xFFF3;aaa |=0xC; aaa &= data_16;break;
case 4: data_16|= 0xFFCF;aaa |=0x30; aaa &= data_16;break;
case 6: data_16|= 0xFF3F;aaa |=0xC0; aaa &= data_16;break;
case 8: data_16|= 0xFCFF;aaa |=0x300; aaa &= data_16;break;
case 10:data_16|= 0xF3FF;aaa |=0xC00; aaa &= data_16;break;
case 12:data_16|= 0xCFFF;aaa |=0x3000; aaa &= data_16;break;
case 14:data_16|= 0x3FFF;aaa |=0xC000; aaa &= data_16;break;
}
ST = 0;
for(i=0;i<16;i++)
{
SH = 0;
tmep = (aaa<<i);
if(tmep < 0x8000)
DS = 0;
else
DS = 1;
SH = 1;
}
ST = 1;
}
void main (void)
{
P3 |= 0xf0;
P1 = 0xff;
while(1)
key();
}
void delay(uchar H)
{
uchar i;
for(; H>0; H--)
for(i=0; i<200; i++);
}
以下电路图可能看不清楚,请向下看贴,我会将清楚的图贴在后面的回复里。
1
void driver(uchar out_data,add)
{
uint data_16,tmep,aaa;
uchar i;
data_16 = 0xFFFF;
data_16 &= (out_data<<add);
switch (add)
{
case 0: data_16|= 0xFFFC;aaa |=0x3; aaa &= data_16;break;
case 2: data_16|= 0xFFF3;aaa |=0xC; aaa &= data_16;break;
case 4: data_16|= 0xFFCF;aaa |=0x30; aaa &= data_16;break;
case 6: data_16|= 0xFF3F;aaa |=0xC0; aaa &= data_16;break;
case 8: data_16|= 0xFCFF;aaa |=0x300; aaa &= data_16;break;
case 10:data_16|= 0xF3FF;aaa |=0xC00; aaa &= data_16;break;
case 12:data_16|= 0xCFFF;aaa |=0x3000; aaa &= data_16;break;
case 14:data_16|= 0x3FFF;aaa |=0xC000; aaa &= data_16;break;
}
ST = 0;
for(i=0;i<16;i++)
{
SH = 0;
tmep = (aaa<<i);
if(tmep < 0x8000)
DS = 0;
else
DS = 1;
SH = 1;
}
ST = 1;
}
其实我有个问题想请教大家的,上面这段有aaa这个变量不是全局变量,为什么退出这个函数,再进来时,aaa的值会保持原来的值呢?不过这也正是我想要的.
这个问题可以这么理解:
aaa变量虽然是局部变量,但是在这个函数退出后并没有其他局部变量来使用aaa的内存空间,造成再次进入本函数时aaa的值保存了上次退出前的值;
“不过这也正是我想要的. ”----不应该利用这种特性,因为您不能在编译前分析它的内存分配,或者说不方便分析,而且这种特性和编译器相关,也就是说,这么写是不可移植的,有可能换个编译器就不能运行,甚至您再添加一些其他代码就会覆盖掉aaa的空间造成aaa的值不是上次退出的值,而变成垃圾。
如果需要在退出的时候还保存aaa的值,可以把它声明为static 类型的变量。
一周热门 更多>