本帖最后由 mnbvcxzlkjhgfds 于 2018-7-21 16:25 編輯
論壇里下載無數個>都試過>只有這個設置完控制溫度(拔掉5v電源時)還有記憶功能>不錯
因為0.0時電源開關會打開>有時18B20會接觸不良引起意外
我只會下載和燒錄>不懂編寫>只求好心人改>有hex文件當然最好
#include<reg52.h> //頭文件
#include<intrins.h>
#include "DS18b20.H"
#include "eeprom52.h"
#include "Nixie tube.h"
#define uchar unsigned char //宏定義
#define uint unsigned int
uchar code ss[]=
{
0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90
}; //數碼管
uchar code ss1[]=
{
0x40,0x79,0x24,0x30,0x19,
0x12,0x02,0x78,0x00,0x10,
0xc7,0x89,0xbf //0xc7=L 0x89=H 0xbf=- 負號
}; //0-9為帶小數點的
uchar ms; //定時器0計數
sbit key1=P3^4;
sbit key2=P3^5;
sbit key3=P3^3;
sbit led_0=P1^0; //上限溫度報警燈
sbit led_2=P1^2; //下限溫度報警燈
char H,L; //用于設置上下限度 上下限度與要比較的數據類型最好相同
uchar flag;
sbit beep=P1^6; //蜂鳴器
bit s0,beep_1=1; //s0用于閃爍標志 beep_1用于在中斷里改變蜂鳴器工作狀態
int temp,i; //存儲讀出來的溫度,與H,L上下限度數據類型相同
void delay(uint T)
{
while(T--);
}
void display()
{
if(flag==0&&temp>=0) //溫度為正數時執行
{
if(temp>999) Nixietube(ss[temp/1000%10],ss[temp/100%10],ss1[temp/10%10],ss[temp%10]);
if(temp>99) Nixietube(0xff,ss[temp/100%10],ss1[temp/10%10],ss[temp%10]);
if(temp<99&&temp/100%10<=0) Nixietube(0xff,0xff,ss1[temp/10%10],ss[temp%10]);
}
if(flag==0&&temp<0) //溫度為負數時
{
if(temp*-1/100%10<=0) Nixietube(0xff,ss1[12],ss1[temp*-1/10%10],ss[temp*-1%10]);
if(temp*-1/100%10>0) Nixietube(ss1[12],ss[temp*-1/100%10],ss1[temp*-1/10%10],ss[temp*-1%10]);
}
if(flag==1) //flag==0顯示溫度 =1 顯示上限 =2 顯示下限
{
if(H>99) Nixietube(ss1[11],ss[H/100],ss[H%100/10],ss[H%10]); //溫度范圍是125~-55 ,當上限值大于99時執行
if(H>=10&&H<=99) Nixietube(ss1[11],0xff,ss[H/10],ss[H%10]); //當上限值大于12小于99時執行 不顯示最高位
if(H<10&&H>=0) Nixietube(ss1[11],0xff,0xff,ss[H%10]); //不顯示百位 十位
if(H<0&&H>=-9) Nixietube(ss1[11],0xff,ss1[12],ss[H*-1%10]); //設置的為負數且介于0~-9之間時執行 不顯示十位
if(H<0&&H<-9) Nixietube(ss1[11],ss1[12],ss[H*-1%100/10],ss[H*-1%10]); //最低可以到55
}
if(flag==2) //同上
{
if(L>99) Nixietube(ss1[10],ss[L/100],ss[L%100/10],ss[L%10]);
if(L>=10&&L<=99) Nixietube(ss1[10],0xff,ss[L/10],ss[L%10]);
if(L<10&&L>=0) Nixietube(ss1[10],0xff,0xff,ss[L%10]);
if(L<0&&L>=-9) Nixietube(ss1[10],0xff,ss1[12],ss[L*-1%10]);
if(L<0&&L<-9) Nixietube(ss1[10],ss1[12],ss[L*-1%100/10],ss[L*-1%10]);
}
}
void key() //按鍵處理
{
if(!key1) //設置上限
{
delay(500);
if(!key1)
{
while(!key1);
if(flag==1)
{
if(H<125)H++;
SectorErase(0x2000); //每修改一次上下限數據就寫進EEROM
byte_write(0x2000,H);
}
else if (flag==2)
{
if(L<H-1) L++; //原則是下限不超過上限
SectorErase(0x2200);
byte_write(0x2200,L);
}
}
}
if(!key2) //設置下限
{
delay(500);
if(!key2)
{
while(!key2);
if(flag==1)
{
if(H>L+1) H--; //原則上限不低于下限
SectorErase(0x2000); //每修改一次上下限數據就寫進EEROM
byte_write(0x2000,H);
}
else if (flag==2)
{
if(L>-55)L--;
SectorErase(0x2200);
byte_write(0x2200,L);
}
}
}
if(!key3) //設置上限下限切換按鍵
{
delay(1000);
if(!key3)
{
while(!key3);
flag=(flag+1)%3;
}
}
}
void alarm() //報警
{
if(temp/10>=H||temp/10<=L) //超過上下限蜂鳴器報警 ,正常的LED燈關閉
{
beep_1=0;
}
else
{
beep_1=1;
} //正常情況下,蜂鳴器關閉
if(temp/10>=H) //上限,當測得的值,大于等于設定值得時候,
{
led_0=0;
}
else
{
led_0=1;
}
if(temp/10<=L) //下限 當實際值小于等于下限值時
{
led_2=0;
}
else
{
led_2=1;
}
}
void main() //主函數
{
do
{
temp=Temper();
}
while(temp==850); //因為DS18B20上電之后會讀出來850,但不是溫度值,所以等待讀出溫度值
delay(1000);
H=byte_read(0x2000);
L=byte_read(0x2200);
if((H>99)||(L>99)||(L>=H)) //讀EEROM里面的數據
{
H=35;
L=16; //如果數據不對,賦予初始值
}
TMOD=0x01;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
EA=1;
ET0=1;
TR0=1; //設置定時器與中斷
while(1)
{
key();
alarm();
}
}
void UART_1() interrupt 1
{
TH0=(65536-10000)/256;
TL0=(65536-10000)%256; //一次定時10MS 十進制65536-50000=15536 折合十六進制3cb0 高位3c低位b0
ms++;
display(); // 完全消影可以開啟這個,屏蔽主函數大循環里的顯示函數
if(ms>100) //數據一秒刷新一次
{
ms=0;
temp=Temper(); //讀溫度
}
if(ms%5==0)
{
if(beep_1==0) //蜂鳴器設置
{
beep=!beep;
}
else
{
beep=1;
}
}
}
|