收藏 分销(赏)

电子钟(DS1302+AT89C52+1602).doc

上传人:xrp****65 文档编号:6157344 上传时间:2024-11-28 格式:DOC 页数:24 大小:227.50KB 下载积分:10 金币
下载 相关 举报
电子钟(DS1302+AT89C52+1602).doc_第1页
第1页 / 共24页
电子钟(DS1302+AT89C52+1602).doc_第2页
第2页 / 共24页


点击查看更多>>
资源描述
电子钟(DS1302+AT89C52+1602) 文章发表于:2009-08-01 09:35   修改一下此篇已发很久的文章,之前的有问题,欢迎拍砖 已下是主程序:   #include <REGX52.H> #include "LCD1602.h" #include "DS1302.h" void Delay1ms(unsigned int count) {  unsigned int i,j;  for(i=0;i<count;i++)  for(j=0;j<120;j++); } main() {  SYSTEMTIME CurrentTime;  LCD_Initial();  Initial_DS1302();  GotoXY(0,0);  Print("Date: ");  GotoXY(0,1);  Print("Time: ");  while(1)  {   DS1302_GetTime(&CurrentTime);   DateToStr(&CurrentTime);   TimeToStr(&CurrentTime);   GotoXY(6,0);   Print(CurrentTime.DateString);   GotoXY(6,1);   Print(CurrentTime.TimeString);   Delay1ms(300);  } } 2 DS1302时钟+DS18B20用LCD1602显示(系统很简单) [精华] 文章发表于:2009-07-14 14:37 先粘张效果图看看吧: 看仔细点啊  貌似很多这样的图但可不一样喔  最小系统是用AT89s52搭建的!记得回去自己用protues和Keil仿真一下,这样有利于进一步了解!故未将仿真好的代码上传,如果真的需要的话可以和我联系!lyzhangxiang.love@ 程序代码: #include <REG51.H> #include <intrins.h> //#include "LCD1602.h" //#include "DS1302.h" #define uint unsigned int #define uchar unsigned char sbit  DS1302_CLK = P1^7;              //实时时钟时钟线引脚 sbit  DS1302_IO  = P1^6;              //实时时钟数据线引脚 sbit  DS1302_RST = P1^5;              //实时时钟复位线引脚 sbit  wireless_1 = P3^0; sbit  wireless_2 = P3^1; sbit  wireless_3 = P3^2; sbit  wireless_4 = P3^3; sbit  ACC0 = ACC^0; sbit  ACC7 = ACC^7; char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year;  //秒,分,时到日,月,年位闪的计数 sbit Set = P2^0;       //模式切换键 sbit Up = P2^1;        //加法按钮 sbit Down = P2^2;      //减法按钮 sbit out = P2^3;       //立刻跳出调整模式按钮 sbit DQ = P1^0;        //温度传送数据IO口 char done,count,temp,flag,up_flag,down_flag; uchar temp_value;      //温度值 uchar TempBuffer[5],week_value[2]; void show_time();   //液晶显示程序 /***********1602液晶显示部分子程序****************/ //Port Definitions********************************************************** sbit LcdRs  = P2^5; sbit LcdRw  = P2^6; sbit LcdEn   = P2^7; sfr  DBPort  = 0x80;  //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口 //内部等待函数************************************************************************** unsigned char LCD_Wait(void) {  LcdRs=0;  LcdRw=1; _nop_();  LcdEn=1; _nop_();         LcdEn=0;  return DBPort;   } //向LCD写入命令或数据************************************************************ #define LCD_COMMAND   0      // Command #define LCD_DATA   1      // Data #define LCD_CLEAR_SCREEN 0x01      // 清屏 #define LCD_HOMING    0x02      // 光标返回原点 void LCD_Write(bit style, unsigned char input) {  LcdEn=0;  LcdRs=style;  LcdRw=0;  _nop_();  DBPort=input; _nop_();//注意顺序  LcdEn=1;  _nop_();//注意顺序  LcdEn=0;  _nop_();  LCD_Wait();  } //设置显示模式************************************************************ #define LCD_SHOW   0x04    //显示开 #define LCD_HIDE   0x00    //显示关   #define LCD_CURSOR   0x02  //显示光标 #define LCD_NO_CURSOR  0x00    //无光标       #define LCD_FLASH   0x01    //光标闪动 #define LCD_NO_FLASH  0x00    //光标不闪动 void LCD_SetDisplay(unsigned char DisplayMode) {  LCD_Write(LCD_COMMAND, 0x08|DisplayMode);  } //设置输入模式************************************************************ #define LCD_AC_UP   0x02 #define LCD_AC_DOWN   0x00      // default #define LCD_MOVE   0x01      // 画面可平移 #define LCD_NO_MOVE   0x00      //default void LCD_SetInput(unsigned char InputMode) {  LCD_Write(LCD_COMMAND, 0x04|InputMode); } //初始化LCD************************************************************ void LCD_Initial() {  LcdEn=0;  LCD_Write(LCD_COMMAND,0x38);           //8位数据端口,2行显示,5*7点阵  LCD_Write(LCD_COMMAND,0x38);  LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);    //开启显示, 无光标  LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏  LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);       //AC递增, 画面不动 } //液晶字符输入的位置************************ void GotoXY(unsigned char x, unsigned char y) {  if(y==0)   LCD_Write(LCD_COMMAND,0x80|x);  if(y==1)   LCD_Write(LCD_COMMAND,0x80|(x-0x40)); } //将字符输出到液晶显示 void Print(unsigned char *str) {  while(*str!='\0')  {   LCD_Write(LCD_DATA,*str);   str++;  } }     /***********DS1302时钟部分子程序******************/ typedef struct __SYSTEMTIME__ {  unsigned char Second;  unsigned char Minute;  unsigned char Hour;  unsigned char Week;  unsigned char Day;  unsigned char Month;  unsigned char  Year;  unsigned char DateString[11];  unsigned char TimeString[9]; }SYSTEMTIME; //定义的时间类型 SYSTEMTIME CurrentTime; #define AM(X) X #define PM(X) (X+12)               // 转成24小时制 #define DS1302_SECOND 0x80          //时钟芯片的寄存器位置,存放时间 #define DS1302_MINUTE 0x82 #define DS1302_HOUR  0x84 #define DS1302_WEEK  0x8A #define DS1302_DAY  0x86 #define DS1302_MONTH 0x88 #define DS1302_YEAR  0x8C void DS1302InputByte(unsigned char d)  //实时时钟写入一字节(内部函数) {     unsigned char i;     ACC = d;     for(i=8; i>0; i--)     {         DS1302_IO = ACC0;            //相当于汇编中的 RRC         DS1302_CLK = 1;         DS1302_CLK = 0;         ACC = ACC >> 1;     } } unsigned char DS1302OutputByte(void)  //实时时钟读取一字节(内部函数) {     unsigned char i;     for(i=8; i>0; i--)     {         ACC = ACC >>1;            //相当于汇编中的 RRC         ACC7 = DS1302_IO;         DS1302_CLK = 1;         DS1302_CLK = 0;     }     return(ACC); } void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据 {     DS1302_RST = 0;     DS1302_CLK = 0;     DS1302_RST = 1;     DS1302InputByte(ucAddr);        // 地址,命令     DS1302InputByte(ucDa);        // 写1Byte数据     DS1302_CLK = 1;     DS1302_RST = 0; } unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据 {     unsigned char ucData;     DS1302_RST = 0;     DS1302_CLK = 0;     DS1302_RST = 1;     DS1302InputByte(ucAddr|0x01);        // 地址,命令     ucData = DS1302OutputByte();         // 读1Byte数据     DS1302_CLK = 1;     DS1302_RST = 0;     return(ucData); }   void DS1302_GetTime(SYSTEMTIME *Time)  //获取时钟芯片的时钟数据到自定义的结构型数组 {  unsigned char ReadValue;  ReadValue = Read1302(DS1302_SECOND);  Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);  ReadValue = Read1302(DS1302_MINUTE);  Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);  ReadValue = Read1302(DS1302_HOUR);  Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);  ReadValue = Read1302(DS1302_DAY);  Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);   ReadValue = Read1302(DS1302_WEEK);  Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);  ReadValue = Read1302(DS1302_MONTH);  Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);  ReadValue = Read1302(DS1302_YEAR);  Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);  } void DateToStr(SYSTEMTIME *Time)    //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[] {   if(hide_year<2)                 //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22     {                                  Time->DateString[0] = '2';    Time->DateString[1] = '0';     Time->DateString[2] = Time->Year/10 + '0';    Time->DateString[3] = Time->Year%10 + '0';  }    else      {        Time->DateString[0] = ' ';        Time->DateString[1] = ' ';          Time->DateString[2] = ' ';        Time->DateString[3] = ' ';   }  Time->DateString[4] = '/';  if(hide_month<2)  {    Time->DateString[5] = Time->Month/10 + '0';    Time->DateString[6] = Time->Month%10 + '0';  }    else    {      Time->DateString[5] = ' ';      Time->DateString[6] = ' ';    }  Time->DateString[7] = '/';  if(hide_day<2)  {    Time->DateString[8] = Time->Day/10 + '0';    Time->DateString[9] = Time->Day%10 + '0';  }    else    {      Time->DateString[8] = ' ';      Time->DateString[9] = ' ';        }  if(hide_week<2)  {    week_value[0] = Time->Week%10 + '0';  //星期的数据另外放到 week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示  }    else    {      week_value[0] = ' ';    }    week_value[1] = '\0';  Time->DateString[10] = '\0'; //字符串末尾加 '\0' ,判断结束字符 } void TimeToStr(SYSTEMTIME *Time)  //将时,分,秒数据转换成液晶显示字符放到数组 TimeString[]; {   if(hide_hour<2)     {    Time->TimeString[0] = Time->Hour/10 + '0';    Time->TimeString[1] = Time->Hour%10 + '0';  }    else      {        Time->TimeString[0] = ' ';        Time->TimeString[1] = ' ';   }  Time->TimeString[2] = ':';     if(hide_min<2)  {    Time->TimeString[3] = Time->Minute/10 + '0';    Time->TimeString[4] = Time->Minute%10 + '0';  }    else      {        Time->TimeString[3] = ' ';        Time->TimeString[4] = ' ';         }  Time->TimeString[5] = ':';     if(hide_sec<2)     {    Time->TimeString[6] = Time->Second/10 + '0';    Time->TimeString[7] = Time->Second%10 + '0';     }       else        {          Time->TimeString[6] = ' ';       Time->TimeString[7] = ' ';        }  Time->DateString[8] = '\0'; } void Initial_DS1302(void)   //时钟芯片初始化 {    unsigned char Second="Read1302"(DS1302_SECOND);  if(Second&0x80)       //判断时钟芯片是否关闭       {  Write1302(0x8e,0x00); //写入允许  Write1302(0x8c,0x07); //以下写入初始化时间 日期:07/07/25.星期: 3. 时间: 23:59:55  Write1302(0x88,0x07);  Write1302(0x86,0x25);  Write1302(0x8a,0x07);  Write1302(0x84,0x23);  Write1302(0x82,0x59);  Write1302(0x80,0x55);  Write1302(0x8e,0x80); //禁止写入  } } /***********ds18b20子程序*************************/ /***********ds18b20延迟子函数(晶振12MHz )*******/ void delay_18B20(unsigned int i) {  while(i--); } /**********ds18b20初始化函数**********************/ void Init_DS18B20(void) {   unsigned char x="0";   DQ = 1;          //DQ复位   delay_18B20(8);  //稍做延时   DQ = 0;          //单片机将DQ拉低   delay_18B20(80); //精确延时 大于 480us   DQ = 1;          //拉高总线   delay_18B20(14);   x="DQ";            //稍做延时后 如果x=0则初始化成功 x="1则初始化失败"   delay_18B20(20); } /***********ds18b20读一个字节**************/  unsigned char ReadOneChar(void) {  uchar i="0";  uchar dat = 0;  for (i=8;i>0;i--)   {     DQ = 0; // 给脉冲信号     dat>>=1;     DQ = 1; // 给脉冲信号     if(DQ)     dat|=0x80;     delay_18B20(4);   }   return(dat); } /*************ds18b20写一个字节****************/  void WriteOneChar(uchar dat) {   unsigned char i="0";   for (i=8; i>0; i--)   {     DQ = 0;    DQ = dat&0x01;      delay_18B20(5);    DQ = 1;      dat>>=1;  } } /**************读取ds18b20当前温度************/ void ReadTemp(void) {  unsigned char a="0";  unsigned char b="0";  unsigned char t="0";  Init_DS18B20();  WriteOneChar(0xCC);     // 跳过读序号列号的操作  WriteOneChar(0x44);  // 启动温度转换  delay_18B20(100);       // this message is wery important  Init_DS18B20();  WriteOneChar(0xCC);  //跳过读序号列号的操作  WriteOneChar(0xBE);  //读取温度寄存器等(共可读9个寄存器) 前两个就是温度  delay_18B20(100);  a=ReadOneChar();     //读取温度值低位  b=ReadOneChar();     //读取温度值高位  temp_value=b<<4;  temp_value+=(a&0xf0)>>4;               } void temp_to_str()   //温度数据转换成液晶字符显示 {   TempBuffer[0]=temp_value/10+'0';  //十位   TempBuffer[1]=temp_value%10+'0';  //个位   TempBuffer[2]=0xdf;   //温度符号   TempBuffer[3]='C';   TempBuffer[4]='\0'; } void Delay1ms(unsigned int count) {  unsigned int i,j;  for(i=0;i<count;i++)  for(j=0;j<120;j++); } /*延时子程序*/ void mdelay(uint delay) { uint i;   for(;delay>0;delay--)      {for(i=0;i<62;i++) //1ms延时.          {;}      } } void outkey()                    //跳出调整模式,返回默认显示 { uchar Second;   if(out==0||wireless_1==1)           { mdelay(8);  count=0;  hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_month=0,hide_year=0;  Second=Read1302(DS1302_SECOND);     Write1302(0x8e,0x00); //写入允许  Write1302(0x80,Second&0x7f);  Write1302(0x8E,0x80);          //禁止写入  done=0;            while(out==0);  while(wireless_1==1);   } } //////////////////////////////////////////////////////////////////////////////////////////////////////////// void Upkey()//升序按键 {      Up=1;   if(Up==0||wireless_2==1)             {        mdelay(8);            switch(count)               {case 1:                                   temp="Read1302"(DS1302_SECOND);  //读取秒数           temp="temp"+1;  //秒数加1                                   up_flag=1;    //数据调整后更新标志           if((temp&0x7f)>0x59)   //超过59秒,清零                                   temp="0";                    break;                case 2:                                   temp="Read1302"(DS1302_MINUTE);  //读取分数           temp="temp"+1;  //分数加1                                   up_flag=1;           if(temp>0x59)          //超过59分,清零           temp="0";           break;                case 3:                                   temp="Read1302"(DS1302_HOUR);  //读取小时数           temp="temp"+1;  //小时数加1                                   up_flag=1;           if(temp>0x23)   //超过23小时,清零           temp="0";           break;                case 4:                                   temp="Read1302"(DS1302_WEEK);  //读取星期数           temp="temp"+1;  //星期数加1                                   up_flag=1;           if(temp>0x7)            temp="1";           break;                case 5:                                   temp="Read1302"(DS1302_DAY);  //读取日数           temp="temp"+1;  //日数加1                                   up_flag=1;           if(temp>0x31)           temp="1";           break;                case 6:                                   temp="Read1302"(DS1302_MONTH);  //读取月数           temp="temp"+1;  //月数加1                                   up_flag=1;           if(temp>0x12)           temp="1";           break;                case 7:                                   temp="Read1302"(DS1302_YEAR);  //读取年数           temp="temp"+1;  //年数加1                                   up_flag=1;           if(temp>0x85)           temp="0";           break;             default:break;               }               while(Up==0);                 while(wireless_2==1);       } } //////////////////////////////////////////////////////////////////////////////////////////////////////////// void Downkey()//降序按键 {       Down=1;      if(Down==0||wireless_3==1)             {        mdelay(8);          switch(count)               {case 1:                                   temp="Read1302"(DS1302_SECOND);  //读取秒数           temp="temp-1";          //秒数减1                                   down_flag=1;       //数据调整后更新标志           if(temp==0x7f)     //小于0秒,返回59秒           temp="0x59";           break;                case 2:                                   temp="Read1302"(DS1302_MINUTE);  //读取分数           temp="temp-1";  //分数减1                                   down_flag=1;           if(temp==-1)           temp="0x59";      //小于0秒,返回59秒           break;                case 3:                                   temp="Read1302"(DS1302_HOUR);  //读取小时数           temp="temp-1";  //小时数减1                                   down_flag=1;           if(temp==-1)           temp="0x23";           break;                case 4:                                   temp="Read1302"(DS1302_WEEK);  //读取星期数           temp="temp-1";  //星期数减1                                   down_flag=1;           if(temp==0)           temp="0x7";;           bre
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服