原创 一个简单的时钟(数码管显示+24c01存储)

2009-3-20 15:17 2630 2 3 分类: MCU/ 嵌入式

https://static.assets-stash.eet-china.com/album/old-resources/2009/3/20/3fbf5f18-6bd0-45cf-a392-44a8e79ac9d4.rar/*********************************************************************************************************
**功能说明:六个数码管依次显示时,分,秒。三个独立键盘的作用分别是:Key1设置,key2加,key3减 ,开始显示19:22:50. 数据掉电存储
**连接说明:s17,18,19分别接P3.4,P3.2,P3.3位选接p2.7,段选接P2.6(控制显示数)


用到的器件:六个数码管,24c01,STC89c51,两74H573,三独立按键
********************************************************************************************************/
////////////头文件与宏定义///////////////////////////////


#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char



/////////管脚定义与申明//////////////////////////////////


sbit dula="P2"^6;
sbit wela="P2"^7;
sbit key1=P3^4;
sbit key2=P3^2;
sbit key3=P3^3;


sbit  sda_i2c=P2^1;
sbit  scl_i2c=P2^2;


uchar code table[]={  
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};//数码管显示编码


//////////////申明函数/////////////////////////////////////
void display(uchar bit5,uchar bit4,uchar bit3,uchar bit2,uchar bit1,uchar bit0 );      //定义函数时冒号不能少
void init( );
void keyscan( );
void key( );
void delay(uint);


/////////////定义变量//////////////////////////////////////
uchar t,hour,min,sec,b5,b4,b3,b2,b1,b0,mode,station;
uchar k1=0,k2=0,k3=0;
uchar num,add,rec;


 


/*********************************************************************************************************
   延时函数void delay( )
********************************************************************************************************/


void delay(uint z)     //延时子函数
{
 uint x,y;
 for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}


 



//=======================================================================
/*****************************i2c=2401读写******************************/
//=======================================================================


void delay_i2c()
{ ;; }
void start_i2c()  //开始信号
{
 sda_i2c=1;
 delay_i2c();
 scl_i2c=1;
 delay_i2c();
 sda_i2c=0;
 delay_i2c();
}
void stop_i2c()   //停止
{
 sda_i2c=0;
 delay_i2c();
 scl_i2c=1;
 delay_i2c();
 sda_i2c=1;
 delay_i2c();
}
void respons_i2c()  //应答
{
 uchar i;
 scl_i2c=1;
 delay_i2c();
 while(( sda_i2c==1)&&(i<250))i++;
 scl_i2c=0;
 delay_i2c();
}


void init_i2c()
{
 sda_i2c=1;
 delay_i2c();
 scl_i2c=1;
 delay_i2c();
}
void write_byte_i2c(uchar date)
{
 uchar i,temp;
 temp=date;
 for(i=0;i<8;i++)
 {
 temp=temp<<1;
 scl_i2c=0;
 delay_i2c();
 sda_i2c=CY;
 delay_i2c();
 scl_i2c=1;
 delay_i2c();
 }
 scl_i2c=0;
 delay_i2c();
 sda_i2c=1;
 delay_i2c();
}


uchar read_byte_i2c()
{
 uchar i,k;
 scl_i2c=0;
 delay_i2c();
 sda_i2c=1;
 delay_i2c();
 for(i=0;i<8;i++)
 {
 scl_i2c=1;
 delay_i2c();
 k=(k<<1)|sda_i2c;
 scl_i2c=0;
 delay_i2c();
 }
 return k;
}
void write_add_i2c(uchar address,uchar date)
{
 start_i2c();
 write_byte_i2c(0xa0);
 respons_i2c();
 write_byte_i2c(address);
 respons_i2c();
 write_byte_i2c(date);
 respons_i2c();
 stop_i2c();
}


uchar read_add_i2c(uchar address)
{
 uchar date;
 start_i2c();
 write_byte_i2c(0xa0);
 respons_i2c();
 write_byte_i2c(address);
 respons_i2c();
 start_i2c();
 write_byte_i2c(0xa1);
 respons_i2c();
 date=read_byte_i2c();
 stop_i2c();
 return date;
}


 



/*********************************************************************************************************
  主函数void main( )
********************************************************************************************************/


void main( )
{  
    init();
    keyscan( );
   
 init_i2c();
    P2=0X00;
   sec="read"_add_i2c(10);
    delay(100);
  
    min="read"_add_i2c(20);
    delay(100);
 hour=read_add_i2c(30);
    delay(100);
 while(1)
 {   key( );
  display(b5,b4,b3,b2,b1,b0);         //
 }
}


 


/*********************************************************************************************************
  初始化函数void init( )
********************************************************************************************************/


void init( )
{
hour=19;
min=22;
sec=50;                   //先初始化时分秒


TMOD=0X01;                //定时中断初始化
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;



}



/*********************************************************************************************************
  中断定时函数void timer0() interrupt 1 , 记住先定义t,sec,min,hour四个变量
********************************************************************************************************/


void timer0() interrupt 1
{
    TH0=(65536-50000)/256;
 TL0=(65536-50000)%256;
 t++;
 if(t==20)       
   {
    
    b0=sec%10;b1=sec/10;   //得把b放这位置,否则易发生问题
                b2=min%10;b3=min/10;
    b4=hour%10;b5=hour/10;
    
    t=0;
    sec++;
    
    if(sec==60)
       { sec="0";
                     min++;
                     b2=min%10;b3=min/10;  //
        
                     if(min==60)
           { min="0";
                         hour++; 
                         b4=hour%10;b5=hour/10;  //
      
       if(hour==23)  hour="0";
                      
                        }


            
                   }      
       
   } 


}


 


/*********************************************************************************************************
  显示函数用 void display(uchar bit5,uchar bit4,uchar bit3,uchar bit2,uchar bit1,uchar bit0)
********************************************************************************************************/


void display(uchar b5,uchar b4,uchar b3,uchar b2,uchar b1,uchar b0)
{


              dula="1";
  P0=table[b5];    
  dula=0;
  P0=0xff; 
  wela=1;
  P0=0xdf;        //1101 1111即与P0.5相连的数码管显示(即WE1)
  wela=0;
  delay(1);


        dula=1;
  P0=table[b4];
  dula=0;
  P0=0xff;
  wela=1;
  P0=0xef;
  wela=0;
  delay(1);


       dula="1";
  P0=table[b3];
  dula=0;
  P0=0xff;
  wela=1;
  P0=0xf7;
  wela=0;
  delay(1);
        dula="1";
  P0=table[b2];
  dula=0;
  P0=0xff;
  wela=1;
  P0=0xfb;
  wela=0;
  delay(1);


  dula=1;
  P0=table[b1];
  dula=0;
  P0=0xff;
  wela=1;
  P0=0xfd;
  wela=0;
  delay(1);


  dula=1;
  P0=table[b0];
  dula=0;
  P0=0xff;
  wela=1;
  P0=0xfe;
  wela=0;
  delay(1);


}


 


 



/****************************独立键盘扫描程序*****************************/
void keyscan()
{
    if(key1==0)
       {
         delay(100);
         if(key1==0)
            {
              k1=1;
            }


         while(!key1);
         delay(200);
           while(!key1);
       }


    if(key2==0)
       {
         delay(100);
         if(key2==0)
           {
             k2=1;
            }


         while(!key2);
         delay(200);
         while(!key2);
       }


     if(key3==0)
       {
         delay(100);
         if(key3==0)
           {
             k3=1;
            }


         while(!key3);
         delay(200);
         while(!key3);
       }
 
            
}



/*********************************************************************************************************
  键盘扫描子程序
  功能:按一下key1进入模式二进行时间调整,
********************************************************************************************************/
void key()
{
   keyscan();
   if(k1==1){num++;if(num>4)num=0;k1=0;}
   if(k2==1){add=1;k2=0;}
   if(k3==1){rec=1;k3=0;}
   //if(num==0) display(uchar bit5,uchar bit4,uchar bit3,uchar bit2,uchar bit1,uchar bit0 );
   if(num==1)
            {
               if(add==1)
               {
                   sec++;
                   if(sec>59|sec<0)sec=0;
                   add="0";
               }
               if(rec==1)
               {
                   sec--;
                   if(sec<0|sec>59)sec=59;
                   rec="0";
               }
            }
         if(num==2)
             {
               if(add==1)
               {
                   min++;
                   if(min>59|min<0)min=0;
                   add="0";
               }
               if(rec==1)
               {
                   min--;
                   if(min<0|min>59)min=59;
                   rec="0";
               }
            }
         if(num==3)
             {
               if(add==1)
               {
                   hour++;
                   if(hour>23|hour<0)hour=0;
                   add="0";
               }
               if(rec==1)
               {
                   hour--;
                   if(hour<0|hour>23)hour=23;
                   rec="0";
               }
            }
            
       


              if(num==4)
                {
                     P2=0X00;
                     write_add_i2c(10,sec);
                     delay(100);
                     write_add_i2c(20,min);
                     delay(100);
                   write_add_i2c(30,hour);
                     delay(100);
                     num="0";
                }


               b0=sec%10;b1=sec/10; 
       b2=min%10;b3=min/10;
    b4=hour%10;b5=hour/10;



}

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

tengjingshu_112148725 2009-4-10 21:43

学习了
相关推荐阅读
用户1457811 2009-05-12 16:27
LCD1602显示(C语言)转战PIC
https://static.assets-stash.eet-china.com/album/old-resources/2009/5/12/24889110-de14-4408-b3af-77e7...
用户1457811 2009-05-09 20:08
彻底征服LCD1602+DS1302
https://static.assets-stash.eet-china.com/album/old-resources/2009/5/9/043b858b-5d89-44e1-8188-7e97d...
用户1457811 2009-05-09 20:08
彻底征服LCD1602+DS1302+DS18B20(超易理解和移植)
https://static.assets-stash.eet-china.com/album/old-resources/2009/5/9/b0a823cb-8d0f-4cc4-8a2b-d7e50...
用户1457811 2009-04-24 21:48
走的太急了,备战09全国电子设计大赛
大三了,九月份就参加全国电子设计大赛了,可发现自己会的东西真的很少!这段时间似乎挺忙的,又学单片机,又学ARM,又学linux,又学AD6.9。但真的太杂了,力不从心啊,自己真的太急了!应该一步一步脚...
用户1457811 2009-04-11 20:41
fedora 10 3D桌面(ATI HD 3200驱动安装)
昨天因为ATI显卡(我的是ATI HD3200)原因没能体验3D桌面的绚丽,今天找了些帖子终于安上了显卡驱动,方法是:1. 安装驱动su -rpm -Uvh http://download1.rpmf...
用户1457811 2009-04-10 17:49
安装配置fedora 10
   昨天安装了fedora 10(硬盘安装,光盘引导,光盘是用nero软件刻录的),由于以前一直用的是虚拟机安装,所有这次有点不一样。   1 昨天安装过程很顺利(主要是自定义分区时要小心),可参考...
EE直播间
更多
我要评论
1
2
关闭 站长推荐上一条 /3 下一条