一、采用AT89C51单片机为核心,设计一个小系统,至少包括键盘(中断)、显示(LED和数码管)以及存储器。要求:
1、 请画出功能框图。
2、 功能要求:
1) 将键盘分为0-9以及“+”、“-”、“=”、“启动”、“复位”以及“暂停”等功能键。
2) 输入四位十进制数,能够稳定地显示在数码管上。
3) 输入一个数(一位),按启动键,将以该数为初值,以一定的延时间隔加1,并显示到数码管上,加到“9999”后再从“0”开始。
4) (选做)在上一步的基础上,在计数过程中如按下“暂停键”,计数暂停,直到再按“暂停”继续计数或按“复位”键归0停止。
通过键盘和数码管完成两位十进制数的加、减运算并将结果显示。
下面的程序怎样改,请求高手指教:
#include <reg51.h>
#define int8 unsigned char
#define int16 unsigned int
#define int32 unsigned long
#define KEY_PORT P0
#define LED_PORT P1
#define DELY_T 3000
int8 g_key;
int8 num[17]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
int8 seg[4]={16,16,16,16},k_alt=0,k_num=0;
int16 num0=0,num1=0,num_s=0;
void delay(int16 n) //去抖动
{
int16 i,j;
for (i=0;i<n;i++)
{
for (j=0;j<100;j++)
{
;
}
}
}
int8 scan_key(void);
/*
函
数原型:int8 scan_key(void)
功能: 返回按下的按键的行列值,
高位为列,低位为行
返回值:
0xee 0xde 0xbe 0x7e //P0.0
0xed 0xdd 0xbd 0x7d //P0.1
0xeb 0xdb 0xbb 0x7b //P0.2
0xe7 0xd7 0xb7 0x77 //P0.3
// P0.4 P0.5 P0.6 P0.7
*/
int8 scan_key(void)
{
int8 key=0x00;
int8 a,b,i;
KEY_PORT=0x0f;
a=KEY_PORT;
if(a!=0x0f) //有键按下,延时并扫描
{
delay(1);//去抖动
a=0x80;
for(i=0;i<4;i++) //四列分别扫描
{
KEY_PORT=(~a);
key=KEY_PORT;
b=key&0x0f; //取低四位,即行信息
if(b!=0x0f) //该列有键按下,否则扫描下一列
{
switch(key) //有键按下的键对应的行、列均为0,其他为1
{
case 0xee: return 7; //第一行,第一列
case 0xde: return 8; //第一行,第二列
case 0xbe: return 9; //第一行,第三列
case 0x7e: return '+'; //第一行,第四列
case 0xed: return 4; //第二行,第一列
case 0xdd: return 5; //第二行,第二列
case 0xbd: return 6; //第二行,第三列
case 0x7d: return '-'; //第二行,第四列
case 0xeb: return 1; //第三行,第一列
case 0xdb: return 2; //第三行,第二列
case 0xbb: return 3; //第三行,第三列
case 0x7b: return '*'; //第三行,第四列
case 0xe7: return 0; //第四行,第一列
case 0xd7: return '.'; //第四行,第二列
case 0xb7: return '='; //第四行,第三列
case 0x77: return '/'; //第四行,第四列
default: b=0x00; //该列无键按下
}
}
a=a>>1; //准备扫描系一列
}
key=0x00;
}
return key;
}
void show()
{
int16 i;
if(num0==0)
{
seg[0]=0; seg[1]=16; seg[2]=16; seg[3]=16;
}
else if(num_s!=num0)
{
num_s=num0;
for(i=0;i<4;i++)
{
if(num_s!=0) {seg=num_s%10; num_s=num_s/10;}
else seg=16;
}
}
P2=0x80; LED_PORT=num[seg[0]]; for(i=0;i<DELY_T;i++) ;LED_PORT=0xff;
P2=0x40; LED_PORT=num[seg[1]]; for(i=0;i<DELY_T;i++) ;LED_PORT=0xff;
P2=0x20; LED_PORT=num[seg[2]]; for(i=0;i<DELY_T;i++) ;LED_PORT=0xff;
P2=0x10; LED_PORT=num[seg[3]]; for(i=0;i<DELY_T;i++) ;LED_PORT=0xff;
}
void int0() interrupt 0
{
EA=0;
EX0=0;
g_key=scan_key();
EA=1;
EX0=1;
}
void main()
{
EA=1;
IT0=1;
EX0=1;
while(1)
{
switch(g_key) //有键按下的键对应的行、列均为0,其他为1
{
case 7: num0=num0*10+7; g_key=255; break;
case 8: num0=num0*10+8; g_key=255; break;
case 9: num0=num0*10+9; g_key=255; break;
case '+': g_key=255; break;
case 4: num0=num0*10+4; g_key=255; break;
case 5: num0=num0*10+5; g_key=255; break;
case 6: num0=num0*10+6; g_key=255; break;
case '-': g_key=255; break;
case 1: num0=num0*10+1; g_key=255; break;
case 2: num0=num0*10+2; g_key=255; break;
case 3: num0=num0*10+3; g_key=255; break;
case '*':g_key=255; break;
case 0: num0=num0*10+0; g_key=255; break;
case '.': g_key=255; break;
case '/': g_key=255; break;
case '=': num0=0; g_key=255; //reset
default: ; //无键按下
}
show();
KEY_PORT=0x0f;
}
}
此帖出自
小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>