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

📄 1302.c

📁 单片机最小系统原理图
💻 C
字号:
/***********************************************************
 文件名称:电子数码万年历
 作    者:
 版    本:0.1
 说    明:共有两个功能,时间的调整,1个闹钟
 修改记录:2005.2.28
***********************************************************/
//此程式是从以前的万年历上移植过来的,可以用里面的一些模块函数
#include<regx51.h>

#define uchar unsigned char
sbit RSTB=P3^7;
sbit IO=P3^6;
sbit SCLK=P3^5;
sbit k1=P1^3;              //设定
sbit k2=P1^2;              //加1
sbit k3=P1^1;      		   //减1
sbit k4=P1^0;              //闹钟设定
sbit k5=P1^4;              //闹钟开/关
sbit clock_switch=P2^6;    //闹钟开关批示
sbit clock_bell=P2^7;      //闹钟定时时间到指示()闹铃开/关
uchar flag;                //定义闪动标志位
uchar bit_count;           //闪动位
uchar clock_flag;          //闹钟开/关标志位

/***********************************/
uchar code display_data[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0x0F8,0x80,0x90,0xFF};
uchar display_seg[15]={2,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uchar data_seg[8]={0x40,0x59,0x23,0x12,0x03,0x1,0x06,0};/*初始化数据年月日数据
                                                      2006年星期13月23日23点55分*/
uchar clock_seg[4];        //闹钟数据REM                                                                                          
   
/***************Display pragma*************/
void dealy(void)           //显示延时
 {
  uchar i;
  for(i=0;i<150;i++);
 
 }


void display(void)        //显示程序
 {
  uchar j,*p;

  for(j=0;j<15;j++) 
   {
    P2=P2|j;
    
    p=display_data;
    if(flag==0xff&&((bit_count-1)==j)) P0=0XFF;
    else {p=p+display_seg[j];P0=*p;}
    
    dealy();
    P0=0XFF;
    P2&=0Xf0;
   }
   
 }


/************************************************/
void reset_3w(void)        //复位
 {
  SCLK=0;
  RSTB=0;
  RSTB=1;
 }

void wbyte_3w(uchar number)//写一个字节
 {
  uchar i;
  for(i=0;i<8;i++)
   { 
    IO=0;
    if(number&0x01) IO=1;
      else IO=0;
    SCLK=0;
    SCLK=1;
    number>>=1;
   }
 }

uchar rbyte_3w()            //读一个字节
 {
  uchar i,k;
  uchar tmpbyte;
  k=0x01;
  IO=1;
  for(i=0;i<8;i++)
    {
     SCLK=1;
     SCLK=0;
     if(IO==1) tmpbyte|=k;
      else tmpbyte&=(~k);
     k<<=1;
     
    }
   return tmpbyte;
 }



 
void write_1302(void)
 {
  uchar i,*p;
  p=data_seg;
  reset_3w();
  wbyte_3w(0x8e);            //写保护器开
  wbyte_3w(0);   
  reset_3w();
  wbyte_3w(0xbe);            //以多字节突发方试写取时钟数据
  for(i=0;i<8;i++)           //秒,分,时,日期,月,星期,年,保护控制寄存器关
   { 
    wbyte_3w(*p);
    p++;
   }
 }

void read_1302(void)
 {
  uchar sec,min,hrs,dte,mon,day,yr;
  reset_3w();
  wbyte_3w(0xbf);    //以多官节突发方试读取时钟数据
  sec=rbyte_3w();    /*秒   */
  min=rbyte_3w();    /*分   */
  hrs=rbyte_3w();    /*时   */
  dte=rbyte_3w();    /*日期 */
  mon=rbyte_3w();    /*月   */
  day=rbyte_3w();    /*星期 */
  yr=rbyte_3w();     /*年   */
  reset_3w();



/*********十六进制转BCD码子程序********/
  display_seg[14]=sec%16;
  display_seg[13]=sec/16;
  display_seg[12]=min%16;
  display_seg[11]=min/16;
  display_seg[10]=hrs%16;
  display_seg[9]=hrs/16;
  display_seg[7]=dte%16;
  display_seg[6]=dte/16;
  display_seg[5]=mon%16;
  display_seg[4]=mon/16;
  display_seg[8]=day;
  display_seg[3]=yr%16;
  display_seg[2]=yr/16;
  
  
 }

void t0(void) interrupt 1 using 0    //定时器T0,闪动定时中断
 {
  static uchar i=0;
  TH0=0x3c;                          //定时100MS中断一次
  TL0=0xb0;                          //重装计数值
  i++;                            
  if(i==4) {flag=~flag;i=0;}
 } 

void clock_write(void)
 {
   display_seg[9]=clock_seg[0];
   display_seg[10]=clock_seg[1];
   display_seg[11]=clock_seg[2];
   display_seg[12]=clock_seg[3];
 }
   
void clock_save(void)                 //闹钟数据保存
 { 
   clock_seg[0]=display_seg[9];
   clock_seg[1]=display_seg[10];
   clock_seg[2]=display_seg[11];
   clock_seg[3]=display_seg[12];
  
 }

void clock_compare(void)
 { 
    if(clock_seg[2]==display_seg[11]&&clock_seg[3]==display_seg[12])
    { 
     if(clock_seg[1]==display_seg[10]) 
      {
       if(clock_seg[0]==display_seg[9])
        clock_bell=0;               //时间到闹铃开
      }
    }
    else clock_bell=1;                //时间没到闹铃关
    if(clock_flag==0) clock_bell=1;   //用闹钟开/关键控制闹铃的工作时间
 }

void complex_data(void)
 {
   data_seg[0]=display_seg[13]*16+display_seg[14];
   data_seg[1]=display_seg[11]*16+display_seg[12];
   data_seg[2]=display_seg[9]*16+display_seg[10];
   data_seg[3]=display_seg[6]*16+display_seg[7];
   data_seg[4]=display_seg[4]*16+display_seg[5];
   data_seg[5]=display_seg[8];
   data_seg[6]=display_seg[2]*16+display_seg[3];   
 }

void key(void)
 {  
   
   if(k1==0)
    {
     display();                       //延时去抖动
     if(k1==0)
      {
       TR0=1;                         //启动定时器
       bit_count++;
       while(k1==0) display();        //等键释放
       while(1) 
        { 
         

         if(k1==0) /*设定/移位*/          
          {
           display();                 //延时去抖动
           if(k1==0)
            {
             bit_count++;
             while(k1==0) display(); 
            }
          }

         
         if(k2==0)/*调整(+)*/
          {
           display();
           if(k2==0)
            {
             while(k2==0) display(); 
             display_seg[bit_count-1]=display_seg[bit_count-1]+1;
            /*实际数据调整位=位实际位闪烁位-1*/
/****************************月份***********************************/
             if(bit_count-1==4)      //月十位判别
              {
                if(display_seg[bit_count-1]==2) display_seg[bit_count-1]=0;
              }
             if(bit_count-1==5&&display_seg[4]==1)      //月个位判别
              { if(display_seg[bit_count-1]==3) display_seg[bit_count-1]=0;}
/****************************日期***********************************/             
             if(bit_count-1==6) //日期十位判别
              {
               if((display_seg[4]+display_seg[5])==2) 
                 if(display_seg[bit_count-1]==3) display_seg[bit_count-1]=0;
               if(display_seg[bit_count-1]==4) display_seg[bit_count-1]=0;
              }
/****************************星周***********************************/  
             if(bit_count-1==8) if(display_seg[bit_count-1]==8) display_seg[bit_count-1]=1;
/****************************时分秒***********************************/  
             if(bit_count-1==9) if(display_seg[bit_count-1]==3) display_seg[bit_count-1]=0;//时十位
             if(bit_count-1==10)//时个位
               {
                if(display_seg[9]==2) if(display_seg[bit_count-1]==4) display_seg[bit_count-1]=0;
                  else if(display_seg[bit_count-1]==10) display_seg[bit_count-1]=0;
               }
             if(bit_count-1==11||bit_count-1==13)//分十位/秒十位
                if(display_seg[bit_count-1]==6) display_seg[bit_count-1]=0;
    /*********************************************************************/
             if(display_seg[bit_count-1]==10) display_seg[bit_count-1]=0;
            }
          }

         if(k3==0)/*调整(-)*/
          {
           display();
           if(k3==0)
            {
             while(k3==0) display(); 
             display_seg[bit_count-1]=display_seg[bit_count-1]-1;
             if(display_seg[bit_count-1]==0xff) display_seg[bit_count-1]=0;
             if(bit_count-1==8) if(display_seg[bit_count-1]==0) display_seg[bit_count-1]=1;
            }
          }


         if(bit_count==16) 
          {  
            TR0=0;
            bit_count=0;
            complex_data();
            write_1302();
            break ;
          } 
         display();
         
        }
      }
    }
  if(k4==0)/*闹钟设定键*/     
   {
    display();
    if(k4==0)
     {
      while(k4==0) display();          //等键释放
      TR0=1;                           //启动定时器
      bit_count=10;
      clock_write();                   //显示闹钟时间(将闹钟数据写入显示缓冲区)
      while(1)
       {
         display();
         if(k4==0) /*设定/移位*/          
          {
           display();                  //延时去抖动
           if(k4==0)
            {
             bit_count++;
             while(k4==0) display();   //等键释放
            }
          }

         if(k2==0)/*调整(+)*/
          {
           display();
           if(k2==0);
            {
             while(k2==0) display(); //等键释放
             display_seg[bit_count-1]=display_seg[bit_count-1]+1;

/****************************时分秒***********************************/  
             if(bit_count-1==9) if(display_seg[bit_count-1]==3) display_seg[bit_count-1]=0;//时十位
             if(bit_count-1==10)//时个位
               {
                if(display_seg[9]==2) if(display_seg[bit_count-1]==4) display_seg[bit_count-1]=0;//
                  else if(display_seg[bit_count-1]==10) display_seg[bit_count-1]=0;
               }
             if(bit_count-1==11||bit_count-1==13)//分十位/秒十位
                if(display_seg[bit_count-1]==6) display_seg[bit_count-1]=0;
    /*********************************************************************/
             if(display_seg[bit_count-1]==10) display_seg[bit_count-1]=0;
            }
          }

         if(k3==0)/*调整(-)*/
          {
           display();
           if(k3==0);
            {
             while(k3==0) display(); //等键释放
             display_seg[bit_count-1]=display_seg[bit_count-1]-1;
             if(display_seg[bit_count-1]==0xff) display_seg[bit_count-1]=0;
             
            }
          }


         if(bit_count==14) 
          {  
            TR0=0;
            bit_count=0;
            clock_save();
            break ;
          } 
       }
     }
   }

    if(k5==0) /*闹钟开关*/          
          {
           display();                   
           if(k5==0)
            {
             clock_flag=~clock_flag;     //置标志位
             clock_switch=~clock_switch;
             while(k5==0) display();    
            }
          }



 }
/***************************************/
void main(void)
 {
  TMOD=0x01;                 //定时器初始化
  TH0=0x3c;                  //定时100MS中断一次
  TL0=0xb0; 
  //TR0=1;     
  ET0=1;                     //开定时器中断
  EA=1;                      //开总中断

  clock_flag=0;              //闹钟功能开
  clock_switch=1;            //闹钟控制指示关
  clock_bell=1;              //闹铃关

  write_1302();
  
  while(1)
  {
   read_1302();
   display();
   key();
   clock_compare();
  }
 } 

⌨️ 快捷键说明

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