一、采用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; } }
|