基于ds1302的电子日历系统

发布时间:2023-06-06  

  基于ds1302的电子日历系统在硬件选择上主要采用AT89S51作为主控制系统;DS1302提供时钟;DS18B20作为数字式温度传感器;LCD1602液晶屏作为显示。

基于ds1302的电子日历系统

  AT89C51单片机

基于ds1302的电子日历系统

  单片机最小系统

  AT89C51单片机采用Flash ROM,内部具有4KB ROM存储空间,相对于本设计而言程序空间完全够用。能于3V的超低压工作,而且与MCS-51系列单片机完全兼容,而且运用于电路设计中时具备ISP在线编程技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,避免芯片的多次拔插对芯片造成的损坏。

  ds1302

基于ds1302的电子日历系统

  DS1302与单片机的连接

  DS130是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后背电源双电源引脚,同时提供了对后背电源进行涓细电流充电的能力。主要特点是采用串行数据传输,可为掉电保护电源提供可编程的充电功能,并且可以关闭充电功能。采用普通32.768kHz晶振。而且DS1302有使用寿命长,误差小等优点。

  1602LCM点阵液晶显示屏

基于ds1302的电子日历系统

  LCM1602与单片机的连接

  LCD液晶显示屏,液晶显示屏的显示功能强大,可显示大量文字,图形,显示多样,清晰可见,对于电子万年历而言,一个1602的液晶屏即可,价格也还能接受,需要的接口线较多,但会给调试带来诸多方便,

  数字式温度传感器DS18B20

基于ds1302的电子日历系统

  DS18B20管脚连线

  此类传感器为数字式传感器而且仅需要一条数据线进行数据传输,易于与单片机连接,可以避免A/D模数转换模块,降低硬件成本,简化系统电路。另外,数字式温度传感器还具有测量精度高、测量范围广等优点。

DS1302原理及说明

  (1) 时钟芯片DS1302的工作原理

  DS1302在每次进行读、写程序前都必须初始化,先把SCLK端置 “0”,接着把RST端置“1”,最后才给予SCLK脉冲;读/写时序如下图7所示。图6为DS1302的控制字,此控制字的位7必须置1,若为0则不能把对DS1302进行读写数据。对于位6,若对程序进行读/写时RAM=1,对时间进行读/写时,CK=0。位1至位5指操作单元的地址。位0是读/写操作位,进行读操作时,该位为1;该位为0则表示进行的是写操作。控制字节总是从最低位开始输入/输出的。表2为DS1302的日历、时间寄存器内容:“CH”是时钟暂停标志位,当该位为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位为0时,时钟开始运行。“WP”是写保护位,在任何的对时钟和RAM的写操作之前,WP必须为0。当“WP”为1时,写保护位防止对任一寄存器的写操作。

  (2) DS1302的控制字

  DS1302的控制字如图6所示。控制字节的高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。

基于ds1302的电子日历系统

  DS1302的控制字

  (3) 数据输入输出

  在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。

基于ds1302的电子日历系统

  DS1302读与写的时序图

  (4) DS1302的寄存器

  DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式,其日历、时间寄存器及其控制字见图。

基于ds1302的电子日历系统

  DS1302的日历、时间寄存器

  此外,DS1302 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。 DS1302与RAM相关的寄存器分为两类:一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。

系统设计

  主程序流程图

基于ds1302的电子日历系统

  时间调整程序流程图

基于ds1302的电子日历系统

主程序:

  #include《reg51.h》

  #define uint unsigned int

  #define uchar unsigned char

  uchar a,miao,shi,fen,ri,yue,nian,week,key1n,temp;

  #define yh 0x80

  #define er 0x80+0x40

  sbit DQ = P3^5;

  sbit RS=P1^7;

  sbit E=P2^4;

  sbit RW=P1^6;

  sbit IO=P1^5;

  sbit SCLK=P1^4;

  sbit RST=P2^2;

  sbit ACC0=ACC^0;

  sbit ACC7=ACC^7;

  sbit key1=P1^0;

  sbit key2=P1^2;

  sbit key3=P1^3;

  uchar code tab1[]={“20 - - ”};

  uchar code tab2[]={“ : : ”};

  void delay(uint xms)

  {

  uint x,y;

  for(x=xms;x》0;x--) ;

  for(y=110;y》0;y--);

  }

  //液晶写入指令函数

  write_1602com(uchar com)

  {

  RS=0;

  RW=0;

  P0=com;

  delay(1);

  E=1;

  delay(1);

  E=0;

  }

  //液晶写入数据函数

  write_1602dat(uchar dat)

  {

  RS=1;

  RW=0;

  P0=dat;

  delay(1);

  E=1;

  delay(1);

  E=0;

  }

  //液晶初始化函数

  lcd_init()

  {

  write_1602com(0x38);

  write_1602com(0x0c);

  write_1602com(0x06);

  write_1602com(0x01);

  write_1602com(yh+1);

  for(a=0;a《14;a++)

  {

  write_1602dat(tab1[a]);

  delay(3);

  }

  write_1602com(er+2);

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

  {

  write_1602dat(tab2[a]);

  delay(3);

  }

  }

  /***************DS1302有关子函数********************/

  //写一个字节

  void write_byte(uchar dat)

  {

  ACC=dat;

  RST=1;

  for(a=8;a》0;a--)

  {

  IO=ACC0;

  SCLK=0;

  SCLK=1;

  ACC=ACC》》1;

  }

  }

  //读一个字节

  uchar read_byte()

  {

  RST=1;

  for(a=8;a》0;a--)

  {

  ACC7=IO;

  SCLK=1;

  SCLK=0;

  ACC=ACC》》1;

  }

  return (ACC);

  }

  //向1302芯片写函数,指定写入地址,数据

  void write_1302(uchar add,uchar dat)

  {

  RST=0;

  SCLK=0;

  RST=1;

  write_byte(add);

  write_byte(dat);

  SCLK=1;

  RST=0;

  }

  //从1302读数据函数,指定读取数据来源地址

  uchar read_1302(uchar add)

  {

  uchar temp;

  RST=0;

  SCLK=0;

  RST=1;

  write_byte(add);

  temp=read_byte(); SCLK=1;

  RST=0; return(temp);

  }

  //BCD码转十进制函数,输入BCD,返回十进制

  uchar BCD_Decimal(uchar bcd)

  {

  uchar Decimal;

  Decimal=bcd》》4;

  return(Decimal=Decimal*10+(bcd&=0x0F));

  }

  //1302芯片初始化子函数(2012-06-26,00:00:00,week2)

  void ds1302_init()

  {

  RST=0;

  SCLK=0;

  write_1302(0x8e,0x00);

  write_1302(0x80,0x00);

  write_1302(0x82,0x00);

  write_1302(0x84,0x00);

  write_1302(0x8a,0x02);

  write_1302(0x86,0x26);

  write_1302(0x88,0x06);

  write_1302(0x8c,0x12);

  write_1302(0x8e,0x80);

  }

  //时分秒显示子函数

  void write_sfm(uchar add,uchar dat)

  {

  uchar gw,sw;

  gw=dat%10;

  sw=dat/10;

  write_1602com(er+add);

  write_1602dat(0x30+sw);

  write_1602dat(0x30+gw);

  }

  //年月日显示子函数

  void write_nyr(uchar add,uchar dat)

  {

  uchar gw,sw;

  gw=dat%10;

  sw=dat/10;

  write_1602com(yh+add);

  write_1602dat(0x30+sw);

  write_1602dat(0x30+gw);

  }

  //写星期函数

  void write_week(uchar week)

  {

  write_1602com(yh+0x0c);

  switch(week

  {

  case 1:

  write_1602dat(‘M’);

  write_1602dat(‘O’);

  write_1602dat(‘N’);

  break;

  case 2:

  write_1602dat(‘T’);

  write_1602dat(‘U’);

  write_1602dat(‘E’);

  break;

  case 3:

  write_1602dat(‘W’);

  write_1602dat(‘E’);

  write_1602dat(‘D’);

  break;

  case 4:

  write_1602dat(‘T’

  write_1602dat(‘H’);

  write_1602dat(‘U’);

  break;

  case 5:

  write_1602dat(‘F’);

  write_1602dat(‘R’);

  write_1602dat(‘I’);

  break;

  case 6:

  write_1602dat(‘S’);

  write_1602dat(‘T’);

  write_1602dat(‘A’);

  break;

  case 7:

  write_1602dat(‘S’);

  write_1602dat(‘U’);

  write_1602dat(‘N’);

  break;

  }

  }

  //*键盘扫描有关函数 void keyscan()

  {

  if(key1==0)

  {

  delay(9);

  if(key1==0)

  {

  delay(20);

  while(!key1);

  key1n++;

  if(key1n==9) key1n=1;

  switch(key1n)

  {

  case 1:

  TR0=0;

  write_1602com(er+0x09);

  write_1602com(0x0f);

  temp=(miao)/10*16+(miao)%10;

  write_1302(0x8e,0x00);

  write_1302(0x80,0x80|temp);

  write_1302(0x8e,0x80);

  break; case 2: write_1602com(er+6);

  break;

  case 3:

  write_1602com(er+3);

  break;

  case 4:

  write_1602com(yh+0x0e);

  break;

  case 5:

  write_1602com(yh+0x0a);

  break;

  case 6:

  write_1602com(yh+0x07);

  break;

  case 7:

  write_1602com(yh+0x04);

  break;

  case 8:

  write_1602com(0x0c);

  TR0=1;

  temp=(miao)/10*16+(miao)%10;

  write_1302(0x8e,0x00);

  write_1302(0x80,0x00|temp);

  write_1302(0x8e,0x80);

  break;

  }

  }

  }

  if(key1n!=0)

  {

  if(key2==0)

  {

  delay(10);

  if(key2==0)

  {

  delay(20);

  while(!key2);

  switch(key1n) {

  case 1:miao++;

  if(miao==60)

  miao=0;

  write_sfm(0x08,miao);

  temp=(miao)/10*16+(miao)%10;

  write_1302(0x8e,0x00);

  write_1302(0x80,temp);

  write_1302(0x8e,0x80);

  write_1602com(er+0x09);

  break;

  case 2:fen++;

  if(fen==60)

  fen=0;

  write_sfm(0x05,fen);

  temp=(fen)/10*16+(fen)%10;

  write_1302(0x8e,0x00);

  write_1302(0x82,temp);

  write_1302(0x8e,0x80);

  write_1602com(er+6);

  break; case 3:shi++;

  if(shi==24)

  shi=0;

  write_sfm(2,shi);

  temp=(shi)/10*16+(shi)%10;

  write_1302(0x8e,0x00);

  write_1302(0x84,temp);

  write_1302(0x8e,0x80);

  write_1602com(er+3);

  break; case 4:week++;

  if(week==8) week=1;

  write_1602com(yh+0x0C);

  write_week(week);

  temp=(week)/10*16+(week)%10;

  write_1302(0x8e,0x00);

  write_1302(0x8a,temp);

  write_1302(0x8e,0x80);

  write_1602com(yh+0x0e);

  break; case 5:ri++;

  if(ri==32)

  ri=1;

  write_nyr(9,ri);

  temp=(ri)/10*16+(ri)%10;

  write_1302(0x8e,0x00);

  write_1302(0x86,temp);

  write_1302(0x8e,0x80);

  write_1602com(yh+10);

  break;

  case 6:yue++;

  if(yue==13)

  yue=1;

  write_nyr(6,yue);

  temp=(yue)/10*16+(yue)%10;

  write_1302(0x8e,0x00);

  write_1302(0x88,temp);

  write_1302(0x8e,0x80);

  write_1602com(yh+7);

  break;

  case 7:nian++;

  if(nian==100) nian=0;

  write_nyr(3,nian);

  temp=(nian)/10*16+(nian)%10;

  write_1302(0x8e,0x00);

  write_1302(0x8c,temp);

  write_1302(0x8e,0x80);

  write_1602com(yh+4);

  break;

  }

  }

  }

  if(key3==0)

  {

  delay(10);

  if(key3==0)

  {

  delay(20);

  while(!key3);

  switch(key1n)

  {

  case 1:miao--;

  if(miao==-1)

  miao=59;

  write_sfm(0x08,miao);

  temp=(miao)/10*16+(miao)%10;

  write_1302(0x8e,0x00);

  write_1302(0x80,temp);

  write_1302(0x8e,0x80);

  write_1602com(er+0x09);

  break; case 2:fen--;

  if(fen==-1)

  fen=59;

  write_sfm(5,fen);

  temp=(fen)/10*16+(fen)%10;

  write_1302(0x8e,0x00);

  write_1302(0x82,temp);

  write_1302(0x8e,0x80);

  write_1602com(er+6);

  break;

  case 3:shi--;

  if(shi==-1)

  shi=23;

  write_sfm(2,shi);

  temp=(shi)/10*16+(shi)%10;

  write_1302(0x8e,0x00);

  write_1302(0x84,temp);

  write_1302(0x8e,0x80);

  write_1602com(er+3);

  break; case 4:week--;

  if(week==0)

  week=7;

  write_1602com(yh+0x0C);

  write_week(week);

  temp=(week)/10*16+(week)%10;

  write_1302(0x8e,0x00);

  write_1302(0x8a,temp);

  write_1302(0x8e,0x80);

  write_1602com(yh+0x0e);

  break; case 5:ri--;

  if(ri==0)

  ri=31;

  write_nyr(9,ri);

  temp=(ri)/10*16+(ri)%10;

  write_1302(0x8e,0x00);

  write_1302(0x86,temp);

  write_1302(0x8e,0x80);

  write_1602com(yh+10);

  break; case 6:yue--;

  if(yue==0)

  yue=12;

  write_nyr(6,yue);

  temp=(yue)/10*16+(yue)%10;

  write_1302(0x8e,0x00);

  write_1302(0x88,temp);

  write_1302(0x8e,0x80);

  write_1602com(yh+7);

  break;

  case 7:nian--;

  if(nian==-1) nian=99;

  write_nyr(3,nian);

  temp=(nian)/10*16+(nian)%10;

  write_1302(0x8e,0x00);

  write_1302(0x8c,temp);

  write_1302(0x8e,0x80);

  write_1602com(yh+4);

  break;

  }

  }

  }

  }

  }

  //定时器、计数器设置函数

  void init()

  {

  TMOD=0x11;

  TH0=0;

  TL0=0;

  EA=1;

  ET0=1;

  TR0=1;

  }

  /******************************* 延时函数 ********************************

  * 功能:在11.059MHz的晶振条件下调用本函数需要24μs ,然后每次计数需16μs

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

  void DS18_delay(int useconds)

  {

  int s;

  for (s=0; s《useconds;s++);

  }

  /******************************* 复位函数 *******************************

  * 功能:完成单总线的复位操作

  * 复位时间为480μs,因此延时时间为(480-24)/16 = 28.5,取29μs。

  * 经过70μs之后检测存在脉冲,因此延时时间为(70-24)/16 = 2.875,取3μs。

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

  unsigned char ow_reset(void)

  {

  unsigned char presence;

  DQ = 0;

  DS18_delay(29);

  DQ = 1;

  DS18_delay(3);

  presence = DQ;

  DS18_delay(25);

  return(presence);

  }

  /****************************** 位写入函数 *******************************

  * 功能:向单总线写入1位值:bitval

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

  void write_bit(char bitval) { DQ = 0;

  if(bitval==1) DQ =1;

  DS18_delay(5);

  DQ = 1;

  }

  /**************************** 字节写入函数 *******************************

  * 功能:向单总线写入一个字节值:val

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

  void ds18write_byte(char val)

  {

  unsigned char i;

  unsigned char temp;

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

  temp = val》》i;

  temp &= 0x01;

  write_bit(temp);

  }

  DS18_delay(5);

  }

  /**************************** 位读取函数 ********************************

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

相关文章

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

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

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

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

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

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

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