#include
#include
#include
#include "lcd.h"
#define uchar unsigned char
#define uint unsigned int
sfr DQ = 0x80; //DS18B20连接在单片机的P0口
sbit LIGHT = P2^7; //灯报警标志P2^7口
sbit P3_6=P3^6; //引脚定义,继电器控制端
uchar PLUS = 0x01;
uchar MINUS = 0xFE;
uchar temp1;
unsigned char xx;
bit mode=0,work=0;
int ALARM_TH = 0x32; //报警温度上限值,50摄氏度
int ALARM_TL = 0x00; //报警温度下限值,0摄氏度
int temp_minus,temp_plus,temp,xiaoshu,xiaoshu1,xiaoshu2;
int temp_value = 0; //DS18B20 读出的温度值
void Temp_write(uchar wbyte); //写DS18B20 一个字节
void Temp_bcd(void);
void Temp_convert(void); //温度转换开始命令
void delay15us(uchar n); //延时15us倍数的程序
int Temp_read(void); //读DS18B20 一个字节
void read_temp(void); //读出温度值子程序
void Temp_reset(void);
extern int abs(int val); //温度值为零下时取绝对值
void display_temperature(void);
void send_temperature(void);
void date_time(void);
void com_initialize(void);
void delay1ms(unsigned int x); //函数声明
void set_adj(void); //函数声明
void inc_key(void); //函数声明
void dec_key(void); //函数声明
//****************************************************************************
void delay1ms(unsigned int x) //delay x*1ms
{
unsigned char j;
while((x--)!=0)
{for(j=0;j<125;j--)
{;}
}
}
//*****************************************************************************按键操作子程序
//****************************************************************************
void key(void)
{
P2=0xff;
if(P2!=0xff)
{delay1ms(10);
if(P2!=0xff)
{
xx=P2;
switch(xx)
{
case 0xfe:{set_adj();break;} //"MS"键按下,调用set_adj()子函数
case 0xfd:{inc_key();break;} //"+"键按下,调用inc_key()子函数
case 0xfb:{dec_key();break;} //"-"键按下,调用dec_key()子函数
case 0xf7:{//ON_OFF=!ON_OFF;/
work=0;
temp1=10;
init_LCD();
//clear_LCD();
gotoxy(1,1); //设置显示位置
display_LCD_string("Init_T: "); //显示初使温度
display_LCD_number(10);
write_LCD_data(223);
display_LCD_string("C");
break;
}
default:break;
}
}
}
}
//*****************************************************************************void set_adj(void) //模式设置子函数
{ mode=!mode;
delay1ms(5000);
if(mode==0)
{P3_6=0; //启动制冷
init_LCD();
gotoxy(1,1);
display_LCD_string("Pre_temp:");
display_LCD_number(temp1);
write_LCD_data(223);
display_LCD_string("C");
delay1ms(5000);
}
if(mode==1)
{init_LCD();
gotoxy(1,1);
display_LCD_string("Please Set:");
delay1ms(5000);
}
}
//****************************************************************************
void inc_key(void) //按键加法子函数
{
if(mode==1)
{temp1++;
init_LCD();
gotoxy(1,1);
display_LCD_string("Set_T: ");
display_LCD_number(temp1);
write_LCD_data(223);
display_LCD_string("C");
delay1ms(9000);
}
}
//****************************************************************************
void dec_key(void) //按键减法子函数
{
if(mode==1)
{temp1--;
init_LCD();
//clear_LCD();
gotoxy(1,1);
display_LCD_string("Set_T: ");
display_LCD_number(temp1);
write_LCD_data(223);
display_LCD_string("C");
delay1ms(9000);
}
}
//****************************************************************************
void delay15us(uchar n)
{
do
{ _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
--n;
}while(n);
return;
}
//****************************************************************************
*温度检测子程序
//****************************************************************************
void Temp_reset(void)
{
uchar i;
bit flag = 0; //flag为初始化完成(1)标志
while(~flag)
{
DQ = MINUS; //主机拉低单线480us
delay15us(40); //产生复位脉冲
DQ = PLUS; //上拉电阻拉高单线60us
delay15us(4); //延时60us
while(DQ & PLUS) //等待DS18B20应答,拉低总线
;
while(~(DQ | MINUS)) //DQ线被拉低以产生应答信号
{
flag = 1; //初始化完成
for(i = 0; i < 25; ++i) //延时200us
{;}
break; //完成复位操作
}
}
DQ = PLUS;
return;
}
//****************************************************************************
*完成二进制到BCD码的转换
//****************************************************************************
void Temp_bcd(void)
{
temp_plus = temp_value;
if(temp_plus & 0xf800) //温度值为负,求其补码
{ gotoxy(2,7); //温度为负时,因最大可测量零下55摄氏度即百位可用来显示负号
display_LCD_string('-');
temp_minus = abs((int) temp_plus); //温度的绝对值
//求出小数位的值
xiaoshu1 = (temp_minus & 0x000f)*10/16; //小数第一位
xiaoshu2 = (temp_minus & 0x000f)*100/16%10; //小数第二位
xiaoshu=xiaoshu1*10+xiaoshu2;
temp_minus >>= 4; //余下整数值
temp_value=temp_minus;
if(temp_minus >= ALARM_TH || temp_minus < ALARM_TL )
//温度高于ALARM_TH,或者低于ALARM_TL即报警
{ LIGHT = 1; } //报警,正常显示温度
else { LIGHT = 0; } //不报警,正常显示温度
}
else //温度为正时,百位可用来显示百位的数值
{ //求出小数位的值
xiaoshu1 = (temp_plus & 0x000f)*10/16; //小数第一位
xiaoshu2 = (temp_plus & 0x000f)*100/16%10; //小数第二位
xiaoshu=xiaoshu1*10+xiaoshu2;
temp_plus >>= 4; //余下整数值
temp_value=temp_plus;
if(temp_plus >= ALARM_TH || temp_plus < ALARM_TL )
//温度高于ALARM_TH,或者低于ALARM_TL即报警
{LIGHT = 1; } //报警,正常显示温度
else {LIGHT = 0; } //不报警,正常显示温度
}
temp=temp_value;
return;
}
//****************************************************************************
void Temp_convert(void)
{
Temp_reset(); //复位DS18B20
Temp_write(0xcc); //跳过读64位ROM序列号命令,用于单线接系统 [Skip ROM] [CCH]
Temp_write(0x44); //启动DS18B20进行温度转换 [Convert T] [44H]
return;
}
//*****************************************************************************int Temp_read(void)
{
uchar i,j,rbyte;
rbyte = 0;
for(i = 0; i < 8; ++i)
{ DQ = MINUS; //DQ保持低电平2us
_nop_();_nop_();
DQ = PLUS;
//将DQ拉高15us以上。P1口在作为输入时必须先写"1",截止场效应管
delay15us(1);
j = (DQ & PLUS);
delay15us(4); //读时隙不低于60us
rbyte = (j << 7) | (rbyte >> 1); //每读一位,即右移一位,将新读的位放入最高位
}
_nop_(); //读时隙间隔至少1us
return(rbyte);
}
/*****************************************************************************
void read_temp(void)
{
uchar temp_lsb,temp_msb;
Temp_reset(); //复位DS18B20
Temp_write(0xcc); //跳过读64位ROM序列号命令,用于单线接系统 [Skip ROM] [CCH]
Temp_write(0xbe); //读暂存器 [Read Scratchpad] [BEH]
temp_lsb = Temp_read(); //读出低字节
temp_msb = Temp_read(); //读出高字节
temp_value = (((uint)temp_msb) << 8) + temp_lsb; //计算(256*高字节+低字节)
return;
}
//****************************************************************************
void Temp_write(uchar wbyte)
{
uchar i;
for(i = 0; i < 8; ++i)
{
DQ = MINUS;
DQ = wbyte & 0x01;
delay15us(6); //写时隙延时90us [Write Time Slots]
DQ = PLUS; //拉高总线
wbyte >>= 1; //取下一位(由低位到高位),每写入一位,把字节右移一位
_nop_(); //每写一位最少间隔1us
}
return;
}
//****************************************************************************
*温度显示子函数
//****************************************************************************
void display_temperature()
{ gotoxy(2,0);
display_LCD_string("Temper:");
gotoxy(2,7);
display_LCD_number(temp_value); //LCD显示温度
display_LCD_string(".");
display_LCD_number(xiaoshu); //LCD显示温度
write_LCD_data(223);
display_LCD_string("C");
}
//****************************************************************************
*主函数
//****************************************************************************
void main(void)
{ P3=0x0FF;
LIGHT = 0; //默认不报警,不亮
PLUS = 0x01;
MINUS = 0xFE;
init_LCD();
//clear_LCD();
gotoxy(1,2);
display_LCD_string("**Hello**"); //欢迎信息显示
while(1)
{
Temp_convert(); //发转换命令
read_temp(); //读温度
Temp_bcd(); //温度值转换
display_temperature();
key();
if(temp_value<=temp1)
{P3_6=1;//关闭制冷
init_LCD();
gotoxy(1,1);
display_LCD_string("Pre_temp OK!!");
work=1;
}
if(work==1)
{if(temp_value>temp1)
{P3_6=0; //开启制冷
init_LCD();
gotoxy(1,1);
display_LCD_string("Pre_temp:");
display_LCD_number(temp1);
write_LCD_data(223);
display_LCD_string("C");
delay1ms(5000);
work=0;}
}
}
}
(3)显示子程序
#include
#include
char code int2charLCD[]="0123456789";
void write_LCD_command(unsigned command) //将命令写入LCM模块
{
rw=WRITE;
rs=COMMAND;
enable=ENABLE;
P1=command;
delay1ms(2);
enable=DISABLE;
rw=1;
}
void write_LCD_data(unsigned LCDdata) //将数据写入LCM模块
{
rw=WRITE;
rs=DATA;
enable=ENABLE;
P1=LCDdata;
delay1ms(2);
enable=DISABLE;
rw=1;
}
void init_LCD(void) //对LCM模块进行初始化
{
write_LCD_command(TwoLine_8bit); // 0x38
write_LCD_command(CURSOR_OFF); // 0x0C
write_LCD_command(CURSOR_RIGHT); // 0x06
}
void clear_LCD() //清除LCM的显示屏
{
write_LCD_command(CLEAR); // Ox01,清屏
write_LCD_command(CURSOR_HOME); // ox02,光标返回原点
}
void display_LCD_string(char *p) //对LCM模块显示字符串
{
while(*p)
{
write_LCD_data(*p);
p++;
}
}
void display_LCD_number(char number) //对LCM模块显示数字
{
unsigned char x,y;
x=number/10;
y=number%10;
write_LCD_data(int2charLCD[x]);
write_LCD_data(int2charLCD[y]);
}
void gotoxy(unsigned x,unsigned y) //设置光标位置
{
if(x==1)
write_LCD_command(GOTO_LINE_1+y);
else
write_LCD_command(GOTO_LINE_2+y);
}