DS18B20采集温度
DS1302时钟当前时间
LCD12864作为显示(不带字库)
第一行显示年月日
第二行显示时分秒
第三行显示星期
第四行显示温度
仿真运行视频
#include
#include
#include "mine.h"
void main()
{
InitLCD();
ds18b20Init();
ds18b20Start();
delayxms(1000);
while(1)
{
ds1302ReadTimeDate();
Show();
}
}
#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);
}
#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;
}
#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]);//显示汉字下半部分
}
#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++);
}
#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
有无大佬知道怎么把取得字模数据能存放到独立的文件里