基于52单片机与ds1302时钟芯片的电子闹钟C程序

发布时间:2023-05-19  

  52单片机是STC公司生产的一种低功耗、高性能CMOS8位微控制器,具有8K字节系统可编程Flash存储器。STC89C52使用经典的MCS-51内核,但是做了很多的改进使得芯片具有传统51单片机不具备的功能。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。


  52单片机结合可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等功能的dDS1302时钟芯片做出的电子闹钟会有什么火花呢?奉上基于52单片机与ds1302时钟芯片的电子闹钟C程序,让大家亲身体验。

  

  52单片机与ds1302时钟芯片的电子闹钟C程序

  #include《reg52.h》

  #define w_second 0x80 //秒写入地址

  #define w_minute 0x82 //分写入地址

  #define w_hour 0x84 //时写入地址

  #define w_day 0x86 //日写入地址

  #define w_month 0x88 //月写入地址

  #define w_week 0x8a //星期写入地址

  #define w_year 0x8c //年写入地址

  #define r_second 0x81 //秒读出地址

  #define r_minute 0x83 //分读出地址

  #define r_hour 0x85 //时读出地址

  #define r_day 0x87 //日读出地址

  #define r_month 0x89 //月读出地址

  #define r_week 0x8b //星期读出地址

  #define r_year 0x8d //年读出地址

  #define w_wp 0x8e //指令写允许端地址

  #define uchar unsigned char

  uchar table[]=

  {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//7段数码管编码

  uchar second; // 秒指针

  uchar minute; // 分指针

  uchar hour; // 时指针

  uchar day; // 日指针

  uchar month; // 月指针

  uchar week; // 星期指针

  uchar year; // 年指针

  uchar cc;

  uchar h_clock,m_clock,h,m;

  sbit change=P1^0; // 选择按钮

  sbit ok=P1^2; // 确定更改按钮

  sbit crrect=P1^1; // 更改按钮

  sbit look=P1^3; // 时间和年月日查看切换按钮

  sbit clock=P1^4; //闹钟设定

  sbit ce=P3^2; // ds1302 片选端

  sbit sclk=P3^0; // ds1302 时控端

  sbit io=P3^1; // ds1302 串口端

  sbit clock_beef=P3^7; //蜂鸣器控制端

  sbit clock_button=P1^5; //闹钟启停按钮

  void write_ds1302(uchar addr,uchar dat) //写程序

  { uchar i,temp;

  ce=0;sclk=0;ce=1;

  for(i=0;i《8;i++)

  { sclk=0;

  temp=addr;

  io=(bit)(temp&0x01); //每一次只传送一位数据

  addr》》=1;

  sclk=1;

  }

  for(i=0;i《8;i++)

  { sclk=0;

  temp=dat;

  io=(bit)(temp&0x01);

  dat》》=1;

  sclk=1;

  }

  ce=0;

  }

  uchar read_ds1302(uchar addr) //读程序

  { uchar i,temp;

  ce=0;sclk=0;ce=1;

  for(i=0;i《8;i++)

  { sclk=0;

  temp=addr;

  io=(bit)(temp&0x01);

  addr》》=1;

  sclk=1;

  }

  for(i=0;i《8;i++)

  { temp》》=1;

  sclk=0;

  if(io) temp=temp|0x80;

  else temp=temp&0x7f;

  sclk=1;

  }

  return temp;

  }

  void set_ds1302() //初始化ds1302

  { write_ds1302(w_wp,0x00);

  write_ds1302(w_second,second);

  write_ds1302(w_minute,minute);

  write_ds1302(w_hour,hour);

  write_ds1302(w_day,day);

  write_ds1302(w_month,month);

  write_ds1302(w_week,week);

  write_ds1302(w_year,year);

  write_ds1302(w_wp,0x80);

  }

  void view1() //时间显示

  { uchar i;

  P0=table[second]; //秒显示

  P2=0x01;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[second/16];

  P2=0x02;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[minute]-0x80; //分显示,(-0x80表示dp点亮)

  P2=0x04;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[minute/16];

  P2=0x08;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[hour]-0x80;//时显示

  P2=0x10;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[hour/16];

  P2=0x20;

  for(i=0;i《=123;i++);

  P2=0;

  }

  void view2() //日期显示

  { uchar i;

  P2=0;

  P0=table[week]; //星期显示

  P2=0x01;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[week/16];

  P2=0x02;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[day]-0x80; //日显示

  P2=0x04;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[day/16];

  P2=0x08;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[month]-0x80;//月显示

  P2=0x10;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[month/16];

  P2=0x20;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[year]-0x80; //年显示

  P2=0x40;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[year/16];

  P2=0x80;

  for(i=0;i《=123;i++);

  P2=0;

  }

  void view3() //闹钟设定程序

  { uchar i;

  P0=table[m];

  P2=0x01;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[m/16];

  P2=0x02;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[h]-0x80;

  P2=0x04;

  for(i=0;i《=123;i++);

  P2=0;

  P0=table[h/16];

  P2=0x08;

  for(i=0;i《=123;i++);

  P2=0;

  }

  void beep() //蜂鸣器启动程序

  { int i;

  clock_beef=~clock_beef;

  for(i=1;i《=50;i++)

  { second=read_ds1302(r_second);

  minute=read_ds1302(r_minute);

  hour=read_ds1302(r_hour);

  view1();

  }

  }

  void display1() //读秒,分,时程序

  { second=read_ds1302(r_second);

  minute=read_ds1302(r_minute);

  hour=read_ds1302(r_hour);

  view1();

  if((h_clock==read_ds1302(r_hour)) &&

  (m_clock==read_ds1302(r_minute)) && (~clock_button)) //判断时分,且闹钟是否开启

  { while(~clock_button)

  { beep();

  }

  clock_beef=0;

  }

  }

  void display2() //读星期,日,月,年程序

  { week=read_ds1302(r_week);

  day=read_ds1302(r_day);

  month=read_ds1302(r_month);

  year=read_ds1302(r_year);

  view2();

  if((h_clock==read_ds1302(r_hour)) &&

  (m_clock==read_ds1302(r_minute)) && (~clock_button))

  { while(~clock_button)

  { beep();

  }

  clock_beef=0;

  }

  }

  void crrect_ds1302(uchar cc) //更改程序

  {

  while(~crrect);

  switch(cc)

  {

  case 1: if(read_ds1302(r_minute)==0x59)

  minute=0x00;

  else { if(read_ds1302

  (r_minute)==9) { minute=read_ds1302

  (r_minute)/16;minute=(minute+1)*16;}

  else

  minute=read_ds1302(r_minute)+1;

  }

  set_ds1302();

  break;

  case 2: if(read_ds1302(r_hour)==0x23)

  hour=0x00;

  else { if(read_ds1302(r_hour)

  《0x20)

  { if

  (read_ds1302(r_hour)==9) {hour=read_ds1302

  (r_hour)/16;hour=(hour+1)*16;}

  else hour=read_ds1302(r_hour)+1;

  }

  else

  hour=read_ds1302(r_hour)+1;

  }

  set_ds1302();

  break;

  case 3: if(read_ds1302(r_week)==0x07)

  week=0x01;

  else week=read_ds1302(r_week)+1;

  set_ds1302();

  break;

  case 4: if(read_ds1302(r_day)==0x31)

  day=0x01;

  else { if(read_ds1302

  (r_day)==9) { day=read_ds1302(r_day)/16;day=(day+1)

  *16;}

  else

  day=read_ds1302(r_day)+1;

  }

  set_ds1302();

  break;

  case 5: if(read_ds1302(r_month)==0x12)

  month=0x01;

  else { if(read_ds1302

  (r_month)==9) { month=read_ds1302

  (r_month)/16;month=(month+1)*16;}

  else

  month=read_ds1302(r_month)+1;

  }

  set_ds1302();

  break;

  case 6: if(read_ds1302(r_year)==0x99)

  year=0x00;

  else { if(read_ds1302

  (r_year)==9) { year=read_ds1302(r_year)/16;year=(year

  +1)*16;}

  else

  year=read_ds1302(r_year)+1;

  }

  set_ds1302();

  break;

  default:{;}

  }

  }

  void change_ds1302() //更改设定选择

  { uchar i;

  cc=0;

  while(ok)

  { if(cc==6) cc=0;

  cc++;

  while(change&&ok)

  { if(i==320) i=0;

  else i++;

  switch(cc)

  {

  case 1: if(i《160) minute=read_ds1302

  (r_minute);

  else {minute=0xaa; year=read_ds1302

  (r_year);}

  view1();

  break;

  case 2: if(i《160) hour=read_ds1302(r_hour);

  else {hour=0xaa; minute=read_ds1302

  (r_minute);}

  view1();

  break;

  case 3: if(i《160)

  week=read_ds1302(r_week);

  else {week=0xaa;hour=read_ds1302

  (r_hour);}

  view2();

  break;

  case 4: if(i《160) day=read_ds1302

  (r_day);

  else {day=0xaa; week=read_ds1302

  (r_week);}

  view2();

  break;

  case 5: if(i《160)

  month=read_ds1302(r_month);

  else {month=0xaa; day=read_ds1302

  (r_day);}

  view2();

  break;

  case 6: if(i《160)

  year=read_ds1302(r_year);

  else {year=0xaa; month=read_ds1302

  (r_month);}

  view2();

  break;

  default: {;}

  }

  if(~crrect) crrect_ds1302(cc);

  }

  while( ~change );

  }

  }

  void crrect_clock(uchar i) //设定定时程序

  { switch(i)

  { case 0: if(m_clock==0x59) m_clock=0x00;

  else { if(m_clock==9) {

  m_clock=m_clock/16;m_clock=(m_clock+1)*16;}

  else

  m_clock=m_clock+1;

  }

  break;

  case 1: if(h_clock==0x23)

  h_clock=0x00;

  else { if(h_clock《0x20)

  { if

  (h_clock==9) {h_clock=h_clock/16;h_clock=(h_clock+1)

  *16;}

  else h_clock=h_clock+1;

  }

  else

  h_clock=h_clock+1;

  }

  break;

  default:{;}

  }

  }

  void set_clock() //分、时设定选择程序

  { uchar i,j;

  while(ok)

  { while(clock && ok)

  { if(j==320) j=0;

  else j++;

  switch(i)

  {

  case 0: if(j《160) m=m_clock;

  else {m=0xaa; h=h_clock;}

  view3();

  break;

  case 1: if(j《160) h=h_clock;

  else {h=0xaa; m=m_clock;}

  view3();

  break;

  default:{;}

  }

  if(~crrect) {while

  (~crrect);crrect_clock(i);}

  }

  while(~clock);

  if(i==0) i++;

  else i=0;

  }

  }

  void main()

  { uchar i;

  cc=0;m_clock=0x00;h_clock=0x00;clock_beef=0;

  second=0x15;

  minute=0x58;

  hour=0x18;

  day=0x18;

  month=0x07;

  week=0x01;

  year=0x11;

  set_ds1302(); //初始化ds1302

  while(1)

  { if(~look) { i=~i;while(~look);}

  if(i==0) display1();

  if(i) display2();

  if(~change) { while(~change);change_ds1302();}

  if(~clock) { while(~clock);set_clock();}

  }

  }


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>