使用1602液晶显示DS1302+S51时钟+温度显示cytrm.docx
《使用1602液晶显示DS1302+S51时钟+温度显示cytrm.docx》由会员分享,可在线阅读,更多相关《使用1602液晶显示DS1302+S51时钟+温度显示cytrm.docx(22页珍藏版)》请在冰豆网上搜索。
使用1602液晶显示DS1302+S51时钟+温度显示cytrm
=============================================================*/
/*#include*/
#include
#include
#include
#defineLCM_RSP2_0//定义引脚
#defineLCM_RWP2_1
#defineLCM_EP2_2
#defineLCM_DataP0
#defineBusy0x80//用于检测LCM状态字中的Busy标识
#defineucharunsignedchar
ucharid,timecount;
bitflag,sflag;//flag是时钟冒号闪烁标志,sflag是温度负号显示标志
voidDisp_line1(void);//显示屏幕第一行
voidDisp_line2(void);//显示屏幕第二行
voidid_case1_key();
//***********DS1302时间显示定义部分
sbitT_CLK=P1^0;
sbitT_IO=P1^1;
sbitT_RST=P1^2;
sbitACC0=ACC^0;
sbitACC7=ACC^7;
voidSet(uchar,uchar);//根据选择调整相应项目
voidRTInputByte(uchar);/*输入1Byte*/
ucharRTOutputByte(void);/*输出1Byte*/
voidW1302(uchar,uchar);//向DS1302写入一个字节
ucharR1302(uchar);//从DS1302读出一个字节
voidSet1302(unsignedchar*);//设置时间
bitsec,min,hour,year,mon,day,weekk;//闪烁标志位
//初始化后设置为:
04年12月2日星期40点0分0秒
unsignedcharinittime[7]={0x00,0x00,0x00,0x02,0x12,0x04,0x04};
//秒分钟小时日月年星期
//*****18B20温度显示定义部分
sbitDQ=P3^3;//18B20接P07口
typedefunsignedcharbyte;
typedefunsignedintword;
Read_Temperature(char,char);
voidmychar(void);
voidadjust_res(charres);//res分别等于0x1f,0x3f,0x5f温度读数分辨率分别对应
//0.5,0.25,0.125
//*******1602LCD驱动
**********************************************************
voidWriteDataLCM(unsignedcharWDLCM);
voidWriteCommandLCM(unsignedcharWCLCM,BuysC);
unsignedcharReadStatusLCM(void);
voidLCMInit(void);
voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedchar
DData);
voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode
*DData);
voidDelay5Ms(void);
voidDelay400Ms(void);
unsignedcharcodeweek[]={"Week."};
/////////////////////////////////////////////////////////////////////
voidmain(void)
{
Delay400Ms();//启动等待,等LCM讲入工作状态
LCMInit();//LCM初始化
Delay5Ms();//延时片刻(可不要)
mychar();//显示自定义字符
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
EA=1;
TR0=1;
ET0=1;
W1302(0x90,0xa5);//打开充电二级管一个二级管串联一个2K电阻
W1302(0x8e,0x80);//写保护,禁止写操作
adjust_res(0x1f);//调整18B20的分辨率0x1f:
0.5;0x3f:
0.25;0x5f:
0.125
while
(1)
{
if((P1_4|P1_5)==0)//初始化
{
Delay5Ms();
if((P1_4|P1_5)==0)Set1302(inittime);
}
if(P1_6==0)//设置和选择项目键
{
Delay5Ms();
if(P1_6==0){id++;if(id>7)id=0;}
while(P1_6==0);
}
switch(id)
{
case0:
sec=0;
Disp_line1();Disp_line2();
break;
case1:
//年
year=1;
Disp_line1();Disp_line2();
id_case1_key();
break;
case2:
//月
year=0;mon=1;
Disp_line1();Disp_line2();
id_case1_key();
break;
case3:
//日
mon=0;day=1;
Disp_line1();Disp_line2();
id_case1_key();
break;
case4:
//星期
day=0;weekk=1;
Disp_line1();Disp_line2();
id_case1_key();
break;
case5:
//小时
weekk=0;hour=1;
Disp_line1();Disp_line2();
id_case1_key();
break;
case6:
//分钟
hour=0;min=1;
Disp_line1();Disp_line2();
id_case1_key();
break;
case7:
//秒
min=0;sec=1;
Disp_line1();Disp_line2();
id_case1_key();
break;
}
}
}
//中断入口,冒号闪烁
voidt0(void)interrupt1using0
{
TH0=(65535-50000)/256;//50ms定时
TL0=(65535-50000)%256;
timecount++;
if(timecount>9)
{
timecount=0;
flag=~flag;
}
}
//id为1时的下一级选择
voidid_case1_key()
{
if(P1_5==0)//增加
{
Delay5Ms();
if(P1_5==0)Set(id,0);
if(id!
=7)while(P1_5==0);
}
if(P1_4==0)//减少
{
Delay5Ms();
if(P1_4==0)Set(id,1);
if(id!
=7)while(P1_4==0);
}
}
//根据选择调整相应项目并写入DS1302
voidSet(ucharsel,ucharsel_1)
{
signedcharaddress,item;
signedcharmax,mini;
if(sel==7){address=0x80;max=0;mini=0;}//秒
if(sel==6){address=0x82;max=59;mini=0;}//分钟
if(sel==5){address=0x84;max=23;mini=0;}//小时
if(sel==3){address=0x86;max=31;mini=1;}//日
if(sel==2){address=0x88;max=12;mini=1;}//月
if(sel==1){address=0x8c;max=99;mini=0;}//年
if(sel==4){address=0x8a;max=7;mini=1;}//星期
item=R1302(address+1)/16*10+R1302(address+1)%16;
if(sel_1==0)item++;elseitem--;
if(item>max)item=mini;
if(itemW1302(0x8e,0x00);//允许写操作
W1302(address,item/10*16+item%10);
W1302(0x8e,0x80);//写保护,禁止写操作
}
//屏幕显示第一行时间和温度
voidDisp_line1(void)
{
Read_Temperature(10,0);//温度显示
//冒号闪烁
if(flag==0)
{DisplayOneChar(3,0,0x3a);DisplayOneChar(6,0,0x3a);}
else
{DisplayOneChar(3,0,0x20);DisplayOneChar(6,0,0x20);}
if(sec==1)//秒闪烁标志位
{
if(flag==1)
{
DisplayOneChar(7,0,R1302(0x81)/16+0x30);//显示秒
DisplayOneChar(8,0,R1302(0x81)%16+0x30);
}
else
{
DisplayOneChar(7,0,0x20);//显示秒
DisplayOneChar(8,0,0x20);
}
}
else
{
DisplayOneChar(7,0,R1302(0x81)/16+0x30);//显示秒
DisplayOneChar(8,0,R1302(0x81)%16+0x30);
}
if(min==1)//分钟闪烁标志位
{
if(flag==1)
{
DisplayOneChar(4,0,R1302(0x83)/16+0x30);//显示分钟
DisplayOneChar(5,0,R1302(0x83)%16+0x30);
}
else
{
DisplayOneChar(4,0,0x20);//显示分钟
DisplayOneChar(5,0,0x20);
}
}
else
{
DisplayOneChar(4,0,R1302(0x83)/16+0x30);//显示分钟
DisplayOneChar(5,0,R1302(0x83)%16+0x30);
}
if(hour==1)//小时闪烁标志位
{
if(flag==1)
{
DisplayOneChar(1,0,R1302(0x85)/16+0x30);//显示小时
DisplayOneChar(2,0,R1302(0x85)%16+0x30);
}
else
{
DisplayOneChar(1,0,0x20);//显示小时
DisplayOneChar(2,0,0x20);
}
}
else
{
DisplayOneChar(1,0,R1302(0x85)/16+0x30);//显示小时
DisplayOneChar(2,0,R1302(0x85)%16+0x30);
}
}
//屏幕显示第二行日期和星期
voidDisp_line2(void)
{
DisplayOneChar(3,1,0x2f);//显示固定字符
DisplayOneChar(6,1,0x2f);
DisplayListChar(10,1,week);
if(year==1)//年闪烁标志位
{
if(flag==1)
{
DisplayOneChar(1,1,R1302(0x8d)/16+0x30);//显示年
DisplayOneChar(2,1,R1302(0x8d)%16+0x30);
}
else
{
DisplayOneChar(1,1,0x20);//显示年
DisplayOneChar(2,1,0x20);
}
}
else
{
DisplayOneChar(1,1,R1302(0x8d)/16+0x30);//显示年
DisplayOneChar(2,1,R1302(0x8d)%16+0x30);
}
if(mon==1)//月闪烁标志位
{
if(flag==1)
{
DisplayOneChar(4,1,R1302(0x89)/16+0x30);//显示月
DisplayOneChar(5,1,R1302(0x89)%16+0x30);
}
else
{
DisplayOneChar(4,1,0x20);//显示月
DisplayOneChar(5,1,0x20);
}
}
else
{
DisplayOneChar(4,1,R1302(0x89)/16+0x30);//显示月
DisplayOneChar(5,1,R1302(0x89)%16+0x30);
}
if(day==1)//日闪烁标志位
{
if(flag==1)
{
DisplayOneChar(7,1,R1302(0x87)/16+0x30);//显示日
DisplayOneChar(8,1,R1302(0x87)%16+0x30);
}
else
{
DisplayOneChar(7,1,0x20);//显示日
DisplayOneChar(8,1,0x20);
}
}
else
{
DisplayOneChar(7,1,R1302(0x87)/16+0x30);//显示日
DisplayOneChar(8,1,R1302(0x87)%16+0x30);
}
if(weekk==1)//星期闪烁标志位
{
if(flag==1)
{
DisplayOneChar(15,1,R1302(0x8b)%16+0x30);//显示星期
}
else
{
DisplayOneChar(15,1,0x20);//显示星期
}
}
else
{
DisplayOneChar(15,1,R1302(0x8b)%16+0x30);//显示星期
}
}
//*********LCM1602驱动程序***************
//写数据
voidWriteDataLCM(unsignedcharWDLCM)
{
ReadStatusLCM();//检测忙
LCM_Data=WDLCM;
LCM_RS=1;
LCM_RW=0;
LCM_E=0;//若晶振速度太高可以在这后加小的延时
LCM_E=0;//延时
LCM_E=1;
}
//写指令
voidWriteCommandLCM(unsignedcharWCLCM,BuysC)//BuysC为0时忽略忙检测
{
if(BuysC)ReadStatusLCM();//根据需要检测忙
LCM_Data=WCLCM;
LCM_RS=0;
LCM_RW=0;
LCM_E=0;
LCM_E=0;
LCM_E=1;
}
//读状态
unsignedcharReadStatusLCM(void)
{
LCM_Data=0xFF;
LCM_RS=0;
LCM_RW=1;
LCM_E=0;
LCM_E=0;
LCM_E=1;
while(LCM_Data&Busy);//检测忙信号
return(LCM_Data);
}
//LCM初始化
voidLCMInit(void)
{
LCM_Data=0;
WriteCommandLCM(0x38,0);//三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,1);//显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1);//关闭显示
WriteCommandLCM(0x01,1);//显示清屏
WriteCommandLCM(0x06,1);//显示光标移动设置
WriteCommandLCM(0x0C,1);//显示开及光标设置
}
//按指定位置显示一个字符
voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData)
{
Y&=0x1;
X&=0xF;//限制X不能大于15,Y不能大于1
if(Y)X|=0x40;//当要显示第二行时地址码+0x40;
X|=0x80;//算出指令码
WriteCommandLCM(X,0);//这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}
//按指定位置显示一串字符***原来的遇到空格0x20就不显示***
voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode
*DData)
{
unsignedcharListLength,j;
ListLength=strlen(DData);
Y&=0x1;
X&=0xF;//限制X不能大于15,Y不能大于1
if(X<=0xF)//X坐标应小于0xF
{
for(j=0;j{
DisplayOneChar(X,Y,DData[j]);//显示单个字符
X++;
}
}
}
//5ms延时
voidDelay5Ms(void)
{
unsignedintTempCyc=5552;
while(TempCyc--);
}
//400ms延时
voidDelay400Ms(void)
{
unsignedcharTempCycA=5;
unsignedintTempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}
1602显示时钟
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitDS1302_CLK=P1^2;
sbitDS1302_IO=P1^1;
sbitDS1302_RST=P1^0;
sbitlcden=P2^2;
sbitlcdwr=P2^1;
sbitlcdrs=P2^0;
unsignedcharsecond,minute,hour,week,day,month,year;
unsignedchartable[]="0123456789";
//unsignedchartable1[]=" ";
unsignedchartable2[]=" ";
unsignedchartable3[]="Time:
";
unsignedchartable4[]="Date:
";
unsignedinttime[]={
0x09,0x12,0x27,0x03,0x23,0x59,0x40
};
ucharnum,count,date,shi;
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//向DS1302送一个字节//
voidInputByte(unsignedcharbyte1)
{
chari;
for(i=8;i>0;i--)
{
DS1302_IO=(bit)(byte1&0x01);
DS1302_CLK=1;
_nop_();
DS1302_CLK=0;
byte1>>=1;
}
return;
}
//读DS1302一个字节//
unsignedcharoutputbyte(void)
{
unsignedchari;
unsignedcharucdat=0;
for(i=8;i>0;i--)
{
DS1302_IO=1;
ucdat>>=1;
if(DS1302_IO)ucdat|=0x80;
DS1302_CLK=1;
_nop_();
DS1302_CLK=0;
}
return(ucdat);
}
//向DS1302某地址写一个字节数据//