1樓:匿名使用者
軟體設計:
有兩個檔案,ds18b20.c和ds18b20.h,將這兩個檔案新增到工程裡即可。
ds18b20.c:
程式名稱:ds18b20溫度測量、報警系統
簡要說明:ds18b20溫度計,溫度測量範圍0~99.9攝氏度
可設定上限報警溫度、下限報警溫度
即高於上限值或者低於下限值時蜂鳴器報警
預設上限報警溫度為32℃、預設下限報警溫度為10℃
報警值可設定範圍:最低上限報警值等於當前下限報警值
最高下限報警值等於當前上限報警值
將下限報警值調為0時為關閉下限報警功能
#include
#include "ds18b20.h"
#define uint unsigned int
#define uchar unsigned char //巨集定義
#define set p3_1 //定義調整鍵
#define dec p3_2 //定義減少鍵
#define add p3_3 //定義增加鍵
#define beep p3_7 //定義蜂鳴器
#define jdq p3_5
bit shanshuo_st; //閃爍間隔標誌
bit beep_st; //蜂鳴器間隔標誌
sbit dian = p2^7; //小數點
uchar x=0; //計數器
signed char m; //溫度值全域性變數
uchar n; //溫度值全域性變數
uchar set_st=0; //狀態標誌
signed char shangxian=70; //上限報警溫度,預設值為70
signed char xiaxian=0; //下限報警溫度,預設值為0
uchar code leddata=;
/*****延時子程式*****/
void delay(uint num)
while( --num );
void shortdelay(void) //誤差 0us
unsigned char a,b,c;
for(c=165;c>0;c--)
for(b=100;b>0;b--)
for(a=150;a>0;a--);
_nop_; //if keil,require use intrins.h
_nop_; //if keil,require use intrins.h
/*****初始化定時器0*****/
void inittimer(void)
tmod=0x1;
th0=0x3c;
tl0=0xb0; //50ms(晶振12m)
/*****定時器0中斷服務程式*****/
void timer0(void) interrupt 1
th0=0x3c;
tl0=0xb0;
x++;
/*****外部中斷0服務程式*****/
void int0(void) interrupt 0
ex0=0; //關外部中斷0
if(dec==0&&set_st==1)
shangxian--;
if(shangxianelse if(dec==0&&set_st==2)
xiaxian--;
if(xiaxian<0)xiaxian=0;
/*****外部中斷1服務程式*****/
void int1(void) interrupt 2
ex1=0; //關外部中斷1
if(add==0&&set_st==1)
shangxian++;
if(shangxian>99)shangxian=99;
else if(add==0&&set_st==2)
xiaxian++;
if(xiaxian>shangxian)xiaxian=shangxian;
/*****讀取溫度*****/
void check_wendu(void)
uint a,b,c;
c=readtemperature()-5; //獲取溫度值並減去ds18b20的溫漂誤差
a=c/100; //計算得到十位數字
b=c/10-a*10; //計算得到個位數字
m=c/10; //計算得到整數位
n=c-a*100-b*10; //計算得到小數位
if(m<0) //設定溫度顯示上限
if(m>99) //設定溫度顯示上限
/*****顯示開機初始化等待畫面*****/
disp_init()
p2 = 0xbf; //顯示-
p1 = 0xf7;
delay(200);
p1 = 0xfb;
delay(200);
p1 = 0xfd;
delay(200);
p1 = 0xfe;
delay(200);
p1 = 0xff; //關閉顯示
/*****顯示溫度子程式*****/
disp_temperature() //顯示溫度
p2 =0xc6; //顯示c
p1 = 0xf7;
delay(300);
p2 =leddata[n]; //顯示個位
p1 = 0xfb;
delay(300);
p2 =leddata[m%10]; //顯示十位
dian = 0; //顯示小數點
p1 = 0xfd;
delay(300);
p2 =leddata[m/10]; //顯示百位
p1 = 0xfe;
delay(300);
p1 = 0xff; //關閉顯示
/*****顯示報警溫度子程式*****/
disp_alarm(uchar baojing)
p2 =0xc6; //顯示c
p1 = 0xf7;
delay(200);
p2 =leddata[baojing%10]; //顯示十位
p1 = 0xfb;
delay(200);
p2 =leddata[baojing/10]; //顯示百位
p1 = 0xfd;
delay(200);
if(set_st==1)p2 =0x89;
else if(set_st==2)p2 =0xc7; //上限h、下限l標示
p1 = 0xfe;
delay(200);
p1 = 0xff; //關閉顯示
/*****報警子程式*****/
void alarm()
if(x>=10)
if((m>=shangxian&&beep_st==1)||(melse beep=1;
if((m>=shangxian)||(m
else jdq=1;
/*****主函式*****/
void main(void)
uint z;
inittimer(); //初始化定時器
ea=1; //全域性中斷開關
tr0=1;
et0=1; //開啟定時器0
it0=1;
it1=1;
check_wendu();
check_wendu();
for(z=0;z<300;z++)
disp_init();
while(1)
if(set==0)
delay(2000);
do{}while(set==0);
set_st++;x=0;shanshuo_st=1;
if(set_st>2)set_st=0;
if(set_st==0)
ex0=0; //關閉外部中斷0
ex1=0; //關閉外部中斷1
check_wendu();
disp_temperature();
alarm(); //報警檢測
else if(set_st==1)
beep=1; //關閉蜂鳴器
ex0=1; //開啟外部中斷0
ex1=1; //開啟外部中斷1
if(x>=10)
if(shanshuo_st)
else if(set_st==2)
beep=1; //關閉蜂鳴器
ex0=1; //開啟外部中斷0
ex1=1; //開啟外部中斷1
if(x>=10)
if(shanshuo_st)
/*****end*****/
ds18b20.h:
#include
#define dq p3_6 //定義ds18b20匯流排i/o
/*****延時子程式*****/
void delay_ds18b20(int num)
while(num--) ;
/*****初始化ds18b20*****/
void init_ds18b20(void)
unsigned char x=0;
dq = 1; //dq復位
delay_ds18b20(8); //稍做延時
dq = 0; //微控制器將dq拉低
delay_ds18b20(80); //精確延時,大於480us
dq = 1; //拉高匯流排
delay_ds18b20(14);
x = dq; //稍做延時後,如果x=0則初始化成功,x=1則初始化失敗
delay_ds18b20(20);
/*****讀一個位元組*****/
unsigned char readonechar(void)
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
dq = 0; // 給脈衝訊號
dat>>=1;
dq = 1; // 給脈衝訊號
if(dq)
dat|=0x80;
delay_ds18b20(4);
return(dat);
/*****寫一個位元組*****/
void writeonechar(unsigned char dat)
unsigned char i=0;
for (i=8; i>0; i--)
dq = 0;
dq = dat&0x01;
delay_ds18b20(5);
dq = 1;
dat>>=1;
/*****讀取溫度*****/
unsigned int readtemperature(void)
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float tt=0;
init_ds18b20();
writeonechar(0xcc); //跳過讀序號列號的操作
writeonechar(0x44); //啟動溫度轉換
init_ds18b20();
writeonechar(0xcc); //跳過讀序號列號的操作
writeonechar(0xbe); //讀取溫度暫存器
a=readonechar(); //讀低8位
b=readonechar(); //讀高8位
t=b;
t<<=8;
t=t|a;
tt=t*0.0625;
t= tt*10+0.5; //放大10倍輸出並四捨五入
return(t);
/*****end*****/
其中控制部分我用的是5v繼電器,可以直接控制你的電機了。
兩個電路圖都差不多的,只不過我的多了幾個調整按鍵,報警溫度可以調的。我的這個程式你完全可以用到你的電路里德