51单片机DS18B20+DS1302+LCD12864实时显示时间日期温度

文章目录

    • 介绍
    • Proteus仿真运行效果
    • 源程序
      • 主函数
      • DS1302时钟函数
      • DS18B20函数
      • LCD12864(不带字库)
      • sharing函数
      • mine头文件

介绍

DS18B20采集温度
DS1302时钟当前时间
LCD12864作为显示(不带字库)
第一行显示年月日
第二行显示时分秒
第三行显示星期
第四行显示温度

Proteus仿真运行效果

仿真运行视频

源程序

主函数

#include
#include 
#include "mine.h"
void main()
{ 
	InitLCD();
	ds18b20Init();
	ds18b20Start();
	delayxms(1000);
	while(1)
	{
		ds1302ReadTimeDate();
		Show();
	}
}

DS1302时钟函数

#include "mine.h"
#include "intrins.h"
uchar ReadAddr[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; 
uchar WriteAddr[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
uchar NowTimeDate[7];
/*写字节*/
void ds1302WriteByte(uchar addr,uchar dat)
{
	uchar i=0;
	RST=0;_nop_();	
	CLK=0;_nop_();
	RST=1;_nop_();
	for(i=0;i<8;i++)//先写低位再写高位
	{
		IO=addr&0x01;
		addr>>=1;
		CLK=1;
		_nop_();
		CLK=0;
		_nop_();		
	}
	for(i=0;i<8;i++)
	{
		IO=dat&0x01;
		dat>>=1;
		CLK=1;_nop_();
		CLK=0;_nop_();		
	}
	RST=0;_nop_();	
}
/*读字节*/
uchar ds1302ReadByte(uchar addr)
{
	uchar i=0,temp=0,value=0;
	RST=0;_nop_();	
	CLK=0;_nop_();
	RST=1;_nop_();
	for(i=0;i<8;i++)
	{
		IO=addr&0x01;
		addr>>=1;	
		CLK=1;_nop_();
		CLK=0;_nop_();		
	}
	for(i=0;i<8;i++)
	{
		temp=IO;
		value=(temp<<7)|(value>>1);
		CLK=1;_nop_();
		CLK=0;_nop_();		
	}
	RST=0;_nop_();	
	CLK=1;_nop_();
	IO = 0;_nop_();
	IO = 1;_nop_();	
	return value;		
}
/*ds1302初始化,可自己写入初始时间,不写入则同步电脑的*/
void ds1302_init()
{
//	uchar i=0;
//	ds1302_write_byte(0x8E,0X00);
//	for(i=0;i<7;i++)
//	{
//		ds1302_write_byte(gWRITE_RTC_ADDR[i],gDS1302_TIME[i]);	
//	}
	ds1302WriteByte(0x8E,0X80);	
}
/*读取时间和日期*/
void ds1302ReadTimeDate()
{
	uchar i=0;
	for(i=0;i<7;i++)
	{
		NowTimeDate[i]=ds1302ReadByte(ReadAddr[i]);	
	}	
}
/*显示*/
void Show()
{
	int Tempture; 
  uchar i;
	uchar Time[5],Date[8];
	uint Bai,Shi;
	/*把时间取出来并显示*时*分*秒*/
	Time[0]=NowTimeDate[2]/16;Time[1]=NowTimeDate[2]&0x0f;
	Time[2]=NowTimeDate[1]/16;Time[3]=NowTimeDate[1]&0x0f;
	Time[4]=NowTimeDate[0]/16;Time[5]=NowTimeDate[0]&0x0f;
	for(i=4;i<6;i++)
  DisplayZf(2,2,(i+1)*8,Time[i]);
	for(i=0;i<2;i++)
	DisplayHz(1,2,i*16,i+2);
	DisplayZf(1,2,32,10);
	DisplayZf(1,2,56,Time[0]);
	DisplayZf(2,2,0,Time[1]);
	DisplayZf(2,2,8,10);
	for(i=2;i<4;i++)
	DisplayZf(2,2,i*8,Time[i]);
	DisplayZf(2,2,32,10);
	/*把日期取出来并显示*年*月*日*/
	Date[0]=2;Date[1]=0;
	Date[2]=NowTimeDate[6]/16;Date[3]=NowTimeDate[6]&0x0f;
	Date[4]=NowTimeDate[4]/16;Date[5]=NowTimeDate[4]&0x0f;
	Date[6]=NowTimeDate[3]/16;Date[7]=NowTimeDate[3]&0x0f;
	Date[8]=NowTimeDate[5]&0x0f;
	for(i=0;i<2;i++)
	DisplayHz(1,0,i*16,i+4);
	DisplayZf(1,0,32,10);
	for(i=0;i<3;i++)
	DisplayZf(1,0,(i+5)*8,Date[i]);
	DisplayZf(2,0,0,Date[3]);
	DisplayZf(2,0,8,12);
	for(i=4;i<6;i++)
	DisplayZf(2,0,(i-2)*8,Date[i]);
	DisplayZf(2,0,32,12);
	for(i=6;i<8;i++)
	DisplayZf(2,0,(i-1)*8,Date[i]);
	/*读星期并显示出来*/
	DisplayHz(1,4,0,6);
	DisplayHz(1,4,16,5);
	DisplayZf(1,4,32,10);
	DisplayHz(2,4,8,6);
	DisplayHz(2,4,24,5);
  DisplayXingQi(2,4,40,Date[8]-2);
	/*读温度并显示出来*/
	Tempture=ds18b20ReadTemperture()*10;
	 if(Tempture<0)
	 {
	   Tempture=-Tempture;
		 DisplayZf(2,6,16,12);
	 }
	 else 
	 {
		 DisplayZf(2,6,16,11);
	 }
	 Bai=Tempture/100;Shi=(Tempture%100)/10;
	/******温度:*.*°*C*********/
	 for(i=0;i<2;i++)  
		 DisplayHz(1,6,i*16,i);
   DisplayZf(1,6,32,10);
	 DisplayZf(2,6,24,Bai);
	 DisplayZf(2,6,32,Shi);
	 DisplayZf(2,6,40,14);
	 DisplayZf(2,6,48,15);
}

DS18B20函数

#include
#include "mine.h"
/***************复位**********/
void ds18b20Reset()
{
 DQ=0;delay10us(75);//拉低DQ,750us(480~960)
 DQ=1;delay10us(2);//DQ=1,20US(15~60)
}
/*******检测18b20是否存在**********/
uchar ds18b20Check()
{
	uchar time_temp=0;
	while(DQ&&time_temp<20)	//等待DQ为低电平,如果一直高电平且超过200us退出,
	{time_temp++;delay10us(1);}
	if(time_temp>=20)return 1;//ds18b20没有响应
	else time_temp=0;//检测到ds18b20
	while((!DQ)&&time_temp<20)
	{time_temp++;delay10us(1);}
	if(time_temp>=20)return 1;	//如果超时则强制返回1
	return 0;//检测到响应
}
/*********温度读取(一位)**********/
uchar ds18b20ReadBit()
{
	uchar dat=0;
	DQ=0;_nop_();_nop_();
	DQ=1;_nop_();_nop_();
	if(DQ)dat=1;	//读1
	else dat=0;//读0
	delay10us(5);
	return dat;
} 
/*******温度读取(一个字节)**********/
uchar ds18b20ReadByte()
{
	uchar i=0,dat=0,temp=0;
	for(i=0;i<8;i++)//循环8次,每次读取一位,且先读低位再读高位
	{
		temp=ds18b20ReadBit();dat=(temp<<7)|(dat>>1);//temp左移7位或上dat右移1位
	}
	return dat;	
}
/*******温度写入(一个字节)**********/
void ds18b20WriteByte(uchar dat)
{
	uchar i=0,temp=0;
	for(i=0;i<8;i++)//循环8次,每次写一位,且先写低位再写高位
	{
		temp=dat&0x01;//取出低位,选择低位准备写入
		dat>>=1;//将次高位移到低位右移
		if(temp)
		{
			DQ=0;_nop_();_nop_();
			DQ=1;delay10us(6);//至少60us
		}
		else
		{
		DQ=0;delay10us(6);
		DQ=1;_nop_();_nop_();	
		}	
	}	
}
void ds18b20Start()
{
  ds18b20Reset();//复位
	ds18b20Check();//检查DS18B20
	ds18b20WriteByte(0xcc);//SKIP ROM
  ds18b20WriteByte(0x44);//转换命令	
}
uchar ds18b20Init()
{
	ds18b20Reset();
	return ds18b20Check();	
}
/***********温度读取*********/
float ds18b20ReadTemperture()
{
	float temp;
	uchar datH=0,datL=0;
	uint value=0;
	ds18b20Start();//开始转换
	ds18b20Reset();//复位
	ds18b20Check();
	ds18b20WriteByte(0xcc);//SKIP ROM
  ds18b20WriteByte(0xbe);//读存储器
	datL=ds18b20ReadByte();//低字节
	datH=ds18b20ReadByte();//高字节
	value=(datH<<8)+datL;//合并为16位数据
	if((value&0xf800)==0xf800)//0xf800(1111 1000 0000 0000)判断符号位,负温度(前五位正负后五位温度)
	{
	value=(~value)+1; //数据取反再加1
	temp=value*(-0.0625);//乘以精度	
	}
	else //正温度
	{
	temp=value*0.0625;	
	}
	return temp;
}

LCD12864(不带字库)

#include
#include "mine.h"
uchar code Hzk[]=
{
	/***********************************温*****************************************/
	0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
	0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,
	/***********************************度*****************************************/
	0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
	0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00,
	/***********************************时*****************************************/
	0x00,0xFC,0x84,0x84,0x84,0xFC,0x00,0x10,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0x00,
  0x00,0x3F,0x10,0x10,0x10,0x3F,0x00,0x00,0x01,0x06,0x40,0x80,0x7F,0x00,0x00,0x00,
	/***********************************间*****************************************/
	0x00,0xF8,0x01,0x06,0x00,0xF0,0x12,0x12,0x12,0xF2,0x02,0x02,0x02,0xFE,0x00,0x00,
  0x00,0xFF,0x00,0x00,0x00,0x1F,0x11,0x11,0x11,0x1F,0x00,0x40,0x80,0x7F,0x00,0x00,
	/***********************************日*****************************************/
  0x00,0x00,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0xFF,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x00,0x00,0x00,0x00,
	/***********************************期*****************************************/
	0x00,0x04,0xFF,0x24,0x24,0x24,0xFF,0x04,0x00,0xFE,0x22,0x22,0x22,0xFE,0x00,0x00,
  0x88,0x48,0x2F,0x09,0x09,0x19,0xAF,0x48,0x30,0x0F,0x02,0x42,0x82,0x7F,0x00,0x00,
 /***********************************星*****************************************/
	0x00,0x00,0x00,0xBE,0x2A,0x2A,0x2A,0xEA,0x2A,0x2A,0x2A,0x3E,0x00,0x00,0x00,0x00,
  0x00,0x44,0x42,0x49,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x49,0x41,0x40,0x00,0x00,
	/*****************************宋体小四(64*64)********************************/
};

uchar code Zfk[]=
{
	/**************************************0~9************************************/
	0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,
	0x00,0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,
	0x00,0x70,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,
	0x00,0x30,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x18,0x20,0x21,0x21,0x22,0x1C,0x00,
	0x00,0x00,0x80,0x40,0x30,0xF8,0x00,0x00,0x00,0x06,0x05,0x24,0x24,0x3F,0x24,0x24,
	0x00,0xF8,0x88,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x20,0x20,0x20,0x11,0x0E,0x00,
	0x00,0xE0,0x10,0x88,0x88,0x90,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x20,0x1F,0x00,
	0x00,0x18,0x08,0x08,0x88,0x68,0x18,0x00,0x00,0x00,0x00,0x3E,0x01,0x00,0x00,0x00,
	0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,
	0x00,0xF0,0x08,0x08,0x08,0x10,0xE0,0x00,0x00,0x01,0x12,0x22,0x22,0x11,0x0F,0x00,
	/**********************************:,+,-,.,°,C,~*********************************/
	0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x0F,0x01,0x01,0x01,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x02,0x02,0x04,0x02,0x00,
	
};
code XingQi[]=
{
	0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00,
	0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,
	0x00,0x04,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x04,0x00,0x00,
	0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,	
	0x00,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x00,0x00,
	0x00,0x7F,0x28,0x24,0x23,0x20,0x20,0x20,0x20,0x21,0x22,0x22,0x22,0x7F,0x00,0x00,
	0x00,0x02,0x42,0x42,0x42,0xC2,0x7E,0x42,0x42,0x42,0x42,0xC2,0x02,0x02,0x00,0x00,
	0x40,0x40,0x40,0x40,0x78,0x47,0x40,0x40,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x00,
	0x20,0x20,0x20,0x20,0x20,0x20,0x21,0x22,0x2C,0x20,0x20,0x20,0x20,0x20,0x20,0x00,
	0x00,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x01,0x02,0x04,0x18,0x60,0x00,0x00,
	0x00,0x00,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0xFF,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x00,0x00,0x00,0x00,
};
/*检查是否忙*/
void busy()		
{uchar dat;
 rs=0;rw=1; 
 do{
	 P0=0x00;
   e=1;	
	 dat=P0;
   e=0;
   dat=0x80 & dat; 
   }while(!(dat==0x00));
}
/*写数据到LCD中*/
void W_Data(uchar dat)
{
  busy();
	rs=1;rw=0;
	P0=dat;
	e=1;e=0;
}
/*写命令到LCD中*/
void W_Cmd(uchar cmd)
{
  busy();
	rs=0;rw=0;
	P0=cmd;
	e=1;e=0;
}
/*设置页(8行为一页,共64行即8页(0~7页)*/
void S_Page(uchar page)
{
  page=0xb8|page;//只有0~7页
	W_Cmd(page);
}
/*起始行*/
void S_StartHang(uchar hang)
{
  hang=0xc0|hang;
	W_Cmd(hang);
}
/*设定列*/
void S_Lie(uchar lie)
{
  lie=lie&0x3f;//lie&(0011 1111),列大于63自动从零列
	lie=0x40|lie;
	W_Cmd(lie);
}
/*开(关)显示*/
void S_OnOff(uchar onoff)
{
  onoff=0x3e|onoff;//(0011 1110)|onoff,0关1开
	W_Cmd(onoff);
}
/*屏幕选择*/
void S_Screen(uchar screen)
{ 
	switch(screen)
	{
	case 0:cs1=0;cs2=0;break;//全屏
	case 1:cs1=0;cs2=1;break;//左屏
	case 2:cs1=1;cs2=0;break;//右屏
	}
}
/*清屏*/
void ClS(uchar screen)
{
  uchar i,j;
	S_Screen(screen);//选择清除那个屏
	for(i=0;i<8;i++)
	{
	S_Page(i);
	S_Lie(0);
	for(j=0;j<64;j++)
	W_Data(0x00);
	}
}
/*初始化*/
void InitLCD()
{
  busy();
	S_Screen(0);S_OnOff(0);
	S_Screen(0);S_OnOff(1);
	S_Screen(0);ClS(0);
	S_StartHang(0);
}
/*显示*/
void DisplayHz(uchar s,uchar page,uchar lie,uchar number)
{int i;	
 S_Screen(s);
 lie=lie&0x3f;
 S_Page(page);S_Lie(lie);
 for(i=0;i<16;i++)  
	W_Data(Hzk[i+32*number]);//显示汉字上半部分
 S_Page(page+1);S_Lie(lie);	  
 for(i=0;i<16;i++)	  
	W_Data(Hzk[i+32*number+16]);//显示汉字下半部分
} 
void DisplayZf(uchar s,uchar page,uchar lie,uchar number)
{
	int i;
	S_Screen(s);
	lie=lie&0x3f;
	S_Page(page);S_Lie(lie);
	for(i=0;i<8;i++)  
		W_Data(Zfk[i+16*number]);
	S_Page(page+1);S_Lie(lie);	  
	for(i=8;i<16;i++)	  
		W_Data(Zfk[i+16*number]);
}
void DisplayXingQi(uchar s,uchar page,uchar lie,uchar number)
{int i;	
 S_Screen(s);
 lie=lie&0x3f;
 S_Page(page);S_Lie(lie);
 for(i=0;i<16;i++)  
	W_Data(XingQi[i+32*number]);//显示汉字上半部分
 S_Page(page+1);S_Lie(lie);	  
 for(i=0;i<16;i++)	  
	W_Data(XingQi[i+32*number+16]);//显示汉字下半部分
} 

sharing函数

#include
#include "mine.h"
void T0_init()
{
	TMOD=0x01;//设置定时器0
	TH0=0x3c;//装初值
	TL0=0xb0;
	EA=1;//开总中断
	ET0=1;//开定时器0中断
	TR0=1;//启动定时器0
}
void delay10us(uint us)
{
	while(us--);	
}
void delayxms(uint x)
{
	uint i,j;
	for(i=0;i<x;i++)
	for(j=0;j<110;j++);
}

mine头文件

#ifndef _MINE_H          
#define _MINE_H
#include
#define uint unsigned int
#define uchar unsigned char
/**************************************ds18b20模块声明*******************************
复位*检查是否存在*读一位*读一个字节*写一个字节*开始读温度*初始*读温度并转换*显示温度*
************************************************************************************/
void ds18b20Rest();
uchar ds18b20Check();
uchar ds18b20ReadBit();
uchar ds18b20ReadByte();
void ds18b20WriteByte(uchar dat);
void ds18b20Start();
uchar ds18b20Init();
float ds18b20ReadTemperture();
void TemptureDisplay();
sbit DQ=P3^3;
/*************************LCD12864模块声明**************************
查忙*写数据*写命令*设定页数(共四行八页0~7)*起始行*列数(64列0~63)****
开关*清屏*初始化*显示汉字(16*16(宽*高))*显示字符(8*16(宽*高))*
*******************************************************************/
void busy();
void W_Data(uchar dat);
void W_Cmd(uchar cmd);	
void S_Page(uchar page);
void S_StartHang(uchar hang);
void S_Lie(uchar lie);
void S_OnOff(uchar onoff);
void S_Screen(uchar screen);
void ClS(uchar screen);
void InitLCD();
void DisplayHz(uchar s,uchar page,uchar lie,uchar number);
void DisplayZf(uchar s,uchar page,uchar lie,uchar number);
void DisplayXingQi(uchar s,uchar page,uchar lie,uchar number);
sbit rs=P2^0;
sbit rw=P2^1;
sbit e=P2^2;
sbit cs1=P2^3;
sbit cs2=P2^4;
/**************************************ds1302模块声明*******************************
初始化*读时间日期*写字节*
************************************************************************************/
//变量声明
void ds1302_init();
void ds1302ReadTimeDate();
void ds1302WriteByte(uchar addr,uchar dat);
extern uchar NowTimeDate[7];//存储时间日期
sbit RST=P1^2;
sbit CLK=P1^1;
sbit IO=P1^0;
/***********共用模块声明*********
定时器T0初始化*延时10us*延时xms*/
void T0_init();
void delay10us(uint us);
void delayxms(uint x);
#endif

有无大佬知道怎么把取得字模数据能存放到独立的文件里

你可能感兴趣的:(记录单片机学习,单片机,嵌入式硬件)