- #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]);
- }
復制代碼
這是網友的程序 求解 |