|
lcd1602+ds1302+ds18b20
当1602显示18b20检测到的温度的时候,1302的时日月显示会清零
如果不显示18b20,1302可以正常显示
一开始刚弄好的时候是正常的,隔了几天就变成这样子了
附上效果图
代码部分:
1602+主函数
#include <reg51.H>
#include "DS1302.h"
#include "DS18B20.h"
#include "key.h"
#include "alarm.h"
#define DATAPORT P0
sbit RS=P2^6; //控制端口定义
sbit RW=P2^5;
sbit E =P2^7;
void delayMs(unsigned int x) //延时函数
{
unsigned char a=200;
for(;x>0;x--)
{
while(--a);
a=200;
}
}
void LCDSTA() //判断液晶显示器是否在忙
{
unsigned char flag;
while(1)
{
RS=0; //RS RW为0 1 为读Busy Flag(DB7)及地址计数器AC(DB0~DB6)
RW=1;
delayMs(5); //延时
E=1; //E控制端产生一个脉冲
delayMs(10);
flag=DATAPORT; //读取端口状态
E=0;
flag=flag&0x80; //读取液晶忙碌标志位BF,即DB7
if(flag==0x00) //为真表示液晶忙完,可以对其进行操作,否则需要等待
break;
}
}
void WRDcomm(unsigned char com) //向LCD发送操作命令
{
LCDSTA(); //判断液晶屏是否在忙,如果通不过,采用延时替换
//delay(4000);
DATAPORT = com; //发送命令
RS=0;
RW=0;
E=1; //E控制产生一个脉冲
delayMs(10);
E=0;
delayMs(10); //等待执行完操作
}
void WRData(unsigned char Data) //向LCD发送操作数据
{
LCDSTA(); //判断液晶屏是否在忙,如果通不过,采用延时替换
DATAPORT=Data;
RS=1;
RW=0;
E=1; //E控制产生一个脉冲
delayMs(10);
E=0;
delayMs(10); //等待执行完操作
}
void lcd_initial() //液晶屏初始化子程序
{
WRDcomm(0x01);
WRDcomm(0x38);
WRDcomm(0x0c);
WRDcomm(0x06);
}
void main()
{
lcd_initial(); //调用液晶初始化函数
delayMs(20);
Ds1302Init();
delayMs(20);
DS18B20_Init();
while(1)
{
DS1302ReadTime();
DS1302_Display();
DS18B20_Display(DS18B20_Read_Temperture());
}
}
ds1302
#ifndef _DS1302_H_
#define _DS1302_H_
#include <reg51.h>
#include <intrins.h>
/***********************************************
外部函数调用
***********************************************/
extern void WRDcomm(unsigned char com);
extern void WRData(unsigned char Data);
/***********************************************
I/O定义
***********************************************/
sbit sclk=P3^6;
sbit io=P3^4;
sbit rst=P3^5;
/***********************************************
DS1302初值显示
***********************************************/
//---DS1302时钟初始化2013年1月1日星期二12点00分00秒。---//
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
unsigned char time[7]={0,0x03, 0x22, 0x27, 0x04, 0x04, 0x17}; //存放1302初始时间
unsigned char write_register[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
unsigned char read_register[7] ={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
/***********************************************
函数名:DS1302_Write_Byte
功能:向DS1302写入一字节数据
***********************************************/
void DS1302_Write_Byte(unsigned char address,unsigned char indata)
{
unsigned char i;
rst=0;
_nop_();
sclk=0;
_nop_();
rst=1;
_nop_();
for(i=0;i<8;i++)
{
sclk=0;
io=address&0x01;
address>>=1;
sclk=1;
}
for(i=0;i<8;i++)
{
sclk=0;
io=indata&0x01;
indata>>=1;
sclk=1;
}
rst=0;
_nop_();
io=1;
sclk=1;
}
/***********************************************
函数名:DS1302_Read_Byte
功能:向DS1302读取一字节数据
***********************************************/
unsigned char DS1302_Read_Byte(unsigned char address)
{
unsigned char i;
unsigned char dat,dat1;
rst=0;
_nop_();
sclk=0;
_nop_();
rst=1;
_nop_();
for(i=0;i<8;i++)
{
io=address&0x01;
address>>=1;
sclk=1;
_nop_();
sclk=0;
_nop_();
}
for(i=0;i<8;i++)
{
dat1=io;
dat=(dat>>1)|(dat1<<7);
sclk=1;
_nop_();
sclk=0;
_nop_();
}
rst=0;
_nop_();
sclk=1;
_nop_();
io=0;
_nop_();
io=1;
_nop_();
return dat;
}
/***********************************************
函数名:DS1302_Init
功能:初始化DS1302
***********************************************/
void Ds1302Init()
{
unsigned char i;
DS1302_Write_Byte(0x8E,0X00); //禁止写保护,就是关闭写保护功能
for (i=0; i<7; i++)//写入7个字节的时钟信号:分秒时日月周年
{
DS1302_Write_Byte(write_register[i],time[i]);
}
DS1302_Write_Byte(0x8E,0x80); //打开写保护功能
}
/*******************************************************************************
函 数 名:DS1302ReadTime
函数功能:读取时钟信息
*******************************************************************************/
void DS1302ReadTime()
{
unsigned char i;
for (i=0; i<7; i++)//读取7个字节的时钟信号:分秒时日月周年
{
time[i] = DS1302_Read_Byte(read_register[i]);
}
}
/*******************************************************************************
* 函数名 : DS1302_Display
* 函数功能 : 显示函数
*******************************************************************************/
void DS1302_Display()
{
WRDcomm(0xc0);
WRData('0'+time[2]/16); //时
WRData('0'+(time[2]&0x0f));
WRData(':');
WRData('0'+time[1]/16); //分
WRData('0'+(time[1]&0x0f));
WRData(':');
WRData('0'+time[0]/16); //秒
WRData('0'+(time[0]&0x0f));
WRDcomm(0x80);
WRData('2');
WRData('0');
WRData('0'+time[6]/16); //年
WRData('0'+(time[6]&0x0f));
WRData('-');
WRData('0'+time[4]/16); //月
WRData('0'+(time[4]&0x0f));
WRData('-');
WRData('0'+time[3]/16); //日
WRData('0'+(time[3]&0x0f));
WRData(0x8D);
//WRData('0'+(time[5]&0x07)); //星期
switch('0'+time[5]&0x07)
{
case 1 : //星期一
{
WRData('M');
WRData('0'+1);
break;
}
case 2 : //星期二
{
WRData('T');
WRData('0'+2);
break;
}
case 3 : //星期三
{
WRData('w');
WRData('0'+3);
break;
}
case 4 : //星期四
{
WRData('T');
WRData('0'+4);
break;
}
case 5 : //星期五
{
WRData('F');
WRData('0'+5);
break;
}
case 6 : //星期六
{
WRData('S');
WRData('0'+6);
break;
}
case 7 : //星期天
{
WRData('S');
WRData('0'+7);
break;
}
}
}
#endif
18b20
#ifndef _DS18B20_H_
#define _DS18B20_H_
#include <reg51.h>
/***********************************************
外部函数调用
***********************************************/
extern void WRDcomm(unsigned char com);
extern void WRData(unsigned char Data);
/*************************************************
I/O定义
*************************************************/
sbit DQ=P3^7;
/*************************************************
函数名:delay1ms
功能:延时,精确至1毫秒
*************************************************/
void delay1ms(unsigned char x)
{
unsigned int i;
for(;x>0;x--)
for(i=110;i>0;i--);
}
/*************************************************
函数名:delay15us
功能:延时,精确至15微秒
*************************************************/
void delay15us(unsigned char x)
{
unsigned char i;
for(;x>0;x--)
for(i=5;i>0;i--);
}
/*************************************************
函数名:DS18B20_Init
功能:18B20初始化,根据返回值判断18B20是否正常工作
*************************************************/
unsigned char DS18B20_Init()
{
unsigned int i;
DQ=0; //将总线拉低480us~960us
i=70;
while(i--);//延时642us
DQ=1; //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
i=0;
while(DQ) //等待DS18B20拉低总线
{
i++;
if(i>5000)//等待>5MS
return 0;//初始化失败
}
return 1;//初始化成功
}
/*************************************************
函数名:DS18B20_Write_Byte
功能:向18B20写入一个字节
*************************************************/
void DS18B20_Write_Byte(unsigned char dat)
{
unsigned char i,j;
for(i=0;i<8;i++)
{
DQ=0;
j++;
// delay15us(2); //最少延时15us
DQ=dat&0x01;
// delay15us(5); //最少延时60us
j=6;
while(j--);
DQ=1;
dat>>=1;
}
}
/*************************************************
函数名:DS18B20_Read_Byte
功能:向18B20读取一个字节
*************************************************/
unsigned char DS18B20_Read_Byte()
{
unsigned char i,j;
unsigned char temp; //存放每一位数据
unsigned char byte; //用于返回字节
for(i=0;i<8;i++)
{
DQ=0;
j++;
// delay15us(1); //最少延时1us
DQ=1;
// delay15us(1); //最少延时10us
j++;
j++;
temp=DQ;
byte=(byte>>1)|(temp<<7);
// delay15us(3); //最少延时45us
j=4;
while(j--);
}
return byte;
}
/*************************************************
函数名:DS18B20_Change_Time
功能:将检测的温度转换成数字量
*************************************************/
void DS18B20_Change_Time()
{
DS18B20_Init();
delay1ms(1);
DS18B20_Write_Byte(0xcc);
DS18B20_Write_Byte(0x44);
delay1ms(10);
}
/*************************************************
函数名:DS18B20_Read_Temperture_Com
功能:温度传感器读取数据
*************************************************/
void DS18B20_Read_Temperture_Com()
{
DS18B20_Init();
delay1ms(1);
DS18B20_Write_Byte(0xcc);
DS18B20_Write_Byte(0xbe);
}
/*************************************************
函数名:DS18B20_Read_temperture
功能:温度读取
*************************************************/
int DS18B20_Read_Temperture()
{
unsigned char lowtemp,hightemp;
int temp=0;
DS18B20_Change_Time();
delay1ms(10);
DS18B20_Read_Temperture_Com();
lowtemp=DS18B20_Read_Byte();
hightemp=DS18B20_Read_Byte();
temp=hightemp;
temp<<=8;
temp|=lowtemp;
return temp;
//delay1ms(5000);
}
/*************************************************
函数名:DS18B20_Display
功能:温度显示
*************************************************/
void DS18B20_Display(int temp)
{
float tp;
if(temp<0)
{ WRDcomm(0xc9);
WRData('-');
temp=temp-1;
temp=~temp;
tp=temp;
temp=tp*0.0625*100+0.5;
}
else
{
tp=temp;
temp=tp*0.0625*100+0.5;
}
time[9]=temp % 10000 / 1000;
time[10]=temp % 1000 / 100;
time[11]=temp % 100 / 10;
WRDcomm(0xca);
WRData('0'+time[9]);
WRDcomm(0xcb);
WRData('0'+time[10]);
WRDcomm(0xcc);
WRData('.');
WRDcomm(0xcd);
WRData('0'+time[11]);
WRData(0xdf);
WRData('C');
}
#endif
|
|