求用C语言编写一个单片机89C51电子时钟程序,有时,分,秒,还有电路图

2024-11-17 02:36:47
推荐回答(4个)
回答1:

#include "
#include
/******************************************************************/
sbit T_CLK=P3^5;      //DS1302引脚连接
sbit T_IO =P3^6;
sbit T_RST=P3^7;

sbit ACC0=ACC^0;           //1bit数据存储位
sbit ACC7=ACC^7;

uchar starts_time[7]={0x00,0x10,0x22,0x20,0x05,0x04,0x10};  //初始化后设置
uchar Sec;
uchar Cent;
uchar Hour;
uchar Year;
uchar Day;
uchar Week;
uchar Month;

/******************************************************************/

//根据选择调整相应项目
void Set(uchar sel,uchar sel_1)
{
  uchar address,time;
  uchar max,min;
 if(sel==1)  {address=0x84; max=23;min=0;}    //小时
 if(sel==2)  {address=0x82; max=59;min=0;}    //分钟
 if(sel==3)  {address=0x88; max=12;min=1;}    //月
 if(sel==4)  {address=0x86; max=31;min=1;}    //日
 if(sel==5)  {address=0x8a; max=7;min=1;}    //星期
  time=R1302(address+1)/16*10+R1302(address+1)%16;    //变成BCD码
  if (sel_1==1) time++;  else time--;
  if(time>max) time=min;  
  if(time          
  W1302(0x8e,0x00);
  W1302(address,time/10*16+time%10);  
  W1302(0x8e,0x80); 
}

//********DS1302读写程序***************///********************************************************************
函 数 名:RTInputByte()
功    能:实时时钟写入一字节
说    明:往DS1302写入1Byte数据 (内部函数)
入口参数:d 写入的数据
返 回 值:无 
***********************************************************************/
void RTInputByte(uchar d)
{
    uchar h;
    ACC = d;
    for(h=8; h>0; h--)
    {
        T_IO = ACC0;           /*相当于汇编中的 RRC */
        T_CLK = 1;
        T_CLK = 0;
        ACC = ACC >> 1;
    }
}
uchar RTOutputByte(void)
{
    uchar h;
    for(h=8; h>0; h--)
    {
        ACC = ACC >>1;         /*相当于汇编中的 RRC */
        ACC7 = T_IO;
        T_CLK = 1;
        T_CLK = 0;
    }
    return(ACC);
}
/***************************************************************************************************/
void W1302(uchar ucAddr, uchar ucDa)
{
    T_RST = 0;
    T_CLK = 0;
    T_RST = 1;
    RTInputByte(ucAddr);       /* 地址,命令 */
    RTInputByte(ucDa);       /* 写1Byte数据*/
    T_CLK = 1;
    T_RST = 0;
}
/********************************************************************
函 数 名:R1302()
功    能:读取DS1302某地址的数据
说    明:先写地址,后读命令/数据 (内部函数)
调    用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址
返 回 值:ucData :读取的数据
***********************************************************************/
uchar R1302(uchar ucAddr)
{
    uchar ucData;
    T_RST = 0;
    T_CLK = 0;
    T_RST = 1;
    RTInputByte(ucAddr);             /* 地址,命令 */
    ucData = RTOutputByte();         /* 读1Byte数据 */
    T_CLK = 1;
    T_RST = 0;
    return(ucData);
}

/********************************************************************
函 数 名:Set1302()
功    能:设置初始时间
说    明:先写地址,后读命令/数据(寄存器多字节方式)
调    用:W1302()
入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年
                               7Byte (BCD码)1B 1B 1B 1B 1B  1B  1B
返 回 值:无
***********************************************************************/
void Set1302(uchar *pClock)
{
    uchar h;
    uchar ucAddr = 0x80;
    W1302(0x8e,0x00);           /* 控制命令,WP=0,写操作?*/
    for(h =7; h>0; h--)
    {
        W1302(ucAddr,*pClock);  /* 秒 分 时 日 月 星期 年 */
        pClock++;
        ucAddr +=2;
    }
 W1302(0xc0,0x01);
 W1302(0XC2,0X03);   //初始自动转换显示时间为3秒。
    W1302(0x8e,0x80);           /* 控制命令,WP=1,写保护?*/

}

void Auto_Set1302(uchar *pClock)
{
    uchar h;
    uchar ucAddr = 0x80;
 if(((R1302(0x81))&0x80)==0x80)
 {
     W1302(0x8e,0x00);           /* 控制命令,WP=0,写操作?*/
     for(h =7; h>0; h--)
     {
         W1302(ucAddr,*pClock);  /* 秒 分 时 日 月 星期 年 */
         pClock++;
         ucAddr +=2;
     }
    W1302(ucNumRows_adder,0);
    W1302(ucNumRows_p_adder,0);
    W1302(DISP_TIME_adder,170);
  W1302(0xc0,0x01);
  W1302(0XC2,0X03);   //初始自动转换显示时间为3秒。
     W1302(0x8e,0x80);           /* 控制命令,WP=1,写保护?*/

 }
}
/******************读取DS1302中的时间****************/
void du1302()
{
      Sec=R1302(0x81);   //对取 秒 分 时 日 月 星期 年
   Cent=R1302(0x83);
   Hour=R1302(0x85);
   Day=R1302(0x87);
   Month=R1302(0x89);
   Week=R1302(0x8b);
   Year=R1302(0x8d);    
   //b=R1302(0xc1);
      //a=R1302(0xc3);
   //a=a/16*10+a%16;
 
}
void  write_1302Data (uchar  ucAddr,uchar  Value)
{  
 W1302(0x8e,0x00);           /* 控制命令,WP=0,写操作?*/
    W1302(ucAddr,Value);        //地址和数据
    W1302(0x8e,0x80);           /* 控制命令,WP=1,写保护?*/
}

回答2:

自己protues仿真的电子时钟,有需要发你邮箱!

回答3:

你好!显示部分是数码管还是Lcd ?私信联系我吧

    

回答4:

可以用DS1302来做