温度时钟测距lcd1602显示程序


#include "reg52.h"
#include "intrins.h"
#define uint unsigned int
#define uchar unsigned char
sbit DS1302_CLK = P2^1; //实时时钟时钟线引脚
sbit DS1302_IO = P2^2; //实时时钟数据线引脚
sbit DS1302_RST = P2^7; //实时时钟复位线引脚
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
sbit DQ = P2^0; //温度传送数据IO口
sbit voice=P2^3;
sbit Trig = P3^6;
sbit Echo = P3^3;
uchar hide_sec,hide_min,hide_hour,hide_day,hide_month,hide_year; //秒,分,时到日,月,年位闪的计数
uchar temp,addr,timel,timeh,temp_value,temp1_value,a;
uchar TempBuffer[5],max_temp[4],min_temp[4],Distance[3];
///////////////////超声波模块/////////////////////////
void delay(uint xms)
{
uint x,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--);
}

void delay_20us()
{
uint a;
for(a=100;a>0;a--);
}

void init()
{
EA=1;
Trig=0;
IT1=1;
}

void chaoshengbo()
{
float time;
uchar distance;
EA=0;
Trig=1;
delay_20us();

Trig=0;
while(Echo==0);
a=0;
EA=1;
EX1=1;
TH2=0;
TL2=0;
TF2=0;
TR2=1;
delay(20);
EA=0;
EX1=0;
if(a==1)
{
time=timeh*256+timel;
distance=time*0.017;

}
else
distance=0;

Distance[0]=distance/100+'0';
Distance[1]=distance%100/10+'0';
Distance[2]=distance%10+'0';
}

void show_time(); //液晶显示程序
///////////////////////////////////////////////////
/***********1602液晶显示部分子程序****************/
///////////////////////////////////////////////////
//Port Definitions**********************************************************
sbit LcdRs = P2^5;
sbit LcdRw = P2^6;
sbit LcdEn = P2^4;
sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
void delay_key(uint a)
{
uint b;
for(b=0;b}
//向LCD写入命令或数据********************************************************
void LCD_Write(bit style, uchar input)
{
LcdRs=style;
LcdRw=0;
P0=input;
delay_key(10);
LcdEn=1;
delay_key(10);
LcdEn=0;
}

//设置显示模式************************************************************
void LCD_SetDisplay(unsigned char DisplayMode)
{
LCD_Write(0, 0x08|DisplayMode);
}

void LCD_SetInput(unsigned char InputMode)
{
LCD_Write(0, 0x04|InputMode);

}
//初始化LCD************************************************************
void LCD_Initial()
{
LcdEn=0;
LCD_Write(0,0x38); //8位数据端口,2行显示,5*7点阵
LCD_Write(0,0x38);
LCD_SetDisplay(0x04|0x00); //开启显示, 无光标
LCD_Write(0,0x01); //清屏
LCD_SetInput(0x02|0x00); //AC递增, 画面不动
}

//液晶字符输入的位置************************
void GotoXY(unsigned char x, unsigned char y)
{
if(y==0)
LCD_Write(0,0x80|x);
if(y==1)
LCD_Write(0,0x80|(x-0x40));
}

//将字符输出到液晶显示
void Print(unsigned char *str)

{
while(*str!='\0')
{
LCD_Write(1,*str);
str++;
}
}
///////////////////////////////////////////////////
/***********DS1302时钟部分子程序******************/
///////////////////////////////////////////////////
typedef struct __SYSTEMTIME__
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char DateString[11];
unsigned char TimeString[9];
}SYSTEMTIME; //定义的时间类型
SYSTEMTIME CurrentTime,ad_CurrentTime;


void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数)
{
unsigned char i;
ACC = d;
for(i=8; i>0; i--)
{
DS1302_IO = ACC0; //相当于汇编中的 RRC
DS1302_CLK = 1;
DS1302_CLK = 0;
ACC = ACC >> 1;
}
}

unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数)
{
unsigned char i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相当于汇编中的 RRC
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
return(ACC);
}

void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr); // 地址,命令
DS1302InputByte(ucDa); // 写1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0;
}

unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据
{
unsigned char ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr|0x01); // 地址,命令
ucData = DS1302OutputByte(); // 读1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0;
return(ucData);
}

void DS1302_GetTime(SYSTEMTIME *Time) //获取时钟芯片的时钟数据到自定义的结构型数组
{
unsigned char ReadValue;
ReadValue = Read1302(0x80);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(0x82);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(0x84);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(0x86);
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(0x88);
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(0x8c);
Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
}

void DateToStr(SYSTEMTIME *Time) //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]
{ if(hide_year<2) //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22
{
Time->DateString[0] = '2';
Time->DateString[1] = '0';
Time->DateString[2] = Time->Year/10 + '0';
Time->DateString[3] = Ti

me->Year%10 + '0';
}
else
{
Time->DateString[0] = ' ';
Time->DateString[1] = ' ';
Time->DateString[2] = ' ';
Time->DateString[3] = ' ';
}
Time->DateString[4] = '/';
if(hide_month<2)
{
Time->DateString[5] = Time->Month/10 + '0';
Time->DateString[6] = Time->Month%10 + '0';
}
else
{
Time->DateString[5] = ' ';
Time->DateString[6] = ' ';
}
Time->DateString[7] = '/';
if(hide_day<2)
{
Time->DateString[8] = Time->Day/10 + '0';
Time->DateString[9] = Time->Day%10 + '0';
}
else
{
Time->DateString[8] = ' ';
Time->DateString[9] = ' ';
}


Time->DateString[10] = '\0'; //字符串末尾加 '\0' ,判断结束字符
}

void TimeToStr(SYSTEMTIME *Time) //将时,分,秒数据转换成液晶显示字符放到数组 TimeString[];
{ if(hide_hour<2)
{
Time->TimeString[0] = Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour%10 + '0';
}
else
{
Time->TimeString[0] = ' ';
Time->TimeString[1] = ' ';
}
Time->TimeString[2] = ':';
if(hide_min<2)
{
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute%10 + '0';
}
else
{
Time->TimeString[3] = ' ';
Time->TimeString[4] = ' ';
}
Time->TimeString[5] = ':';
if(hide_sec<2)
{
Time->TimeString[6] = Time->Second/10 + '0';
Time->TimeString[7] = Time->Second%10 + '0';
}
else
{
Time->TimeString[6] = ' ';
Time->TimeString[7] = ' ';
}
Time->DateString[8] = '\0';
}

void Initial_DS1302(void) //时钟芯片初始化
{
Write1302(0x8e,0x00); //写入允许
Write1302(0x8c,0x12); //以下写入初始化时间 日期:07/07/25.星期: 3. 时间: 23:59:55
Write1302(0x88,0x10);
Write1302(0x86,0x04);
Write1302(0x8a,0x3);
Write1302(0x84,0x18);
Write1302(0x82,0x12);
Write1302(0x80,0x33);
Write1302(0x8e,0x80); //禁止写入
}

void ad_DS1302(void) //时钟芯片初始化
{
Write1302(0x8e,0x00); //写入允许
Write1302(0x8c,(ad_CurrentTime.Year/10)<<4|(ad_CurrentTime.Year%10)); //以下写入初始化时间 日期:07/07/25.星期: 3. 时间: 23:59:55
Write1302(0x88,(ad_CurrentTime.Month/10)<<4|(ad_CurrentTime.Month%10));
Write1302(0x86,(ad_CurrentTime.Day/10)<<4|(ad_CurrentTime.Day%10));
Write1302(0x84,(ad_CurrentTime.Hour/10)<<4|(ad_CurrentTime.Hour%10));
Write1302(0x82,(ad_CurrentTime.Minute/10)<<4|(ad_CurrentTime.Minute%10));
Write1302(0x80,(ad_CurrentTime.Second/10)<<4|(ad_CurrentTime.Second%10));
Write1302(0x8e,0x80); //禁止写入
}
//////////////////////////////////////////////////////////
/********************ds18b20子程序***********************/
//////////////////////////////////////////////////////////

/***********ds18b20延迟子函数(晶振12MHz )*******/

void delay_18B20(unsigned int i)
{
while(i--);
}

/**********ds18b20初始

化函数**********************/

void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay_18B20(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay_18B20(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay_18B20(14);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay_18B20(20);
}

/***********ds18b20读一个字节**************/

unsigned char ReadOneChar(void)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}

/*************ds18b20写一个字节****************/

void WriteOneChar(uchar dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18B20(5);
DQ = 1;
dat>>=1;
}
}

/**************读取ds18b20当前温度************/

void ReadTemp(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned char t=0;

Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换

delay_18B20(100); // this message is wery important

Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度

delay_18B20(100);

a=ReadOneChar(); //读取温度值低位
b=ReadOneChar(); //读取温度值高位
temp_value=b<<4;
temp_value+=(a&0xf0)>>4;
temp1_value=a&0x0f;
}
void temp_to_str() //温度数据转换成液晶字符显示
{
TempBuffer[0]=temp_value/10+'0'; //十位
TempBuffer[1]=temp_value%10+'0'; //个位
TempBuffer[2]='.';
TempBuffer[3]=temp1_value*625/1000%10+'0';
TempBuffer[4]=0xdf; //温度符号
TempBuffer[5]='C';
TempBuffer[6]='\0';
}
//===============上下限温度初始化===================
void max_temp_value() //上限
{
max_temp[0]='3'; //十位
max_temp[1]='5'; //个位
max_temp[2]='.';
max_temp[3]='0';
}
void min_temp_value() //下限
{
min_temp[0]='1'; //十位
min_temp[1]='5'; //个位
min_temp[2]='.';
min_temp[3]='0';
}
//**********************************************
//延时子程序模块
//**********************************************
void mdelay(uint delay)
{ uint i;
for(;delay>0;delay--)
{for(i=0;i<70;i++) //1ms延时.
{;}
}
}
void show_time() //液晶显示程序
{
DS1302_GetTime(&CurrentTime); //获取时钟芯片的时间数据
TimeToStr(&CurrentTime); //时间数据转换液晶字符
DateToStr(&CurrentTime); //日期数据转换液晶字符
ReadTemp(); //开启温度采集程序
temp_to_str(); //温度数据转换成液晶字符
GotoXY(10,1); //液晶字符显示位


Print(TempBuffer); //显示温度
GotoXY(0,1);
Print(CurrentTime.TimeString); //显示时间
GotoXY(0,0);
Print(CurrentTime.DateString); //显示日期
GotoXY(13,0);
Print(Distance); //显示超声波测到的距离
GotoXY(11,0);
Print("s="); //在液晶上显示 字母s
mdelay(500); //扫描延时
}

//==================警报声,分长短音================
void alarm_voice(uchar i)
{
uchar n;
if(i==0)
{
n=8;
for(;n>0;n--)
{
DS1302_GetTime(&CurrentTime); //获取时钟芯片的时间数据
TimeToStr(&CurrentTime); //时间数据转换液晶字符
DateToStr(&CurrentTime); //日期数据转换液晶字符
ReadTemp(); //开启温度采集程序
temp_to_str(); //温度数据转换成液晶字符
GotoXY(10,1); //液晶字符显示位置
Print(TempBuffer); //显示温度
GotoXY(0,1);
Print(CurrentTime.TimeString); //显示时间
GotoXY(0,0);
Print(CurrentTime.DateString); //显示日期
GotoXY(15,0);
voice=~voice;
}
}
else if(i==1)
{
n=20;
for(;n>0;n--)
{
DS1302_GetTime(&CurrentTime); //获取时钟芯片的时间数据
TimeToStr(&CurrentTime); //时间数据转换液晶字符
ReadTemp(); //开启温度采集程序
temp_to_str(); //温度数据转换成液晶字符
GotoXY(10,1); //液晶字符显示位置
Print(TempBuffer); //显示温度
GotoXY(0,1);
Print(CurrentTime.TimeString); //显示时间
voice=~voice;
}
}
}
///////////////////////////////////////////////////
/*****************主函数**************************/
///////////////////////////////////////////////////
void main()
{
uchar num;
uchar code table[]=" Welcome To SCAU ";
uchar code table1[]="We Will Win" ;
float Current_temp,max_temp_count,min_temp_count;
LCD_Initial(); //液晶初始化
Init_DS18B20( ) ; //DS18B20初始化
Initial_DS1302(); //时钟芯片初始化
max_temp_value(); //上限
min_temp_value(); //下限
init();
LCD_Write(0,0x80+0x10);
for(num=0;num<16;num++)
{
LCD_Write(1,table[num]);
delay_key(50);
}
LCD_Write(0,0x80+0x53);
for(num=0;num<11;num++)
{
LCD_Write(1,table1[num]);
delay_key(50);
}
for(num=0;num<16;num++)
{
LCD_Write(0,0x18);
delay_key(25000);
}
delay_key(60000);
delay_key(60000);
//******************正常时间温度显示***************************
while(1)
{
chaoshengbo();
LCD_Write(0, 0x01);
LCD_SetDisplay(0x04|0x00);
show_time(); //液晶显示数据
Current_temp=TempBuffer[0]*10+TempBuffer[1]+TempBuffer[3]/10;
max_temp_count=max_temp[

0]*10+max_temp[1]+max_temp[3]/10;
min_temp_count=min_temp[0]*10+min_temp[1]+min_temp[3]/10;
if(Current_temp>=max_temp_count)
alarm_voice(1);
else
if(Current_temp<=min_temp_count)
alarm_voice(0);
}
}

void time1() interrupt 2
{
TR2=0;//关定时器
ET2=0;
a=1; //置位标志位
timeh=TH2;//把计时值放入缓冲
timel=TL2;
}

void time2() interrupt 5
{
TH2=0;
TL2=0;
}


相关文档
最新文档