急求一个用AT89C52控制,2个4位数码管(用74HC595驱动)显示的简易时分秒的电子钟。需要c语言程序。附图

kuaidi.ping-jia.net  作者:佚名   更新日期:2024-07-29
【急】请问下,如何用一个AT89C52和两个74H595做出一个单片机定时器的电子时钟,利用这个图写出程序

你好!显示时分秒,然后通过按键调节时间?

主要看你的数码管是共阴还是共阳的,如果是共阳那就好办,595的8个输出连数码管的7段和小数点,然后两个位选直接用8550驱动就行了,程序的思路就是先选通位,然后给595段码,然后延时再选通另外一位再给595段码延时,一直重复这个就行了。

/************************************************/
/*******************数字电子钟*******************/
/************************************************/
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int

sbit qingling=P1^0;     //清零
sbit tiaofen=P1^1;      //调分
sbit tiaoshi=P1^2;      //调时
sbit sounder=P1^7;      //naozhong
sbit ds = P3^5;         // 595
sbit st_cp = P3^7;
sbit sh_cp = P3^4;
uint a,b;
uchar hour,minu,sec,    //时钟
      hour0,minu0,sec0, //秒表
      hour1,minu1,sec1;
      h1,h2,m1,m2,s1,s2,//显示位
      k,s;  //状态转换标志
uchar j,datah,datal;       
uchar code select[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
/*****************函数声明***********************/
void keyscan();
void init();
void delay(uchar z);
void display(uchar,uchar,uchar);
void sounde();
void disp595();
/*****************主函数*************************/       
void main()
{
    init();
    while(1)
    {             
    while(TR1)
    {
     
    keyscan();    //扫描函数
    while(s==1)   //s是状态标志,当s=0时,闹钟取消。s=1时,设定闹钟时间 
    {             //s=2时,闹钟工作,时间与设定时刻一致时,闹钟响
    keyscan();                    //s状态切换(0-》1-》2-》0)通过外部中断1实现。
    display(hour1,minu1,sec1); //闹钟时刻显示
     }
    display(hour0,minu0,sec0);//时钟表显示           
           
     while(k)      /*k是秒表状态(0-》1-》2-》0)通过外部中断0实现。*/
     {
     display(hour,minu,sec);      //秒表显示           
      }
         
    }
  }

}

/*****************初始化函数***********************/
void init()
{
      a=0;
      b=0;
      k=0;
      s=0;
      hour0=0;
      minu0=0;
      sec0=0;
      hour=0;
      minu=0;
      sec=0;
      hour1=0;
      minu1=0;
      sec1=0;

      TMOD=0x11;              //定时器0,1工作于方式1;赋初值
      TH0=(65536-5000)/256;
      TL0=(65536-5000)%256;
      TH1=(65536-50000)/256;
      TL1=(65536-50000)%256;
     
      EA=1;
      EX0=1;       //秒表中断
      EX1=1;       //闹钟设定中断
      ET0=1;
      ET1=1;
      IT0=1;        //边沿触发方式
      IT1=1;

      PX0=1;
      PX1=1;
     
      TR0=0;              //初始,秒表不工作
      TR1=1;        //时钟一开始工作     
}

/*****************定时器0中断*************/
void timer0_int() interrupt 1      //秒表
{
      TH0=(65536-5000)/256;
      TL0=(65536-5000)%256;
      a++;
      if(a==2)
      {
      a=0;
      sec++;
      if(sec==100)
            {
            sec=0;      //毫秒级
            minu++;
            if(minu==60)
            {
                  minu=0;            //秒
                  hour++;
                  if(hour==60)        //分
                  {
                  hour=0;
                  }
            }
            }
      }
     
}

/*************外部中断0中断函数************/
void ex0_int() interrupt 0
{     
      k++;
      if(k==3)
      k=0;
      if(k==1)
      {
      TR0=~TR0;
      if(TR0==1)
      {             
         hour=0;
         minu=0;
         sec=0;     
      }
      }
      if(k==2)
      {
      TR0=~TR0;
      }       
}

/*************外部中断1中断函数************/
void ex1_int() interrupt 2
{
      s++;
      if(s==3)
      s=0;
}

/*************定时器1中断****************/
void timer1_int() interrupt 3       //控制时钟工作
{
      TH1=(65536-50000)/256;
      TL1=(65536-50000)%256;
      if(s==2)
      {
      if(hour1==hour0 && minu0==minu1)
      sounde();
      }
      b++;
      if(b==20)
      {
      b=0;
      sec0++;
         if(sec0==60)
           { 
              sec0=0;
                minu0++;
              if(minu0==60)
               {
                   minu0=0;
                   hour0++;
                   if(hour0==24)
                         hour0=0;
               }
           }
      }
}
/*************键盘扫描****************/
void keyscan()
{
      if(s==1)
      {
      if(qingling==0)
      {
            delay(10);
            if(qingling==0)
            {
            sec1=0;
            minu1=0;
            hour1=0;
            }
      }
      if(tiaofen==0)
      {
            delay(10);
            if(tiaofen==0)
            {
            minu1++;
            if(minu1==60)
            {
                  minu1=0;
            }
            while(!tiaofen);
            }
      }
      if(tiaoshi==0)
      {
            hour1++;
            if(hour1==24)
            {
            hour1=0;
            }
            while(!tiaoshi);
      }
      }
      else              //调整时钟时间
      {
       if(qingling==0)
      {
            delay(10);
            if(qingling==0)
            {
            sec0=0;
            minu0=0;
            hour0=0;
            }
      }
      if(tiaofen==0)
      {
            delay(10);
            if(tiaofen==0)
            {
            minu0++;
            if(minu0==60)
            {
                  minu0=0;
            }
            while(!tiaofen);
           
            }
      }
      if(tiaoshi==0)
      {
            hour0++;
            if(hour0==24)
            {
            hour0=0;
            }
            while(!tiaoshi);
      }
      }     
}
/*************显示函数****************/
void display(uchar hour,uchar minu,uchar sec)
{
      h1=hour/10;
      h2=hour%10;
      m1=minu/10;
      m2=minu%10;
      s1=sec/10;
      s2=sec%10;

      datah=table[h1];
      datal=select[7];
   disp595();
      delay(5);

      datah=table[h2];
      datal=select[6];
   disp595();
      delay(5);

      datah=0x40;
      datal=select[5];
   disp595();
      delay(5);

      datah=table[m1];
      datal=select[4];
   disp595();
      delay(5);

      datah=table[m2];
      datal=select[3];
   disp595();
      delay(5);

      datah=0x40;
      datal=select[2];
   disp595();
      delay(5);

      datah=table[s1];
      datal=select[1];
   disp595();
      delay(5);

      datah=table[s2];
      datal=select[0];
   disp595();
      delay(5);
}
/*************disp595()函数****************/
void disp595()
{
 for(j=0;j<8;j++)
 {
  sh_cp=0;
  datal<<=1;
  ds=CY;
  sh_cp=1;//sh_cp上升沿 移位
 }
 for(j=0;j<8;j++)
 {
  sh_cp=0;
  datah<<=1;
  ds=CY;
  sh_cp=1;//sh_cp上升沿 移位
 }
 st_cp=0;
    st_cp=1;//st_cp上升沿 存储 
}
/*************闹钟函数****************/
void sounde()
{
      sounder=~sounder;     
}
/*************延时函数****************/
void delay(uchar z)
{
      int x,y;
      for(x=z;x>0;x--)
      for(y=110;y>0;y--);
}



貌似可以做定时砸蛋滴哦

  • AT89C52单片机控制发光二极管的亮灭的C程序编程如何写?
    答:这种最基本的程序随便拿本书或网上一搜都是啊 include <AT89X51.H> sbit K1=P3^0;sbit L1=P1^0;void main(void){ while(1){ if(K1==0) //开关闭合 { L1=0;//灯亮 ---p1.0输出低电平 ,L1有电势差。} else { L1=1;//灯灭 } } } ...
  • 求一个由AT89C52单片机控制的八路抢答器的C语言程序设计
    答:j++);}main(){uchar i,key; P2=0xff; while(1) { i=0; P1=table[i]; while(1) { key=P3; if(key!=0)break; } switch(key) { case 0x01:i=1;break; case 0x02:i=2;break; case 0x04:i=3;break; case 0x08:i=4;break; case 0x10:i=5;break; case 0x20:...
  • AT89C52单片机数字时钟,怎么控制按钮让它可以设置时间
    答:设置一个按键位置变量,如用012345对应年月日时分秒,对就位置修改对应时间,超过5就循环回0。if(进入修改时间){ switch(按到修改的位置){ case 0: 调用按键扫描,如有修改再调用 更改年份程序,保存 case 1: 调用按键扫描,如有修改再调用 更改月份程序,保存 case 2: 调用按键扫描,如有修改再...
  • 急求DHT11 用AT89C52单片机驱动的C程序,最好能和郭天祥51单片机兼容的...
    答:这个与兼空与否没太大关系,我的是11.0592MH的时钟,你只需要程序中将定义的通信管脚改一下就可以使用了。很简单。里面可以读取2个DHT11,你随便选一个用就行了。已发送。
  • 急需电子时钟的设计,利用单片机AT89C52、时钟芯片DS1302、1602液晶显示...
    答:include<reg52.h> include<define.h> void delay(uint z){ uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);} void didi(){ beep=0;delay(50);beep=1;delay(100);beep=0;delay(50);beep=1;} void write_com(uchar com){ rs=0;lcden=0;P0=com;delay(5);lcden=1;delay...
  • 做AT89C52和继电器控制电机的系统,烧进程序后系统不稳定的原因?电路系 ...
    答:你的89C52集成块电源供电系统抗干扰较差造成,1.加大5V电源输出功率。2.加大5V电源滤波电容。3.加大89C52集成块复位电容,最大可至1uF(此时,集成块上电时有1S左右的复位时间),4,.检查89C52集成块的晶振在线路板上的走线是否太长,并用大面积覆铜与地连接,将此处与其他布线隔离,确保该震荡信号不...
  • 求助,我要用at89c52单片机去控制16路的舵机控制板.舵机控制板上有scl...
    答:AT89C52是没有SCL和SDA的,但可以用32个IO口中的任意两个来模拟。所以楼主的定义方法是可以的。
  • AT89C52低功耗模式
    答:在低功耗操作中,AT89C52提供了两种节能模式:空闲节电模式和掉电模式。在空闲节电模式下,CPU进入休眠状态,但片内所有的外设仍保持激活。这个模式由软件控制,当系统进入空闲状态时,会将片内RAM和特殊功能寄存器的内容暂时冻结。任何允许的中断请求或硬件复位都能结束这种状态。值得注意的是,当从空闲模式...
  • 关于用AT89C52单片机控制一个数码管显示问题
    答:我手工画的八个led是一个共阴数码管的原理图 a b c d e f g 分别是数码管的每一个段,dp是数码管的小数点(这些都称为段选)。他们的阴极连到一块,称为公共端(为什么叫共阴数码管就是这样来的)。数码管显示不同的数字,是通过让数码管的不同段的亮灭组合实现的。比如说要显示0,需要使...
  • 怎么用at89c52控制一个220v的风扇的快慢,因为单片机才几伏,而风扇确...
    答:单片机驱动一个三极管,三极管驱动一个继电器,继电器常开触点串联风扇接220V,就可以了。还可以是单片机通过光电耦合器驱动双向可控硅,再驱动电扇,这样甚至可以调速。