- #include<reg52.h>
- #include"stdio.h"
- typedef unsigned char uint8;
- typedef unsigned int uint16;
- /***************************************************/
- sbit RS =P2^6; //LCD1602的数据命令选择
- sbit RW = P2^5;
- sbit EN_LCD =P2^7; //LCD1602的使能信号
- sbit BUZZER = P1^5;
- sbit K1 = P3^0; //右
- sbit K2 = P3^1; //加
- sbit K3 = P3^2; //减
- /****************DS18B20引脚**********************/
- sbit DS18B20 = P3^7; //DS18B20数据端
- /***********************************************************/
- /******************************************************/
- void delay(uint16 time); // 延时函数(6us单位)
- void lcd_ini(); // LCD1602的初始化
- void lcd_order(uint8 date); // 向LCD1602的写1个指令
- void lcd_data(uint8 date); // 向LCD1602的写1个指令
- void xie1602(uint8 add,uint8 daa); //写数据
- void xianshi1();//显示温度
- uint8 ds18_ini(); //ds18B20初使化函数
- void ds18_write(uint8 date); //功能向DS18B20中写入一个数据
- uint8 ds18_read(); //功能从DS18B20中读出一个数据并返回。
- void ds18_check(); //起动DS18B20行进温度采集,并返回当前温度(tmp)
- void xiugai(); //修改报警范围
- long tmp=0; //储存温度值
- long t_h=37, t_l=10; // 温度的上限和下限
- bit tmp_hb = 0; tmp_lb = 0; //温度上下限调节指示变量
- void panduan(); //判断报警
- uint8 hodometer[]= " H:00 L: 00 ";
- uint8 temp[]= " wendu:00.00 ";
- uint16 ji = 0;
- uint8 ku=0; //biaozhiwei
- void main()
- {
- lcd_ini();
- ds18_ini(); //ds18B20初使化
- ds18_write(0xcc); //跳过序列号
- ds18_write(0x44); //启动温度转换
- xie1602(4,t_h);
- xie1602(12,t_l);
- while(1)
- {
- ds18_check(); //从DS18B20中读出温度
- xianshi1();
- xiugai();
- panduan();
- }
- }
- void xie1602(uint8 add,uint8 daa)
- {
- lcd_order(0x80+add);
- lcd_data(0x30+daa/10);
- lcd_data(0x30+daa%10);
- }
- //判断是否在报警范围内
- void panduan()
- {
- if(tmp<(t_l*1000)||tmp>(t_h*1000)&&t_l>=0)
- {
- BUZZER = 0;
- delay(10);
- }
- else if(t_l<0&&tmp>(t_h*1000))
- {
- BUZZER = 1;
- }
- else
- BUZZER = 1;
- }
- //选择修改的内容
- void xiugai()
- { uint8 jj;
- uint8 i = 0;
- BUZZER = 1;
-
- if(K1==0)
- {
- while(!K1);
- while(1)
- {
- lcd_order(0x0f); //开启光标显示
- lcd_order(0x80+5);//光标显示位置
- if(K2 == 0) //判断加按键按下
- {
- while(K2 == 0); //等待按键释放
- t_h++; //温度上限加1
- xie1602(4,t_h); //将温度上限显示出来
- }
- if(K3 == 0) //判断减按键按下
- {
- while(K3 == 0); //等待按键释放
- if(t_h>t_l) //判断 温度上限大于温度下限
- t_h--;
- xie1602(4,t_h); //将温度上限显示出来
- }
- if(K1 == 0) //后面的注释类似
- {
- while(K1 == 0);
- while(1)
- {
- lcd_order(0x0f);
- lcd_order(0x80+13);
- if(K2 == 0)
- {
- while(K2 == 0);
- if(t_l<t_h&&t_l>=0)
- {
- lcd_order(0x80+11);
- lcd_data(' ');
- t_l++;
- xie1602(12,t_l);
- }
- else {
- t_l++;
- jj = ~t_l;
- xie1602(12,jj);
- }
- }
- if(K3 == 0)
- {
- while(K3 == 0);
- if(t_l>(-50))
- {
- t_l--;
- if(t_l<0)
- jj = ~t_l;
- }
- if(t_l>=0)
- {
- lcd_order(0x80+11);
- lcd_data(' ');
- xie1602(12,t_l);
- }
- if(t_l<0)
- {
- xie1602(12,jj);
- lcd_order(0x80+11);
- lcd_data('-');
- }
- }
- if(K1 == 0)
- {
- while(K1 == 0);
- goto loop;
- }
- }
- }
- }
- }
- loop:BUZZER = 1;
- }
- /**********************************************
- 函数名:delay
- 行参 :time 延时基数
- 功能 :用while延时
- ************************************************/
- // 延时函数(1ms单位)
- void delay(uint16 time)
- {
- while(time--);
- }
- /**********************************************
- 函数名:lcd_ini
- 功能 :LCD1602的初始化
- ************************************************/
- void lcd_ini()
- {
- uint8 i;
- RW = 0;
- lcd_order(0x38); //设置1602的显示光标功能
- delay(100);
- lcd_order(0x0e); //显示开及光标设置
- delay(100);
- lcd_order(0x06); //显示光标移动设置
- delay(100);
- lcd_order(0x01); //显示清屏
- delay(100);
- lcd_order(0x80);
- for(i = 0;i<16;i++)
- lcd_data(hodometer[i]);
- }
- /**********************************************
- 函数名:lcd_order
- 行参 :date 要定入的指令
- 功能 :向LCD1602的写1个指令
- ************************************************/
- void lcd_order(uint8 date)
- {
- RS=0; //选择写指令
- EN_LCD=0; //使能初使化
- P0=date; //发送指令
- EN_LCD=1; //开使能
- delay(100); //延时
- EN_LCD=0; //关使能
- }
- /**********************************************
- 函数名:lcd_order
- 行参 :date 要定入的指令
- 功能 :向LCD1602的写1个指令
- ************************************************/
- void lcd_data(uint8 date)
- {
- RS=1; //选择写数据
- EN_LCD=0; //使能初使化
- P0=date; //发送指令
- EN_LCD=1; //开使能
- delay(100); //延时
- EN_LCD=0; //关使能
- }
- /*************************************************************
- DS18B20
- **************************************************************/
- /****************************************
- 函数名: ds18_ini
- 功能: 对DS18B20进行初使化,
- 若DS18B20是好的则返回1
- 若DS18B20是环的则返回0
- ****************************************/
- //ds18B20初使化函数,可根据资料上的时序来写
- uint8 ds18_ini()
- {
- uint8 ans;
- DS18B20 = 1;
- delay(1);
- DS18B20 = 0;
- delay(100);
- DS18B20 = 1;
- delay(6);
- ans = DS18B20;
- delay(100);
- if(!ans)
- return 1;
- else
- return 0;
- }
- /**********************************
- 函数名: ds18_write
- 函数行参: date(向ds18b20写入的数据)
- 功能: 功能向DS18B20中写入一个数据
- ***********************************/
- void ds18_write(uint8 date)
- {
- uint8 i;
- DS18B20=1;
- delay(1);
- for(i=0;i<8;i++) //根据时序将数据从低到高一位一位发送出来
- {
- DS18B20 = 0;
- if(date&0x01) //从低到高取出数据的每位
- DS18B20 = 1;
- else
- DS18B20 = 0;
- delay(10);
- DS18B20 = 1;
- date>>=1;
- delay(1);
-
- }
- }
-
- /*************************************************
- 函数名: ds18_read
- 函数返回值:rate(从ds18b20中读出的数据)
- 功能: 功能从DS18B20中读出一个数据并返回。
- *************************************************/
- uint8 ds18_read()
- {
- uint8 i,date = 0;
- DS18B20 = 1; //释放总线
- delay(1);
- for(i = 0;i < 8;i ++) //根据时序将数据从低到高一位一位接收
- {
-
- DS18B20 = 0;
- date >>= 1;
- DS18B20 = 1;
- if(DS18B20)
- date |= 0x80; //将date的一位置1
- delay(8);
- DS18B20 = 1;
- delay(1);
-
- }
- return date; //返回读出的数
- }
- /************************************************************
- 函数名: ds18_check
- 函数返回值: tmp(当前温度)
- 功能: 起动DS18B20行进温度采集,并返回当前温度(tmp)
- *************************************************************/
- void ds18_check()
- {
- uint8 date1,date2;
- float ta;
- if(ds18_ini())
- {
-
- ds18_write(0xcc); //跳过序列号
- ds18_write(0x44); // 启动温度转换
- ds18_ini(); // 复位
- ds18_write(0xcc); //跳过序列号
- ds18_write(0xbe); // 启动读取温度
- date1 = ds18_read(); //读取两个温度字节
- date2 = ds18_read();
- tmp=date2;
- tmp<<=8;
- tmp=tmp|date1;
- ta=tmp*0.0625;
- tmp=ta*1000;
- }
-
- }
- void xianshi1()
- {
- uint8 i;
- temp[8]=0x30+tmp/10000;
- temp[9]=0x30+tmp/1000%100;
- temp[11]=0x30+tmp/100%100;
- temp[12]=0x30+tmp/10%100;
- temp[13]=0x30+tmp%10;
- lcd_order(0x80+0x40);
- for(i = 0;i<16;i++)
- lcd_data(temp[i]);
- }
复制代码
这是网友的程序 求解 |