12864+DS1302时钟+18B20温度计.docx
《12864+DS1302时钟+18B20温度计.docx》由会员分享,可在线阅读,更多相关《12864+DS1302时钟+18B20温度计.docx(30页珍藏版)》请在冰豆网上搜索。
![12864+DS1302时钟+18B20温度计.docx](https://file1.bdocx.com/fileroot1/2022-11/20/92eeea6b-c96f-4e61-a2c8-09cb5c8fecc5/92eeea6b-c96f-4e61-a2c8-09cb5c8fecc51.gif)
12864+DS1302时钟+18B20温度计
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
sbitDS1302_CLK=P1^0;//实时时钟时钟线引脚
sbitDS1302_IO=P1^1;//实时时钟数据线引脚
sbitDS1302_RST=P1^2;//实时时钟复位线引脚
sbitDQ=P3^3;//温度传送数据IO口
sbitACC0=ACC^0;
sbitACC7=ACC^7;
ucharhide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year;//秒,分,时到日,月,年位闪的计数
sbitSet=P1^4;//模式切换键对应实验板K5
sbitUp=P1^5;//加法按钮对应实验板K6
sbitDown=P1^6;//减法按钮对应实验板K7
sbitout=P1^7;//立刻跳出调整模式按钮对应实验板K8
uchardone,count,temp,up_flag,down_flag;
uchartemp_value,temp1_value;//temp_value温度值正数部分temp1_value温度值小数部分
ucharTempBuffer[8],week_value[3];
voidshow_time();//液晶显示程序
//****************************************
//12864液晶显示部分子程序模块
//****************************************
sbitrs=P2^0;
sbitrw=P2^1;
sbite=P2^2;
#definelcddataP0
sbitbusy=P0^7;//lcdbusybit
voidwr_d_lcd(ucharcontent);
voidwr_i_lcd(ucharcontent);
voidclrram_lcd(void);
voidinit_lcd(void);
voidbusy_lcd(void);
voidrev_row_lcd(ucharrow);
voidrev_co_lcd(ucharrow,ucharcol,ucharmode);
voidclr_lcd(void);
voidwr_co_lcd(ucharrow,ucharcol,ucharlcddata1,ucharlcddtta2);
voidwr_row_lcd(ucharrow,char*p);
//**********************************
//液晶初始化
//**********************************
voidinit_lcd(void)
{
wr_i_lcd(0x06);/*光标的移动方向*/
wr_i_lcd(0x0c);/*开显示,关游标*/
}
//***********************************
//填充液晶DDRAM全为空格
//**********************************
voidclrram_lcd(void)
{
wr_i_lcd(0x30);
wr_i_lcd(0x01);
}
//***********************************
//对液晶写数据
//content为要写入的数据
//***********************************
voidwr_d_lcd(ucharcontent)
{
busy_lcd();
rs=1;
rw=0;
lcddata=content;
e=1;
;
e=0;
}
//********************************
//对液晶写指令
//content为要写入的指令代码
//*****************************
voidwr_i_lcd(ucharcontent)
{
busy_lcd();
rs=0;
rw=0;
lcddata=content;
e=1;
;
e=0;
}
//********************************
//液晶检测忙状态
//在写入之前必须执行
//********************************
voidbusy_lcd(void)
{
lcddata=0xff;
rs=0;
rw=1;
e=1;
while(busy==1);
e=0;
}
//********************************
//指定要显示字符的坐标
//*******************************
voidgotoxy(unsignedchary,unsignedcharx)
{
if(y==1)
wr_i_lcd(0x80|x);
if(y==2)
wr_i_lcd(0x90|x);
if(y==3)
wr_i_lcd((0x80|x)+8);
if(y==4)
wr_i_lcd((0x90|x)+8);
}
//**********************************
//液晶显示字符串程序
//**********************************
voidprint(uchar*str)
{
while(*str!
='\0')
{
wr_d_lcd(*str);
str++;
}
}
//***********************************
//DS1302时钟部分子程序模块
//***********************************
typedefstruct__SYSTEMTIME__
{
ucharSecond;
ucharMinute;
ucharHour;
ucharWeek;
ucharDay;
ucharMonth;
ucharYear;
ucharDateString[11];
ucharTimeString[9];
}SYSTEMTIME;//定义的时间类型
SYSTEMTIMECurrentTime;
#defineAM(X)X
#definePM(X)(X+12)//转成24小时制
#defineDS1302_SECOND0x80//时钟芯片的寄存器位置,存放时间
#defineDS1302_MINUTE0x82
#defineDS1302_HOUR0x84
#defineDS1302_WEEK0x8A
#defineDS1302_DAY0x86
#defineDS1302_MONTH0x88
#defineDS1302_YEAR0x8C
//**********************************
//实时时钟写入一字节(内部函数)
//**********************************
voidDS1302InputByte(uchard)
{
uchari;
ACC=d;
for(i=8;i>0;i--)
{
DS1302_IO=ACC0;//相当于汇编中的RRC
DS1302_CLK=1;
DS1302_CLK=0;
ACC=ACC>>1;
}
}
//*************************************
//实时时钟读取一字节(内部函数)
//*************************************
ucharDS1302OutputByte(void)
{
uchari;
for(i=8;i>0;i--)
{
ACC=ACC>>1;//相当于汇编中的RRC
ACC7=DS1302_IO;
DS1302_CLK=1;
DS1302_CLK=0;
}
return(ACC);
}
//**************************************
//ucAddr:
DS1302地址,ucData:
要写的数据
//**************************************
voidWrite1302(ucharucAddr,ucharucDa)
{
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr);//地址,命令
DS1302InputByte(ucDa);//写1Byte数据
DS1302_CLK=1;
DS1302_RST=0;
}
//**************************************
//读取DS1302某地址的数据
//**************************************
ucharRead1302(ucharucAddr)
{
ucharucData;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr|0x01);//地址,命令
ucData=DS1302OutputByte();//读1Byte数据
DS1302_CLK=1;
DS1302_RST=0;
return(ucData);
}
//******************************************
//获取时钟芯片的时钟数据到自定义的结构型数组
//******************************************
voidDS1302_GetTime(SYSTEMTIME*Time)
{
ucharReadValue;
ReadValue=Read1302(DS1302_SECOND);
Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);//转换为相应的10进制数
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&0x10)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_MONTH);
Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_YEAR);
Time->Year=((ReadValue&0xf0)>>4)*10+(ReadValue&0x0F);
}
//******************************************
//将时间年,月,日,星期数据转换成液
//晶显示字符串,放到数组里DateString[]
//******************************************
voidDateToStr(SYSTEMTIME*Time)
{
uchartab[]={0XD2,0XBB,0XB6,0XFE,0XC8,0XFD,0XCB,0XC4,0XCE,0XE5,0XC1,0XF9,0XC8,0XD5};
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]=tab[2*(Time->Week%10)-2];//星期的数据另外放到week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示
week_value[1]=tab[2*(Time->Week%10)-1];
}
else
{
week_value[0]='';
week_value[1]='';
}
week_value[2]='\0';
Time->DateString[10]='\0';//字符串末尾加'\0',判断结束字符
}
//******************************************
//将时,分,秒数据转换成液晶
//显示字符放到数组TimeString[]
//*****************************************
voidTimeToStr(SYSTEMTIME*Time)
{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->TimeString[8]='\0';
}
//******************************
//时钟芯片初始化
//******************************
voidInitial_DS1302(void)
{
ucharSecond=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子程序*************************/
/***********ds18b20延迟子函数(晶振12MHz)*******/
voiddelay_18B20(unsignedinti)
{
while(i--);
}
/**********ds18b20初始化函数**********************/
voidInit_DS18B20(void)
{
unsignedcharx=0;
DQ=1;//DQ复位
delay_18B20(8);//稍做延时
DQ=0;//单片机将DQ拉低
delay_18B20(40);//精确延时大于480us
DQ=1;//拉高总线
delay_18B20(7);
x=DQ;//稍做延时后如果x=0则初始化成功x=1则初始化失败
delay_18B20(10);
}
/***********ds18b20读一个字节**************/
ucharReadOneChar(void)
{
uchari=0;
uchardat=0;
for(i=8;i>0;i--)
{
DQ=0;//给脉冲信号
dat>>=1;
DQ=1;//给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
/*************ds18b20写一个字节****************/
voidWriteOneChar(uchardat)
{
uchari=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
delay_18B20(5);
DQ=1;
dat>>=1;
}
}
/**************读取ds18b20当前温度************/
voidReadTemp(void)
{
uchara=0;
ucharb=0;
uchart;
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0x44);//启动温度转换
delay_18B20(100);//thismessageisweryimportant
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0xBE);//读取温度寄存器等(共可读9个寄存器)前两个就是温度
delay_18B20(50);
a=ReadOneChar();//读取温度值低位
b=ReadOneChar();//读取温度值高位
t=b&0xf8;
if(t)
{
TempBuffer[0]=':
';
TempBuffer[1]='-';
temp_value=b<<4;
temp_value+=(a&0xf0)>>4;
temp_value=~temp_value+1;
temp1_value=~a&0x0f;
}
else
{
temp_value=b<<4;
temp_value+=(a&0xf0)>>4;
temp1_value=a&0x0f;
TempBuffer[0]=':
';
TempBuffer[1]=temp_value/100+'0';//百位
if(TempBuffer[1]=='1')
{
TempBuffer[1]='1';
}
else
{
TempBuffer[1]='';
}
}
}
voidtemp_to_str()//温度数据转换成液晶字符显示
{
TempBuffer[2]=temp_value%100/10+'0';//十位
TempBuffer[3]=temp_value%10+'0';//个位
Temp