效果和接法看圖吧,只是簡單用時鐘芯片顯示時間
屏幕截圖 2021-09-04 125226.png (149.71 KB, 下載次數: 59)
下載附件
2021-9-4 12:57 上傳
單片機源程序如下:
- #include <reg51.h>
- #include <string.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define delayNOP() {_nop_();_nop_();_nop_();_nop_();}
- sbit SDA=P2^6; // DS1302數據線
- sbit CLK=P2^5; // DS1302時鐘線
- sbit RST=P2^4; // DS1302復位線
- //DS18B20數據端口定義
- sbit DQ=P2^4; //DS18B20數據端口
- sbit LCD_RS=P2^0; // LCD寄存器選擇
- sbit LCD_RW=P2^1; // LCD讀寫/寫控制
- sbit LCD_EN=P2^2; // LCD啟用
- uchar tCount=0;
- //一年中每個月的天數,2月的天數由年份決定
- uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31};
- //周日,每周一到周六(0,1-6)【讀取DS1302時分別是1-7】
- uchar *WEEK[]={"SUN","MON","TUS","WEN","THU","FRI","SAT"};
- //LCD顯示緩沖
- uchar LCD_DSY_BUFFER1[]={"00-00-00 "};
- uchar LCD_DSY_BUFFER2[]={"00-00-00 "};
- uchar DateTime[7]; //所讀取的日期時間
- uchar Adjust_flag=0; //當前調節的時間對像:秒,分,時,日,月,年(1,2,3,4,5,6)
- uchar Change_Flag[]=" YMDHM";//(分,時,日,月,年)(不調節秒與周)
- void DelayMS(uchar x)//延時
- {uchar i;
- while(x--)
- for(i=0;i<120;i++);
- }
- void Write_A_Byte_TO_DS1302(uchar x)//向DS1302寫入一個字節
- {uchar i;
- for(i=0;i<8;i++)
- {SDA=x&1; CLK=1; CLK=0; x>>=1;
- }
- }
- uchar Get_A_Byte_FROM_DS1302()//讀取一個字節
- {uchar i,b,t;
- for(i=0;i<8;i++)
- {b>>=1; t=SDA; b|=t<<7; CLK=1;CLK=0;
- }
- return b/16*10+b%16;//BCD碼轉換
- }
- uchar Read_Data(uchar addr)//指定位置讀數據
- {uchar dat;
- RST=0; CLK=0; RST=1;
- Write_A_Byte_TO_DS1302(addr);
- dat=Get_A_Byte_FROM_DS1302();
- CLK=1;RST=0;
- return dat;
- }
- void Write_DS1302(uchar addr,uchar dat)//向某地址寫入數據
- {CLK=0;RST=1;
- Write_A_Byte_TO_DS1302(addr);
- Write_A_Byte_TO_DS1302(dat);
- CLK=0;RST=0;
- }
- void SET_DS1302()//設置時間
- { uchar i;
- Write_DS1302(0x8e,0x00);
- for(i=0;i<7;i++)
- {
- Write_DS1302(0X80+2*i,(DateTime[i]/10<<4)|(DateTime[i]%10));//日,月,周,年,寫入 地址每次增2
- }
- Write_DS1302(0x8e,0x80);//加保護
- }
- void GetTime()//讀取本地的時間
- {
- uchar i;
- for(i=0;i<7;i++)
- {
- DateTime[i]=Read_Data(0x81+2*i);
- }
- }
- //LCD驅動代碼
- bit LCD_Busy_Check()//LCD忙
- {bit result;
- LCD_RS=0;
- LCD_RW=1;
- LCD_EN=1;
- delayNOP();
- result=(bit)(P0&0x80);
- LCD_EN=0;
- return result;
- }
- void Write_LCD_Command(uchar cmd) //寫指令
- {while(LCD_Busy_Check());
- LCD_RS=0;LCD_RW=0;LCD_EN=0; _nop_(); _nop_();
- P0=cmd;
- delayNOP();
- LCD_EN=1;
- delayNOP();
- LCD_EN=0;
- }
-
- void Write_LCD_Data(uchar dat)//寫數據
- {while(LCD_Busy_Check());
- LCD_RS=1;LCD_RW=0;LCD_EN=0;
- P0=dat;
- delayNOP();
- LCD_EN=1;
- delayNOP();
- LCD_EN=0;
- }
- void Init_LCD()//LCD初始化
- {Write_LCD_Command(0x01);DelayMS(5);
- Write_LCD_Command(0x38);DelayMS(5);
- Write_LCD_Command(0x0c);DelayMS(5);
- Write_LCD_Command(0x06);DelayMS(5);
- }
- void Set_LCD_POS(uchar pos)//設置顯示位置
- { Write_LCD_Command(pos|0x80);
- }
- void Display_LCD_String(uchar p,uchar *s)//在LCD上顯示字符串
- {uchar i;
- Set_LCD_POS(p);
- for(i=0;i<16;i++)
- {Write_LCD_Data(s[i]);
- DelayMS(1);
- }
- }
- void Format_DateTime(uchar d,uchar *a)//日期與時間值轉換為數字字符
- {a[0]=d/10+'0';
- a[1]=d%10+'0';
- }
- uchar isLeapYear(uint y)//判斷是否為閏年
- {return (y%4==0&&y%100!=0)||(y%400==0);
- }
- void RefreshWeekDay()
- {uint i,d,w=5; //
- for(i=2021;i<2021+DateTime[6];i++)
- { d=isLeapYear(i)?366:365;
- w=(w+d)%7;
- }
- d=0;
- for(i=1;i<DateTime[4];i++)
- d+=MonthsDays[i];
- d+=DateTime[3];
- DateTime[5]=(w+d)%7+1;
- }
- //定時器0每秒刷新LCD顯示
- void T0_INT() interrupt 1
- { uchar i;
- if(++tCount!=2) return;
- tCount=0;//刷新
- Format_DateTime(DateTime[6],LCD_DSY_BUFFER1);//年
- Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+3);//月
- Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+6);//日
- Format_DateTime(DateTime[2],LCD_DSY_BUFFER2);//時
- Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+3);//分
- Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+6);//秒
- Display_LCD_String(0x03,LCD_DSY_BUFFER1);//顯示年月日,星期,時分秒
- Set_LCD_POS(0x43);
- for(i=0;i<14;i++)
- {
- Write_LCD_Data(LCD_DSY_BUFFER2[i]);
- DelayMS(1);
- }
- }
- //主程序
- void main()
- {
- Init_LCD();//液晶初始化
- IE=0X87;//允許INT0,T0中斷
- TR0=1;
- while(1)
- {GetTime();
-
- }}
復制代碼 |