loading ...

2006-07-03 | C51单片机实现液晶秒表以及简单计算器-----C51单片机制作

分享

DESIGNED  BY   HUAZ            2006.6.2

电路图比较简单,是一个51最小系统,没有采用总线方式,而简单的连线方式,上有4*4矩阵键盘,一数码管,89S51单片机,串口下载线,数码管显示锁存芯片\蜂鸣器\1602液晶.

因为最近考试太多,刚刚考试完又课程设计,桌子上太混乱,原理图没有找到.所以就先贴上代码.

此代码已经调试成功过,可以实现时间的调整.4*4矩阵键盘,第一排前三列是实现小时\分钟\秒的加.第二排前三列是实现小时\分钟\秒的减.当然还可以通过设置矩阵键盘的键值,来实现加\减\乘\除四则运算,由数码管显示参与运算的数字以及最终的运算结果.其他的不多说了,等下次我把图贴上,大家勉强可以拿去研究下.其实硬件很简单,不详细说问题也不大的.

#include<reg51.h>
#include<stdio.h>
#include<stdlib.h>
#include<intrins.h>
#include<absacc.h>
#define uchar unsigned char
#define uint unsigned int
uchar temp1;
void displayListChar(unsigned char X, unsigned char Y, uchar DData);
uchar dispbuf[]={'0','1','2','3','4','5','6','7','8','9',':'};

uchar second; 
uchar minute;
uchar hour;
uint tcnt,g;
uchar flag;

void dlms(void);
uchar kbscan(void);
void Show_Time(void);
void delay5ms(void);
  void dlms(void);
   void Settime(uchar verify);//verify 在这里为调整的意思

 void delay400ms(void) ;

///#define busy 0x80 file://用/于检测LCD状态字中的Busy标识
///#define RSaddr 0x1000
///#define RWaddr 0x2000
///#define CSaddr 0x0400
#define wc 0x8fff
#define wd 0xdfff
#define rc 0xbfff
void waitLcd()                     //just wait until 液晶不忙为止
  {
    char temp;
    bit flag=1;
    while(flag==1)
    {
       temp=XBYTE[rc];
       if (temp>>7==0) flag=0;
       P1=temp;
    }
      P1=0xff;
  }
                                    //just wait until 液晶不忙为止
void WriteCommand_Lcd(bit isCheck,char c)   
  {
    if (isCheck==1) waitLcd();
     XBYTE[wc]=c;
  }

void writedata(char c)
{
    waitLcd();
    XBYTE[wd]=c;
}

void LcdInit()
  {
    delay5ms();
  delay5ms();
 delay5ms();
 WriteCommand_Lcd(0,0x38); //三次显示模式设置,不检测忙信号
 delay5ms();
 WriteCommand_Lcd(0,0x38);
 delay5ms();
 WriteCommand_Lcd(0,0x38);
 delay5ms();
 WriteCommand_Lcd(1,0x38); //显示模式设置,开始要求每次检测忙信号,8位2行5*7
 WriteCommand_Lcd(1,0x08); //关闭显示
 WriteCommand_Lcd(1,0x01); //清显示
 WriteCommand_Lcd(1,0x06); // 文字不动,光标右移
 WriteCommand_Lcd(1,0x0C); // 显示开及光标设置
  }


void displayListChar(unsigned char X, unsigned char Y, uchar DData)
  {
 Y &= 0x1;
 X &= 0xF;
 if (X <= 0xF)
   {
    Y &= 0x1;
 X &= 0xF;
 if (Y) X |= 0x40;
 X |= 0x80;
 WriteCommand_Lcd(0,X);
 writedata(dispbuf[DData]);
 
   }
 }

 void Show_Time(unit k)
{
   displayListChar(0,0,hour/10);
   displayListChar(1,0,hour%10);
   displayListChar(2,0,10);
   displayListChar(3,0,minute/10);
   displayListChar(4,0,minute%10);
   displayListChar(5,0,10);
   displayListChar(6,0,second/10);
   displayListChar(7,0,second%10);
 switch(k)
{
  case 1: displayListChar(0,1,1);
  case 2: displayListChar(0,1,2);
  case 3: displayListChar(0,1,3);
  case 4: displayListChar(0,1,4);
  case 5: displayListChar(0,1,5);
  case 6: displayListChar(0,1,6);
  case 7: displayListChar(0,1,7);
  case 8: displayListChar(0,1,8);
  case 9: displayListChar(0,1,9);
  case 10:displayListChar(0,1,10);
  case 11:displayListChar(0,1,11);
  case 12:displayListChar(0,1,12);
  case 13:displayListChar(0,1,13);
  case 14:displayListChar(0,1,14);
  case 15:displayListChar(0,1,15);
  case 16:displayListChar(0,1,16);
 }
 


 void Settime(uchar verify)
{
  //键盘设置
//    1 /hour+    (0xee)     2/minute+  0xde   3/second+  0xbe     +
// 4/hour-   0xed   5/ minute-   0xdd     6/second-    0xbd        -
// 7   8   9   *
// 0  CLR  =   /
  ////hour+的代码
   if(flag)
   {
    if (verify==0xee)
   {
         dlms();
   if (verify==0xee)
   {
           hour++;
                 if(hour==24)
                {
                  hour=0;
                }
    //while(verify==0xee);           
      verify=0x00;
        }
   //    1 /hour+    (0xee)     2/minute+  0xde   3/second+  0xbe
 }
  ///minute +的代码
   else if (verify==0xde)
   {
         dlms();
   if (verify==0xde)
   {
           minute++;
                 if(minute==60)
                {
                 minute=0;
                }
    //while(verify==0xde);           
      verify=0x00;
        }
   //    1 /hour+    (0xee)     2/minute+  0xde   3/second+  0xbe
  }
//////second++的代码
    else if (verify==0xbe)
   {
         dlms();
   if (verify==0xbe)
   {
           second++;
                 if(second==60)
                {
                 second=0;
                }
   // while(verify==0xbe);           
       verify=0x00;
        }    
   //    1 /hour+    (0xee)     2/minute+  0xde   3/second+  0xbe
  }

//////hour- (0xed) 的代码
  else if (verify==0xed)
   {
        dlms();
   if (verify==0xed)
   {
    if(hour==0)
          {hour=24;
     }
     hour--;
                // if(hour==0)
               // {
               //   hour=23;
                //}
    //while(verify==0xed);           
      verify=0x00;
        }
  
 }
 // 4/hour-   0xed   5/ minute-   0xdd     6/second-    0xbd
///下面为minute -的代码
    else  if (verify==0xdd)
   {
        dlms();
   if (verify==0xdd)
   {     if(minute==0)
          {minute=60;}
           minute--;
                 //if(minute==0)
                //{
                // minute=59;
                //}
    //while(verify==0xdd);           
      verify=0x00;
        }
   
  }
// 4/hour-   0xed   5/ minute-   0xdd     6/second-    0xbd
///下面为second -的代码
  else  if (verify==0xbd)
   {
         dlms();
   if (verify==0xbd)
   { if(second==0)
          {second=60;}
           second--;
                 //if(second==0)
                //{
                // second=59;
                //}
   // while(verify==0xbd);           
       verify=0x00;
        }     
 // 4/hour-   0xed   5/ minute-   0xdd     6/second-    0xbd 
  }

}

   
}


void main(void)
{
  
    TMOD=0x02; //置自动重装载模式
    TH0=0x06;   //设初值
    TL0=0x06;  //设初值
    TR0=1;     //开始计数
    ET0=1;    //开定时器/计数器
    EA=1;     //中断开
    delay400ms();//启动等待,等LCM讲入工作状态
    LcdInit();     //LCM初始化
    while(1)
   { 
       uchar key;
      key=kbscan();
    dlms(); 
    Show_Time();
   // if ((key==0xee)||(key==0xbe)||(key==0xde)||(key==0xed)||(key==0xdd)||(key==0xbd))
   if (key!=0)
   {
         if (key==0x7e)
           {
              dlms();
   if (key==0x7e)
   {
       EA=0;
    flag=1;
               
                }
    //while(verify==0xee);           
      key=0x00;
        }
     
   if (key==0x7d)
   {
         dlms();
   if (key==0x7d)
   {
       EA=1;
    flag=0;
               
                }
    //while(verify==0xee);           
      key=0x00;
        }
  
         Settime( key );
         delay400ms();
   }

    }
}
    

void delay5ms(void)          
  {
   unsigned int TempCya = 277;
 while(--TempCya);
  }      


 
  //延时400ms
void delay400ms(void)          
  {
   unsigned int TempCya = 22160;
 while(--TempCya);
  }                     
  //延时400ms

 


void timer0(void) interrupt 1 using 1
{  
  tcnt++;
  if(tcnt==2000)
    {
      tcnt=0;
      second++;
      if(second==60)
        {
          second=0;
          minute++;
          if(minute==60)
            {
              minute=0;
              hour++;
              if(hour==24)
                {
                  hour=0;    
                }


             }
   
         }
     }
  
      }

//键盘扫描
uchar kbscan(void)
{  
    uchar sccode;
 P1=0xf0;
 if( (P1&0xf0)!=0xf0 )
 {
     dlms();
  if((P1&0xf0)!=0xf0)
  {
     sccode=0xfe;
     while ((sccode&0x10)!=0)
     {
         P1=sccode;
      if ((P1&0xf0)!=0xf0)
       {
        temp1=P1;
     return  temp1;
    }
    else
    {
       sccode=(sccode<<1)|0x01;
                }
         
      }
        }
      }
return (0);
}
            
void dlms(void)
{   
      g=554;
      while(g--);  //延时10mS钟
}

分享 分享 |  评论 (3) |  阅读 (?)  |  固定链接 |  类别 (个人项目和作品) |  发表于 14:26  | 最后修改于 2006-07-03 14:31
搜狐博客温馨提示:警惕博客留言诈骗, 搜狐博客管理员的正确地址为http://admin.blog.sohu.com, 其他都是冒牌。搜狐博客官方不会要求参加活动的各位博友缴纳任何的手续费用。请勿轻信留言、评论中的中奖信息,更不要拨打陌生电话及向陌生帐户汇款,谨防受骗!识别更多网络骗术,请 点击查看详情
正在读取评论信息...
您还未登录,只能匿名发表评论。或者您可以 登录 后发表。
 
  一个单亲妈妈的心愿:治好7岁儿子的白血病
表  情:
加载中...
回复通知: 同时用小纸条通知对方该回复