⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 计数器.txt

📁 一个基于51单片机的时钟电路设计源代码
💻 TXT
字号:
// 1    2       3       +       =
// 4    5       6       -       ce
// 7    8       9       *       on/off
// +/-  0       .       /

//按键:     0   1   2   3   4   5   6   7   8   9
//对应值:   0   1   2   3   4   5   6   7   8   9
//按键:     +   -   *   /   =   .   +/-
//对应值:   10  11  12  13  15  16  17
#include "reg51.h"
#include "math.h"
#define key_null 255
#define uchar unsigned char
#define uint  unsigned int
sbit P0_0=P0^0 ;
sbit P0_1=P0^1 ;
sbit P0_2=P0^2 ;
sbit P0_3=P0^3 ;
sbit P0_4=P0^4 ;
sbit P0_5=P0^5 ;
sbit P0_6=P0^6 ;
sbit P0_7=P0^7 ;
sbit P1_0=P1^0 ;
sbit P1_1=P1^1 ;
sbit P1_2=P1^2 ;
sbit P1_3=P1^3 ;
sbit P1_4=P1^4 ;
sbit P1_5=P1^5 ;
sbit P1_6=P1^6 ;
sbit P1_7=P1^7 ;
sbit P2_0=P2^7 ;
sbit P3_0=P3^0 ;
sbit P3_1=P3^1 ;
sbit P3_2=P3^2 ;
sbit P3_3=P3^3 ;
sbit P3_4=P3^4 ;
sbit P3_5=P3^5 ;
sbit P3_6=P3^6 ;
sbit P3_7=P3^7 ;
uchar idata p_led,buff[9],keynum[8],opcode[4],op,operate,key,knum,num,dot ;
                                      //  buff[9]的前8个元素为显示屏上8片led对应的数字,buff[8]为显示屏中应显示的数字的个数
                                      //  数组keynum(8)存放从键盘获得的计算数,operate 存放从键盘获的计算符
                                      //  key 存放获得的键盘值,区分计算数和计算符后分别存入keynum(8)和operate中
                                      //  opcode[4]为为实现优先运算而设立存放计算符
                                      //  knum 为 keynum[8]的指针
                                      //  num 为 opnum[3]的指针
                                      //  dot为keynum[8]中小数点的位置


float opnum[3] ;
           //  opnum[3]为为实现优先运算而设立存放计算数

bit flag=1;
          //  标志是否可将计算符operate存入opcode[]中,以防出现多次按下计算符
bit flag3=1;
          //  标志是否有计算符按键按下
bit flag4=0;
         //   进行count()中第一种运算的标志
bit flag5=0;
         //   进行count()中第二种运算的标志

bit dotflag,revflag;
         //   dotflag为小数点标志,revflag 为正负数标志
uchar keyscan(void)    // 键盘扫描程序
{

 uchar temp=key_null;
           //  对p0赋初值1111 1111 ,p2_0赋初值0
  P0=0xfe;
           //  对p0赋值 1111 1110,对第一行进行扫描
  if (P0_4==0)  temp=1;         //  扫描第一列
  else if (P0_7==0) temp=10;
  P0=0xfe;
  if (P2_0==0) temp=15;
  P0=0xfe;
  if (P0_5==0) temp=2;     //  扫描第二列
  P0=0xfe;
  if (P0_6==0) temp=3;     //  扫描第三列
      //  扫描第四列
     //  扫描第五列
  P0= 0xfd;        // 对第二行进行扫描
  if (P0_4==0)  temp=4;
  else if (P0_5==0) temp=5;
  P0= 0xfd;
  if (P0_6==0) temp=6;
  else if (P0_7==0) temp=11;
  P0=0xfb;         // 对第三行进行扫描
  if (P0_4==0)  temp=7;
  else if (P0_5==0) temp=8;
  P0=0xfb;
  if (P0_6==0) temp=9;
  else if (P0_7==0) temp=12;
  P0=0xf7;        // 对第四行进行扫描
  if (P0_4==0)  temp=17;
  else if (P0_5==0) temp=0;
  P0=0xf7;
  if (P0_6==0) temp=16;
  else if (P0_7==0) temp=13;

  //send(temp);
  return temp;
}

uchar read_key(void)    //  把键盘值取入程序中
{
  uchar i;
  uint j;
  for(;keyscan()!=key_null;);          //  等待按键放开
  loop: for(;keyscan()==key_null;);    //  等待按键按下
  i=keyscan();
  for(j=0;j<2000;j++)   // 延时2ms
  if(i==keyscan()) return i;           //   两次获取按键,若一致,输出该值
  else goto loop ;
}
void ledscan(void) interrupt 1         //   显示屏扫描程序
{
  uchar led_code[21]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xbf};
                       //   led_code[0~9] : 0~9   led_code[10~19]:0.~9.  led[20]:-
  TH0=-(1000/256);
  TL0=-(1000%256);     //    计数器复位
    if(p_led<buff[8]){
   
    
     // 对显示屏的led进行动态赋值
    if(p_led<4) P3=~(0x10<<p_led);    //注意电路中得接法
    else P3=~(0x01<<(p_led-4));
    P1=led_code[buff[p_led]];  //注意取数时应倒取
 p_led++;
}
 else p_led=0;
   if(p_led==8)p_led=0;
  if(buff[7]==20)
  {
     P3=0xf7;
     P1=led_code[20];
  }
}
void getopnum(void)           // 获取计算数
{
   uchar i,n;
   float a,b;
   if(keynum[0]<20)            //如果没有新数进knum[0]=20
   {

      if(dotflag==1) n=dot;    //  n为keynum[8]中整数部分的长度
      else n=knum;
      a=0;
      b=0;
      for(i=0;i<n;i++) a+=keynum[i]*pow(10,n-i-1);       //取出整数部分
      if(dotflag==1)
      for(i=n+1;i<knum;i++) b+=keynum[i]*pow(0.1,i-n);   //取出小数部分
      keynum[0]=20;
      opnum[num]=a+b;
      if(revflag==1)opnum[num]=-opnum[num];       //若有按下+/-键,对opnum[num]取反
      if(num==0) opnum[1]=opnum[0];
      num++;
   }
}
uchar  judge(uchar opno1,uchar opno2)      //对计算符进行优先级别判断,先乘除后加减
{
   char a,b;
   switch(opno1)
   {
      case 10:
         a=2;
         break;
      case 11:
         a=2;
         break;
      case 12:
         a=3 ;
         break;
      case 13:
         a=3;
         break;
      case 14:          // 14为自己添加的最低等级的符号,且一直存放在opcode[0]中
         a=0;
         break;
      case 15:
         a=1;
         break;
   }
    switch(opno2)
   {
      case 10:
         b=2;
         break;
      case 11:
         b=2;
         break;
      case 12:
         b=3;
         break;
      case 13:
         b=3;
         break;
      case 14:
         b=0;
         break;
      case 15:
         b=1;
         break;
   }
   if((a-b)>=0) return 1;              //优先级别高的,所赋的值较大
   else return 0;
}
void count(void)
{
   while(judge(opcode[op],operate)==1)
   {
      if(operate==15 && op<=2)       //第一种运算,使opcode中至少存放一个计算符,可进行累运算,如2+3===11
      {
         if(opcode[op]==10) opnum[num-2] += opnum[num-1];
         else if(opcode[op]==11) opnum[num-2] -= opnum[num-1];
         else if(opcode[op]==12) opnum[num-2] *= opnum[num-1];
         else if(opcode[op]==13) opnum[num-2] /= opnum[num-1];
         flag4=1;
         break;
      }
      else             //在为按下等号时将式中可运算的部分运算完,但要保留最后一个运算符
      {
         if(opcode[op]==10) opnum[num-2] += opnum[num-1];
         else if(opcode[op]==11) opnum[num-2] -= opnum[num-1];
         else if(opcode[op]==12) opnum[num-2] *= opnum[num-1];
         else if(opcode[op]==13) opnum[num-2] /= opnum[num-1];
         op--;
         num--;
         flag5=1;
      }
   }
}
void send(uchar lednum )             //  送出按键按下时代表的值
{
   uchar i;
   if(flag3==1)
   {
      buff[8]=0;
      flag3=0;
   }
   if(lednum>=0 && lednum<=9)
   {
      for(i=buff[8];i>0;i--) buff[i]=buff[i-1];
      buff[0]=lednum;
      buff[8]++;
   }
   if(lednum==16) buff[0]+=10;
   if(revflag==1) buff[7]=20;
   else buff[7]=0;
}
void send2(float f)             //  送出每次可计算的计算结果的值
{
   int  intnum,temp,i,k,n,j,dectemp[6];
   float dec;
   bit flag;
   buff[7]=0;
   flag=0;
   i=0;
   temp=0;
   buff[8]=0;
   if(f<0)           //  #####
   {
      flag=1;
      f=fabs(f);
      buff[7]=20;
   }
   intnum=f;
   dec=f-intnum;
   if(intnum>0)
   {
      while(intnum>0)
      {
         buff[i]=intnum%10;
         intnum=intnum/10;
         i++;
         buff[8]++;
      }
      n=i;
   }
   else buff[0]=0;
   if(dec>0.000009 && dotflag==1)
   {
      buff[0]+=10;
      for(j=0;j<6;j++)
      {
         dec*=10;
         temp=dec;
         dec-=temp;
         dectemp[j]=temp;
      }
      dectemp[5]+=5 ;                       //########################
      for(i=4;i>=0;i--)
      {
         dectemp[i]+= dectemp[i+1]/10;      //#########################
         dectemp[i+1]=dectemp[i+1]%10;
      }                                     //######################
      dectemp[0]=dectemp[0]%10;
      for(j=4;j>=0;j--)
      {
         if(dectemp[j]!=0)
         {
            temp=j;
            break;
         }
            temp=j;
      }


   if(flag==1) k=7;
   else k=8;
   for(j=0;j<=temp && n+j<k;j++)
   {

      for(i=buff[8];i>0;i--) buff[i]=buff[i-1];
      buff[0]=dectemp[j];
      buff[8]++;          //#####  此算法为将所得结果浮点型的数拆分为单个整数,存放在数组buff中
   }
  }
}
void getnum()
{
  uchar k;
  key=read_key();

  if(key==16 &&  dotflag==0)
  {
     dotflag=1;
     if(knum==0)
     {
        keynum[0]=0;
        knum++;
        buff[8]=1;
     }
     dot=knum;
     knum++;
     send(16);
  }
  if(key==17)
  {
     revflag=!revflag;
     send(17);
  }   //main(): flag2=revflag
  if(key>=0 &&  key<=9)
  {
     if(revflag==1) k=7;
     else k=8;
     if(knum<=k)
     {
        keynum[knum]=key;
        knum++;
        if(operate==15)
        {
           opcode[0]=14;
           op=0;
           num=0;
           revflag=0;
        }
        if(flag==1 && (opcode[op]!=15 ||  operate!=15))
        {
           op++;
           opcode[op]=operate;
           flag=0;
        }
        send(key);
     }
   }
  else if(key>=10 && key<16)
  {
     flag3=1;
     if(key!=15 && flag==1 && operate==15)
     {
        op=0;
        opcode[0]=14;
        num--;
     }
     if(flag==0)
     {
        getopnum();
     }
     operate=key;
     flag=1;

     if(num>=2 && op>=1) count();
     if(flag4==1)
     {
        send2(opnum[num-2]);
        flag4=0;
     }
     else if(flag5==1)
     {
        send2(opnum[num-1]);
        flag5=0;
     }
     knum=0;
     dotflag=0;
     revflag=0;
  }
}


main()
{
   p_led=0;
   P1=0xc0;
   P3=0xef;
   buff[8]=0;
   buff[7]=0;
   knum=0;
   op=0;
   num=0;
   operate=14;
   opnum[0]=0;
   buff[0]=0;
   revflag=0;
   dotflag=0;
   TH0=-(1000/256);
   TL0=-(1000%256);
   TMOD=0x01;
   EA=1;
   ET0=1;
   TR0=1;
   while(1) getnum();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -