求一个AT89S51单片机电子时钟程序!急急急.......!

2024-12-29 18:35:01
推荐回答(3个)
回答1:

  #include
  #include
  #include
  #include

  typedef unsigned char uchar;

  uchar g8563_Store[4]; /*时间交换区,全局变量声明*/
  uchar code c8563_Store[4]={0x50,0x59,0x07,0x01}; /*写入时间初值:星期一 07:59:40*/

  sbit CS=P1^4;
  sbit CLK=P1^7;
  sbit DIO=P1^6;
  sbit KEY=P3^2;

  sbit SDA=P1^1; // pcf8563时钟
  sbit SCL=P1^0; // pcf8563时钟

  bdata uchar com_data;
  sbit mos_bit=com_data^7;
  sbit low_bit=com_data^0;

  void delay_50us()
  {
  uchar i;
  for (i=0; i<6; i++){;}
  }

  void delay_8us()
  {
  uchar i;
  for (i=0; i<1; i++){;}
  }
  void delay_50ms()
  {
  uchar i,j;
  for(j=0;j<50;j++)
  for(i=0;i<125;i++){;}
  }
  void send(uchar sebuf)
  {
  uchar i;
  com_data=sebuf;
  CLK=0;
  CS=0;
  delay_50us();
  for(i=0;i<8;i++)
  {
  delay_8us();
  DIO=mos_bit;
  CLK=1;
  delay_8us();
  com_data=com_data<<1;
  CLK=0;
  }
  DIO=0;
  }
  uchar receive(void)
  {
  uchar i,rebuf;
  CLK=1;
  delay_50us();
  for(i=0;i<8;i++)
  {
  com_data=com_data<<1;
  low_bit=DIO;
  CLK=1;
  delay_8us();
  CLK=0;
  delay_8us();
  }
  rebuf=com_data;
  DIO =1;
  CS=1;
  return rebuf;
  }
  void reset(void)
  {
  DIO=1;
  delay_50ms();
  send(0xa4);
  CS=1;
  }
  /* 7289显示程序 */
  /* addr为显示位置 范围0~7 */
  /* dat为现实内容 */
  void display(uchar addr,uchar dat)
  {
  if(addr<0 || addr >7)
  return;
  send(0xc8 + addr);
  delay_50us();
  send(dat);
  CS=1;
  }
  /* 发送双字节命令 */
  void sendcommand(uchar addr,uchar dat)
  {
  send(addr);
  delay_50us();
  send(dat);
  CS=1;
  }
  /********************************************
  内部函数,延时1
  ********************************************/
  void Delay()
  {
  // {P10=1;_nop_();P10=0;}
  _nop_();
  _nop_(); /*根据晶振频率制定延时时间*/
  }
  /********************************************
  内部函数,I2C开始
  ********************************************/
  void Start()
  {
  EA=0;
  SDA=1;
  SCL=1;
  Delay();
  SDA=0;
  Delay();
  SCL=0;
  }
  /********************************************
  内部函数,I2C结束
  ********************************************/
  void Stop()
  {
  SDA=0;
  SCL=0;
  Delay();
  SCL=1;
  Delay();
  SDA=1;
  Delay();
  EA=1;
  }
  /********************************************
  内部函数,输出ACK ,每个字节传输完成,输出ack=0,结束读书据,ack=1;
  ********************************************/
  void WriteACK(uchar ack)
  {
  SDA=ack;
  Delay();
  SCL=1;
  Delay();
  SCL=0;
  }
  /********************************************
  内部函数,等待ACK
  ********************************************/
  void WaitACK()
  {
  uchar errtime=20;
  SDA=1;
  Delay(); /*读ACK*/
  SCL=1;
  Delay();
  while(SDA)
  { errtime--; }
  SCL=0;
  Delay();

  }
  /********************************************
  内部函数.输出数据字节
  入口:B=数据
  ********************************************/
  void writebyte(uchar wdata)
  {
  uchar i;
  for(i=0;i<8;i++)
  {
  if(wdata&0x80) SDA=1;
  else SDA=0;
  wdata<<=1;
  SCL=1;
  Delay();
  SCL=0;
  }
  WaitACK(); //I2C器件或通讯出错,将会退出I2C通讯
  }
  /********************************************
  内部函数.输入数据
  出口:B
  ********************************************/
  uchar Readbyte()
  {
  uchar i,bytedata;
  SDA=1;
  for(i=0;i<8;i++)
  {
  SCL=1;
  bytedata<<=1;
  bytedata|=SDA;
  SCL=0;
  Delay();
  }
  return(bytedata);
  }
  /********************************************
  输出数据->pcf8563
  ********************************************/
  void writeData(uchar address,uchar mdata)
  {
  Start();
  writebyte(0xa2); /*写命令*/
  writebyte(address); /*写地址*/
  writebyte(mdata); /*写数据*/
  Stop();
  }
  /********************************************
  输入数据<-pcf8563
  ********************************************/
  uchar ReadData(uchar address) /*单字节*/
  {
  uchar rdata;
  Start();
  writebyte(0xa2); /*写命令*/
  writebyte(address); /*写地址*/
  Start();
  writebyte(0xa3); /*读命令*/
  rdata=Readbyte();
  WriteACK(1);
  Stop();
  return(rdata);
  }
  void ReadData1(uchar address,uchar count,uchar * buff) /*多字节*/
  {
  uchar i;
  Start();
  writebyte(0xa2); /*写命令*/
  writebyte(address); /*写地址*/
  Start();
  writebyte(0xa3); /*读命令*/
  for(i=0;i  {
  buff[i]=Readbyte();
  if(i  }
  WriteACK(1);
  Stop();
  }
  /********************************************
  内部函数,读入时间到内部缓冲区
  ********************************************/
  void P8563_Read()
  {
  uchar time[7];
  ReadData1(0x02,0x07,time);
  g8563_Store[0]=time[0]&0x7f; /*秒*/
  g8563_Store[1]=time[1]&0x7f; /*分*/
  g8563_Store[2]=time[2]&0x3f; /*小时*/
  g8563_Store[3]=time[4]&0x07; /*星期*/
  }
  /********************************************
  读入时间到内部缓冲区----外部调用
  ********************************************/
  void P8563_gettime()
  {
  P8563_Read();
  if(g8563_Store[0]==0)
  P8563_Read(); /*如果为秒=0,为防止时间变化,再读一次*/
  }
  /********************************************
  写时间修改值
  ********************************************/
  void P8563_settime()
  {
  uchar i;
  for(i=2;i<=4;i++) { writeData(i,g8563_Store[i-2]); }
  writeData(6,g8563_Store[3]);
  }
  /********************************************
  P8563的初始化-----外部调用
  ********************************************/
  void P8563_init()
  {
  uchar i;

  for(i=0;i<=3;i++) g8563_Store[i]=c8563_Store[i]; /*初始化时间*/
  P8563_settime();
  writeData(0x0,0x00);
  writeData(0xa,0x8); /*8:00报警*/
  writeData(0x1,0x12); /*报警有效*/
  writeData(0xd,0xf0);

  }

  main()
  {
  reset();
  P8563_init();
  while(1)
  {
  P8563_Read();
  display(0,g8563_Store[2] >> 4);
  display(1,g8563_Store[2] & 0x0f);
  sendcommand(0x82,0x0a);
  display(3,g8563_Store[1] >> 4);
  display(4,g8563_Store[1] & 0x0f);
  sendcommand(0x85,0x0a);
  display(6,g8563_Store[0] >> 4);
  display(7,g8563_Store[0] & 0x0f);
  }
  }

回答2:

你很懒,我也是

回答3:

sodisni
自己写撒
我和楼上的一样懒