教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 精品文档 > 说明书 >

基于51单片机DS1302 DS18B20和12864显示程序

来源:网络收集 时间:2026-01-16
导读: 给你一个昨天晚上做的《可调式电子时钟》,仿真图见图片 程序源代码: //------------------------------------------------------------------------------------- //名称:用DS1302与1602设计的可调式电子日历时钟 //------------------------------------

给你一个昨天晚上做的《可调式电子时钟》,仿真图见图片

程序源代码:

//-------------------------------------------------------------------------------------

//名称:用DS1302与1602设计的可调式电子日历时钟

//-------------------------------------------------------------------------------------

#include<reg52.h>

#include<string.h>

#define uchar unsigned char

#define uint unsigned int

sbit SDA=P1^0;//DS1302数据线

sbit CLK=P1^1;//DS1302时钟线

sbit RST=P1^2;//DS1302复位线

sbit RS=P2^0;//LCD寄存器选择

sbit RW=P2^1;//LCD读/写控制

sbit EN=P2^2;//LCD使能段

sbit K1=P3^4;//选择

sbit K2=P3^5;//加

sbit K3=P3^6;//减

sbit K4=P3^7;//确定

uchartCount=0;

//一年中每个月的天数,2月的天数有年份决定

ucharMonthsDays[]={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[]={"DATE 00-00-00 "};

uchar LCD_DSY_BUFFER2[]={"TIME 00:00:00 "};

ucharDateTime[7];//所读取的日期时间

char Adjust_Index=-1;//当前调节的时间对象:秒,分,时,日,月,年(0,1,2,3,4,6)

ucharChange_Flag[]="-MHDM-Y";//(分,时,日,月,年)(不调秒与周)

voidDelayMS(uint x)

{

uchar i;

while(x--) for(i=0;i<120;i++);

}

//向DS1302写入一个字节

void Write_A_Byte_TO_DS1302(uchar x)

{

uchar i;

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

{

SDA=x&1;

CLK=1;

CLK=0;

x>>=1;

}

}

//从DS1302里读取一个字节

uchar Get_A_Byte_FROM_DS1302()

{

uchari,b,t;

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

{

b>>=1;

t=SDA;

b|=t<<7;

CLK=1;

CLK=0;

}

//BCD码转换

return b/16*10+b%16;

}

//从DS1302指定的位置读数据

ucharRead_Data(ucharaddr)

{

uchardat;

RST=0;

CLK=0;

RST=1;

Write_A_Byte_TO_DS1302(addr);

dat=Get_A_Byte_FROM_DS1302();

CLK=1;

RST=0;

returndat;

}

//向DS1302某地址写入数据

void Write_DS1302(ucharaddr, uchardat)

{

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=1;i<7;i++)

{

//分的起始地址100000010(0x80),后面依次是时,日,月,周,年,写入地址每次递增2

Write_DS1302(0x80+2*i,(DateTime[i]/10<<4)|(DateTime[i]&10)); }

Write_DS1302(0x8e,0x80);//加保护

}

//读取当前日期时间

voidGetTime()

{

uchar i;

for(i=0;i<7;i++)

DateTime[i]=Read_Data(0x81+2*i);

}

//读LCD状态

ucharRead_LCD_State()

{

uchar state;

RS=0;

RW=1;

EN=1;

DelayMS(1);

state=P0;

EN=0;

DelayMS(1);

return state;

}

//忙等待

voidLCD_Busy_Wait()

{

while((Read_LCD_State()&0x80)==0x80);

DelayMS(5);

}

//向LCD写数据

voidWrite_LCD_Date(uchardat)

{

LCD_Busy_Wait();

RS=1;

RW=0;

EN=0;

P0=dat;

EN=1;

DelayMS(1);

EN=0;

}

//写指令

voidWrite_LCD_Command(ucharcmd)

{

LCD_Busy_Wait();

RS=0;

RW=0;

EN=0;

P0=cmd;

EN=1;

DelayMS(1);

EN=0;

}

//LCD初始化

voidInit_LCD()

{

Write_LCD_Command(0X38);

DelayMS(1);

Write_LCD_Command(0x01);

DelayMS(1);

Write_LCD_Command(0x06);

DelayMS(1);

Write_LCD_Command(0x0c);

}

//设置液晶屏位置

voidSet_LCD_POS(uchar p)

{

Write_LCD_Command(p|0x80);

}

//在LCD上显示字符串

voidDisplay_LCD_String(ucharp,uchar *s)

{

uchar i;

Set_LCD_POS(p);

for(i=0;i<16;i++)

Write_LCD_Date(s[i]);

DelayMS(1);

}

//日期与时间值转换为数字符

voidFormat_DateTime(uchar d, uchar *a)

{

a[0]=d/10+'0';

a[1]=d%10+'0';

}

//判断是否为润年

ucharisLeapYear(uint y)

{

return(y%4==0&&y%100!=0)||(y%400==0);

}

//求自2000.1.1开始的任何一天是星期几

//函数没有通过,求出总天数后再求星期几

//因为求总天数可能会越出uint的范围

voidRefreshWeekDay()

{

uint i, d, w=5;//已知1999.12.31是周五

for(i=2000;i<2000+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];

//保存星期,0~6表示星期日,星期一,二,...六,为了与DS1302的星期格式匹配,返回值需要加1

DateTime[5]=(w+d)%7+1;

}

//年月日时分++/--

voidDateTime_Adjust(char x)

{

switch(Adjust_Index)

{

case 6://年00~99

if(x==1&&DateTime[6]<99) DateTime[6]++;

if(x==-1&&DateTime[6]>0) DateTime[6]--;

//获取2月天数

MonthsDays[2]=isLeapYear(2000+DateTime[6])? 29:28;

//如果年份变换后当前月份的天数大于上限则设为上限

if(DateTime[3]>MonthsDays[DateTime[4]])

DateTime[3]=MonthsDays[DateTime[4]];

RefreshWeekDay();//刷新星期

break;

case 4://月01-12

if(x==1&&DateTime[4]<12) DateTime[4]++;

if(x==-1&&DateTime[4]>1) DateTime[4]--;

//获取2月天数

MonthsDays[2]=isLeapYear(2000+DateTime[6])? 29:28;

//如果月份变换后当前月份的天数大于上限则设为上限

if(DateTime[3 …… 此处隐藏:3809字,全部文档内容请下载后查看。喜欢就下载吧 ……

基于51单片机DS1302 DS18B20和12864显示程序.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wendang/1484481.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)