|
基于51單片機(jī)溫度控制,使用18b20來做溫度傳感器,四位共陽數(shù)碼管顯示。功能說明書:系統(tǒng)啟動后默認(rèn)溫度下限28℃、上限30℃。當(dāng)溫度低于設(shè)定下限溫度時繼電器開啟、加熱指示燈亮起,當(dāng)溫度達(dá)到設(shè)定上限溫度時蜂鳴器響起、保溫指示燈亮起,當(dāng)溫度高于設(shè)定下限溫度低于上限溫度時蜂鳴器關(guān)閉保溫指示燈繼續(xù)亮起,溫度低于下限溫度時切換繼電器開啟加熱指示燈亮起。(假設(shè)設(shè)置燒水,溫度下限設(shè)置在90℃、上限設(shè)置100℃就行)
制作出來的實物圖如下:
51hei圖片20221023115815.jpg (2.12 MB, 下載次數(shù): 59)
下載附件
2022-10-23 12:20 上傳
電路原理圖如下:
51hei圖片20221023122146.png (104.32 KB, 下載次數(shù): 58)
下載附件
2022-10-23 12:22 上傳
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei圖片20221022204816.png (38.53 KB, 下載次數(shù): 63)
下載附件
2022-10-23 12:22 上傳
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
51hei圖片20221022213922.png (47.19 KB, 下載次數(shù): 50)
下載附件
2022-10-23 12:22 上傳
51hei圖片20221022214102.png (396.13 KB, 下載次數(shù): 44)
下載附件
2022-10-23 12:22 上傳
單片機(jī)源程序如下:
#include<reg52.h> //51單片機(jī)的頭文件
#include<intrins.h> //函數(shù)程序中需要使用到空指令
/***_crol_ 字符循環(huán)左移
_cror_ 字符循環(huán)右移
_irol_ 整數(shù)循環(huán)左移
_iror_ 整數(shù)循環(huán)右移
_lrol_ 長整數(shù)循環(huán)左移
_lror_ 長整數(shù)循環(huán)右移
_nop_ 空操作 (相當(dāng)于8051 NOP 指令)
_testbit_ 測試并清零位 (相當(dāng)于8051 JBC 指令) ***/
#define dm P0 //段碼輸出口
#define uchar unsigned char //宏定義,用uchar來代替unsigned char(無符號字符型變量,也即是無符號的8位變量),
//宏定義的原因就是書寫方便,宏定義后,uchar可直接用來定義變量
#define uint unsigned int //原因同上,不過要注意,unsigned int為無符號的整型變量
//sbit是用來管腳的。
sbit DQ=P1^0; //溫度輸入口
sbit w0=P2^4; //數(shù)碼管4
sbit w1=P2^5; //數(shù)碼管3
sbit w2=P2^6; //數(shù)碼管2
sbit w3=P2^7; //數(shù)碼管1
sbit beep=P2^0; //蜂鳴器
sbit jidianqi=P2^1; //繼電器
sbit yellow=P3^5; //加熱指示燈
sbit led=P3^6; //高溫指示燈
sbit zc=P3^7; //系統(tǒng)運(yùn)行正常指示燈
sbit set=P3^4; //選擇設(shè)置
sbit add=P3^3; //加
sbit dec=P3^2; //減
int temp1=0;//最高溫度和最低溫度標(biāo)志位
uint h;
uint temp; //溫度函數(shù)
uchar r;
uchar high=30,low=28; //開機(jī)默認(rèn)最高溫度和最低溫度
uchar sign;
uchar q=0;
uchar tt=0;
uchar scale;
uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; //共陽小數(shù)斷碼表
uchar code table_dm[12]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0xbf}; //共陽LED段碼表"0""1""2""3""4""5""6""7""8""9""不亮""-"
uchar code table_dm1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //共陽個位帶小數(shù)點的斷碼表
uchar data temp_data[2]={0xff,0xff};//讀出溫度暫放
uchar data display[5]={0xff,0xff,0xff,0xff,0xff};//顯示單元數(shù)據(jù),共四個數(shù)據(jù)和一個運(yùn)算暫用
/***************11us延時函數(shù)***************/
void delay(uint t)
{
for(;t>0;t--);
}
/***************數(shù)碼管顯示***************/
void scan()
{
int j;
for(j=0;j<4;j++)
{
switch(j)
{
case 0:
dm=table_dm[display[0]];;
w0=0; //打開數(shù)碼管顯示小數(shù)數(shù)字的數(shù)碼管位選端
delay(50);
w0=1; //關(guān)閉數(shù)碼管顯示小數(shù)數(shù)字的數(shù)碼管位選端
case 1:
dm=table_dm1[display[1]];
w1=0; //打開數(shù)碼管顯示個位數(shù)字的數(shù)碼管位選端
delay(50);
w1=1; //關(guān)閉數(shù)碼管顯示個位數(shù)字的數(shù)碼管位選端
case 2:
dm=table_dm[display[2]];
w2=0; //打開數(shù)碼管顯示十位數(shù)字的數(shù)碼管位選端
delay(50);
w2=1; //關(guān)閉數(shù)碼管顯示十位數(shù)字的數(shù)碼管位選端
case 3:
dm=table_dm[display[3]];
w3=0; //打開數(shù)碼管顯示百位數(shù)字的數(shù)碼管位選端
delay(50);
w3=1; //關(guān)閉數(shù)碼管顯示百位數(shù)字的數(shù)碼管位選端
}
}
}
/****溫度傳感器采用的是DS18b20,此傳感器采用的
是“單總線”來傳輸數(shù)據(jù)。****/
/**************DS18B20初始化**************/
ow_reset(void) //初始化
{
char presence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_(); //將數(shù)據(jù)線拉高并延時
DQ=0; //將DQ(P1.0)引腳拉低。請注意,這里的DQ不是變量,而是單片機(jī)的引腳。!
delay(50); //延時
DQ=1; //將DS拉高
delay(6);
presence=DQ;
}
delay(45);
presence=~DQ;
}
DQ=1;
return presence;
}
/****************寫命令函數(shù)*****************/
void write_byte(uchar val)
{
uchar i;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_(); //將數(shù)據(jù)線拉高并延時
DQ=0;_nop_();_nop_();_nop_();_nop_(); //將數(shù)據(jù)線拉低并延時
DQ=val&0x01;
delay(6);
val=val>>1;
}
DQ=1;
delay(1);
}
/****************讀一個字節(jié)函數(shù)*******************/
uchar read_byte(void)
{
uchar i;
uchar value=0;
for(i=8;i>0;i--) //采用for 循環(huán),讀取原始溫度數(shù)據(jù)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ=0;_nop_();_nop_();_nop_();_nop_();
DQ=1;_nop_();_nop_();_nop_();_nop_();
if(DQ)value|=0x80;
delay(6);
}
DQ=1;
return value;
}
/***************讀取溫度函數(shù)***************/
read_temp() //讀取18b20傳感器函數(shù)
{
ow_reset();
delay(200);
write_byte(0xcc);
write_byte(0x44);
ow_reset();
delay(1);
write_byte(0xcc);
write_byte(0xbe);
temp_data[0]=read_byte();
temp_data[1]=read_byte();
temp=temp_data[1];
temp<<=8;
temp=temp|temp_data[0];
return temp;
}
/***************溫度數(shù)據(jù)處理函數(shù)***************/
work_temp(uint tem) //溫度轉(zhuǎn)換函數(shù)
{
uchar n=0;
if(tem>6348)
{
tem=65536-tem;
n=1;
}
display[4]=tem&0x0f;
display[0]=ditab[display[4]];
display[4]=tem>>4;
display[3]=display[4]/100;
display[1]=display[4]%100;
display[2]=display[1]/10;
display[1]=display[1]%10;
r=display[1]+display[2]*10+display[3]*100;
if(!display[3])
{
display[3]=0x0a;
if(!display[2])
{
display[2]=0x0a;
}
}
if(n)
{
display[3]=0x0b;
}
return n;
}
/***************報警提示電路***************/
void BEEP()
{
{zc=0;} //系統(tǒng)正常指示燈
if(r>=high&&r<129) //如果實際溫度高于等于于設(shè)定溫度
{
led=0;//保溫?zé)袅?br />
beep=0;//蜂鳴器響
jidianqi=1; //繼電器停止加熱
yellow=1;//加熱燈滅
}
else //否則
{
beep=1;//蜂鳴器停
}
if(r<low) //如果實際溫度小于設(shè)定溫度
{
yellow=0;//加熱燈亮
led=1;//保溫?zé)魷?br />
jidianqi=0; //繼電器開始加熱
}
}
/***************溫度顯示轉(zhuǎn)換**************/
void xianshi(int horl) //數(shù)碼管顯示函數(shù)
{
int n=0;
if(horl>128)
{
horl=256-horl;
n=1;
}
display[3]=horl/100; // 顯示千位
display[3]=display[3]&0x0f; //顯示千位
display[2]=horl%100/10; // 顯示百位
display[1]=horl%10; // 顯示個位
display[0]=0; // 顯示分
if(!display[3])
{
display[3]=0x0a;
if(!display[2])
{
display[2]=0x0a;
}
}
if(n)
{
display[3]=0x0b;
}
仿真程序和AD PCB文件下載:
51 18b20 .rar
(1.78 MB, 下載次數(shù): 324)
2022-10-23 12:25 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|
評分
-
查看全部評分
|