本文包含原理图、PCB、源代码、封装库、中英文PDF等资源
您需要 登录 才可以下载或查看,没有账号?注册会员
×
1602用四线驱动+DS1302+DS18B20+89C52构成的带温度时钟
1602用四线驱动+DS1302+DS18B20+89C52构成的带温度时钟
/*=====================================================
用YJD1602四线驱动+DS1302+DS18B20+89C52构成的带温度时钟
P0^0=接YJD1602的 4脚 RS
P0^1=接YJD1602的 5脚 RW
P0^2=接YJD1602的 6脚 EN
P0^4=接YJD1602的11脚 D4
P0^5=接YJD1602的12脚 D5
P0^6=接YJD1602的13脚 D6
P0^7=接YJD1602的14脚 D7
程序编写:LBQ691477940???? 23-01-2011?? 16:30
======================================================*/
#include <reg52.h>
#include <intrins.h>
#define nop _nop_()
#define PtData P0??//定义连接口线
#define uint unsigned int
#define uchar unsigned char
sbit BF = P0^7;//判断LCM是否忙
sbit rs=P0^0;//接YJD1602的4脚
sbit rw=P0^1;//接YJD1602的5脚
sbit en=P0^2;//接YJD1602的6脚
sbit DQ=P2^7;
sbit spk=P2^3;
sbit a0=ACC^0;
sbit a1=ACC^1;
sbit a2=ACC^2;
sbit a3=ACC^3;
sbit a4=ACC^4;
sbit a5=ACC^5;
sbit a6=ACC^6;
sbit a7=ACC^7;
sbit k1=P1^7;????//调整模式????????
sbit k2=P1^6;????//+按钮
sbit k3=P1^5;????//-按钮
sbit k4=P1^4;
sbit clock_clk =P2^2;//ds1302_clk(时钟线7)
sbit clock_dat =P2^1;//ds1302_dat(数据线6)
sbit clock_Rst =P2^0;//ds1302_Rst(复位线5)
uint??idata tdat;????????//温度值变量
char idata sett;????????//模式计数变量
char tflag;????????????//温度正负标志
char idata disp_buf1[16];//1602显示缓冲区1(即上排16个字符)
char idata disp_buf2[16];//1602显示缓冲区2(即下排16个字符)
char idata timedata[7];//存放时间值变量
uchar code table[]=" YJD1602??CLOCK ";
char idata temdata[5];????//存放温度值变量
uchar i;
uchar code self_dat[]={????????????????????????
????0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,????????//一,代码 0x04
????0x00,0x00,0x00,0x0e,0x00,0xff,0x00,0x00,????????//二,代码 0x05
????0x00,0x00,0xff,0x00,0x0e,0x00,0xff,0x00,????????//三,代码 0x06
????0x00,0x00,0xff,0xf5,0xfb,0xf1,0xff,0x00,???????? //四,代码 0x07
????0x00,0xfe,0x08,0xfe,0x0a,0x0a,0xff,0x00,????????//五,代码 0x08
????0x00,0x04,0x00,0xff,0x00,0x0a,0x11,0x00,????????//六,代码 0x09
????0x00,0x1f,0x11,0x1f,0x11,0x11,0x1f,0x00};????????//日,代码 0x0a};//自定义字符
//************LCD相关函数**********************************//
void delay(uint n)????????//延时时间为n*1ms
{????uchar x=0;
????for(;n>0;n--)
????{
????????for(;x<250;x++)
????????{
????????????nop;
????????????nop;
????????????nop;
????????????nop;
????????}
????}
}
//=======================================================================*/
void check_busy()????//LCD忙检测函数
????{
????????BF=1;
????????rs=0;
????????rw=1;????????
????????en=0;
????????en=0;
????????en=1;
????????while(BF);????????????
????}
//----------------------------------------------------------------------
//送控制指令程序
void W_LCD1(uchar Temp,q)
????{????
????????uchar Temp1,Temp2;
????????check_busy();
????????Temp1=PtData&0x0f;
????????Temp2=(Temp&0xf0);
????????PtData=(Temp2|Temp1);//和P0口的控制一起送回P0口
????????rw=0;
????????if(q)
????????????{
????????????????rs=1;
????????????????goto as;
????????????}
????????rs=0;
as:????????
????????nop;
????????en=1;
????????nop;
????????nop;
????????en=0;
????????Temp2=(Temp<<4);//左移四位
????????Temp2&=0xf0;
????????Temp1=PtData&0x0f;
????????PtData=(Temp2|Temp1);//和P0口的控制一起送回P0口
????????if(q)
????????????{
????????????????rs=1;
????????????????goto ad;
????????????}
????????rs=0;
ad:????????
????????nop;
????????en=1;
????????nop;
????????nop;
????????en=0;
????}
//=======================================================================????
void self_data()????//写入自定义字符
{
????uchar i=0;
????W_LCD1(0x06,0); //设定地址指针加一
????W_LCD1(0x48,0); //装入自定义字符的起始地址(CGRAM)
????for(;i<64;i++)????????
????????W_LCD1(self_dat,1);
}
void lcd_init()???? //初始化
{??
????PtData=0xff;
????W_LCD1(0x28,0);??//8位,双列,5*7
????//lcd_wcom(0x38);??//8位,双列,5*7
????W_LCD1(0x0c,0);??//开显示,关光标,光标所在字符不闪烁
????W_LCD1(0x06,0);???? //显示地址递增
????W_LCD1(0x01,0);???? //清屏,光标移到左上角
????self_data();
}
/*------------------------------------------------------------------------
//***********DS18B20相关函数*******************/
void delay_18b20(uint sum)
{
????while(sum--);
}
void rst_18b20()???????????????? //复位
{????//uchar flag;
????DQ=1;
????delay_18b20(8);
????DQ=0;
????delay_18b20(80);
????DQ=1;
????delay_18b20(13);
????//flag=DQ;
????//return(flag);
????delay_18b20(20);
}????
void wr_18b20(uchar dat)????//写一个字节的数据
{
????uchar i=8;
????for(;i>0;i--)
????{
????????DQ=0;
????????DQ=dat&0x01;
????????delay_18b20(5);
????????DQ=1;
????????dat>>=1;
????}????
}
uchar rd_18b20()????????//读一个字节的数据
{
????uchar dat=0,i=8;
????for(;i>0;i--)
????{
????????DQ=0;
????????dat>>=1;
????????DQ=1;
????????if(DQ)
????????dat|=0x80;
????????delay_18b20(4);
????}
????return(dat);
}
uint rd_temperature()????????//读取温度值,返回值为uint型,占两个字节
{????
????uchar a=0,b=0;
????uint t=0;
????float tt=0;
????rst_18b20();????????//复位
????wr_18b20(0xcc);????????//跳过ROM
????wr_18b20(0x44);????????//启动温度转换
????rst_18b20();????????//再次对18B20操作时,需要重新复位一次
????wr_18b20(0xcc);????????//跳过ROM
????wr_18b20(0xbe);????????//读取内部RAM的内容
????a=rd_18b20();????????//读温度值低位(内部RAM的第0个字节)
????b=rd_18b20();????????//读温度值高位(内部RAM的第1个字节)
????t=b;
????t<<=8;????????????????//温度值高位放在t的高8位
????t=t|a;????????????????//温度值低位放在t的低8位
????if(t<0x0fff)????????//判断温度值为正还是负
?????????? tflag=0;????????//tflag=0温度值为正
????else
?? {
????????t=~t+1;????????????//温度值为负,负值以补码存放,这里要将其还原为原码
????????tflag=1;????????//tflag=1温度值为负
?? }
????tt=t*0.0625;
????t= tt*10;????????????//放大10倍精确到一位小数
????return(t);????
}
//***********************************************//
uchar disp_self(uchar i)???????? //判断自定义字符是第几个
{????????
????switch(i)
????{
????????case 1:i=1;break;
????????case 2:i=2;break;
????????case 3:i=3;break;
????????case 4:i=4;break;
????????case 5:i=5;break;
????????case 6:i=6;break;
????????case 7:i=7;break;
????????default : break;
????}
????return(i);
}
void tem_conv()
????????????{????????
????????????????uchar flagdat ;//定义温度值符号
????????????????if(tflag==0)
????????????????temdata[4]=flagdat=0x20;//正温度不显示符号
?????????????????? else
???????????????? temdata[4]=flagdat=0x2d;//负温度显示负号:-
???????????????? temdata[0]=tdat/1000+0x30;//温度百位值
???????????????? temdata[1]=tdat%1000/100+0x30;//温度十位值
???????????????? temdata[2]=tdat%100/10+0x30;//温度个位值
???????????????? temdata[3]=tdat%10+0x30;//温度小数位值
????????????????if(temdata[0]==0x30)
????????????????????{temdata[0]=0x20;//如果百位为0,不显示
?????????????????????????? if(temdata[1]==0x30)
????????????????????????{
????????????????????????????temdata[1]=0x20;//如果百位为0,十位为0也不显示
????????????????????????}
?????????????????????? }????????????????
??????????????}
void beeper(uchar i)???? //蜂鸣器
{
????uchar j;
????for(j=i;j>0;j--)
????{????????????
????????spk=0;
????????delay(200);
????????spk=~spk;
????????delay(200);????????
????}
}
void int_display()??//初始显示
{
????uchar m=0;
????lcd_init();
????W_LCD1(0x80,0);??????????????//显示地址
????for(m=0;m<16;m++)
????????{
????????????W_LCD1(table[m],1); //将数组中字符显示出来
????????????delay(1000);??????????
????????}????????
????????delay(10);????
????????beeper(2);
????????W_LCD1(0x01,0);????????
}
//********************************************//
void updata_disp()????????????????//更新缓冲区数据程序
{
????disp_buf1[0]='2';
????disp_buf1[1]='0';
????disp_buf1[2]=timedata[6]/16+0x30;
????disp_buf1[3]=timedata[6]%16+0x30;
????disp_buf1[4]='/'; |