附录(一):实物图
图1
图2
附录(二)软件程序
#include
#define uint unsigned int #define uchar unsigned char
sbit w_select1=P2^0;
sbit w_select2=P2^1; sbit w_select3=P2^2; sbit w_select4=P2^3; sbit cs_1=P2^7;
//unsigned long int a=0;
uchar code table[10] = {0xC0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; //uchar code table[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; /************************************************************** * 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms * x * 输入 : x (延时一毫秒的个数) * 输出 : 无
***************************************************************/ void Delay_1ms(uint x) {
uint i; uchar j;
for(i = 0; i < x; i++) for(j = 0; j <= 148; j++); }
/************************************************************** * 名称: Keyscan()
* 功能: P1外接4×4按键, 按照扫描法读出键值 * 输出: 按键值0~15/如无键按下, 返回16
***************************************************************/ uchar Keyscan(void) {
uchar i, j, temp, Buffer[4] = {0xef, 0xdf, 0xbf, 0x7f}; for(j = 0; j < 4; j++) { //循环四次
P1 = Buffer[j]; //在P1高四位分别输出一个低电平 temp = 0x01; //计划先判断P1.0位 for(i = 0; i < 4; i++) { //循环四次
if(!(P1 & temp)) //从P1低四位,截取1位 return (i + j * 4); //返回取得的按键值 temp <<= 1; //判断的位,左移一位 } }
return 16;
} //呵呵,实质性的语句不过8行,就是这么简练!
void Display1(long a)//显示输入键值对应的十进制数 {
w_select1=0; w_select2=0; w_select3=0; w_select4=0; cs_1=1;
P0 = table[a/1000]&0x7f;
w_select4=1; Delay_1ms(10); w_select4=0;
P0 = table[(a/100)]; w_select3=1; Delay_1ms(10); w_select3=0;
P0 = table[(a/10)]; w_select2=1; Delay_1ms(10); w_select2=0;
P0 = table[a]; w_select1=1; Delay_1ms(10);
/************************************************************** * 名称: Display(uchar k)
* 功能: 将参数分成十位、个位分别显示 * 输入: k (键盘数值)
* 输出: P0口输出七段码,P2口输出位选码
***************************************************************/
void Display2(uchar h) {
P2 = 0; //?? P0 = table[h / 10];
P2 = 0x02; Delay_1ms(5); //??5ms?? P2 = 0; //?? P0 = table[h % 10];
P2 = 0x01; Delay_1ms(5); //??5ms??
}
/************************************************************** * 名称 : Main() * 功能 : 主函数
***************************************************************/
void Main(void) {
uchar Key_Value = 16, Key_Temp1, Key_Temp2; //两次读出的键值 long Temp6,Temp7,Temp8,Temp9,Temp4=0,Temp5; int k,j=0, i=0,count; uchar A[4]; cs_1=1; P3=0x00; Temp4=P3; P0=0xff; while(1) {
//---------以下读入按键、消抖、等待按键释放
P1 = 0xff;
Key_Temp1 = Keyscan(); //先读入按键 if(Key_Temp1 != 16) { //如果有键按下
Delay_1ms(5); //延时一下
//Display(Key_Value); //可用显示代替延时 Key_Temp2 = Keyscan(); //再读一次按键 if (Key_Temp1 == Key_Temp2) {//必须是两次相等
Key_Value = Key_Temp1; //才保存下来,这就是消除抖动 while(Keyscan()<16) Display2(Key_Value);
if((Key_Value<10)&&(i<5))//对按键次数进行计数 {A[i]=Key_Value; i++;
12
count=i; if(i==4)i=0;
}
switch(count) //把连续按键值转换成对应的十进制数
{case 1:{Temp5=A[0];Display1(Temp5); Delay_1ms(5);} break;
case 2:{Temp5=A[0]*10+A[1];Display1(Temp5);Delay_1ms(5); } break;
case 3 :{Temp5=A[0]*100+A[1]*10+A[2];Display1(Temp5);Delay_1ms(5);} break; case 4:{Temp5=A[0]*1000+A[1]*100+A[2]*10+A[3]; Display1(Temp5);Delay_1ms(5);
if(Temp5>=5001) Temp5=0;}break; }
if(Key_Value==13) //键值步进加20 { if(j==1) {Temp6=Temp7;} else
Temp6=Temp5; Temp6=Temp6+20; Temp7=Temp6; Display1(Temp7); Delay_1ms(5); k=j=1; }
if(Key_Value==14) //键值步进减20 { switch(j)
{case 0:Temp8=Temp5;break; case 1:Temp8=Temp7;break; case 2:Temp8=Temp9;break;}
Temp8=Temp8-20; Temp9=Temp8; Display1(Temp9); Delay_1ms(5); k=j=2; }
if(Key_Value==12) //DA转换控制键 {
switch(k)
{case 0:Temp4=Temp5*0.0512;break;
case 1:Temp4=Temp7*0.0512;Temp5=Temp7;break;
case 2:Temp4=Temp9*0.0512;Temp5=Temp9;break; } k=0;
cs_1=0; P3=Temp4;
} } }
if(Key_Value==13) Display1(Temp7);
13