简单加法

2019-03-24 20:07发布

一、采用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; 
 }
}
此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
3条回答
njlianjian
2019-03-25 07:20
这个有两种方式:
1、使用软件来做,用定时扫描;
2、用硬件来做,使用锁存器;
具体程序没怎么看,但是大概的思路是:16进制进行运算,然后转成BCD码进行显示。
以上可供参考

一周热门 更多>