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--;
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>
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繼電器,可以直接控制你的電機了。
兩個電路圖都差不多的,只不過我的多了幾個調整按鍵,報警溫度可以調的。我的這個程式你完全可以用到你的電路里德
51微控制器數碼管動態顯示從右往左
這是四位數碼管從右從左流動顯示,像滾動字幕一樣的。用不著矩陣按鍵哪版。其實程式很簡單權,沒那麼複雜。程式如下 include define uchar unsigned char define uint unsigned intuchar code tab 共陰段碼碼,0x00為滅void dela...
如何通過程式設計,實現51微控制器控制數碼管顯示0 9這幾個數字
while後加邏輯語句,如果值為true也就是1時就會執行下面的語句,執行完再判斷是不是true,如果是的話繼續執行,然後就迴圈了 如果為false也就是0就會停止 如果不加的話也就是執行一次,執行完後結束,燈就不亮了,按理說應該亮一次,但是執行太快你根本沒來得及看到燈亮就已經結束了 如果加迴圈語句...
求助51微控制器高手數碼管動態顯示問題要求是數碼管動態顯示
把一個多位抄數 大於9的數襲 分別顯示在兩個數碼 管上面就是把這個數的每一位拆開,用數碼管的動態掃描進行顯示。至於閃動,不就是一亮一滅嗎?就用個定時器定時,在一秒的時間內,一半時間是亮的,一半時間是滅的,不就閃爍了嘛 沒有if成立的條件時數碼管的的位選保持最後下次狀態,然後j一直加到最大值,再從0開...