1. 程式人生 > >課設 - 基於微控制器的溫控報警系統設計 (電路+程式)

課設 - 基於微控制器的溫控報警系統設計 (電路+程式)

 

本設計所介紹的數字溫度計與傳統的溫度計相比,具有讀數方便,測溫範圍廣,測溫準確,其輸出溫度採用數字顯示,主要用於對測溫比較準確的場所,或科研實驗室使用,該設計控制器使用微控制器AT89S51,測溫感測器使用DS18B20,用3位共陽極LED數碼管以串列埠傳送資料,實現溫度顯示,能準確達到以上要求。

 

#include<reg52.h>
#include <stdio.h>
#include <absacc.h>
code unsigned char seg7code[11]=
{ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,
0x82,0xf8,0x80,0x90,0x40}; //顯示段碼
 
sbit TMDAT =P3^1; //DS18B20 的資料輸入/輸出腳DQ,根據情況設定
 
sbit jia=P2^1;
sbit jian=P2^0;
sbit hong=P1^0;//紅色警告燈
sbit sheng=P1^1;//蜂鳴器
sbit lan=P1^2;//蘭色燈
bit write=0; //寫24C08 的標誌;
 
j=30;
unsigned int sdata;//測量到的溫度的整數部分
unsigned char xiaoshu1;//小數第一位
unsigned char xiaoshu2;//小數第二位
unsigned char xiaoshu;//兩位小數
 
bit fg=1; //溫度正負標誌
 
////////24C08 讀寫驅動程式////////////////////
sbit scl=P3^4; // 24c08 SCL
sbit sda=P3^5; // 24c08 SDA

void delay1(unsigned char x)
{ unsigned int i;
for(i=0;i<x;i++);
;}

void flash()
{ ; ; }

void x24c08_init() //24c08 初始化子程式
{scl=1; flash(); sda=1;  flash();}

void start() //啟動(I方C)匯流排
{sda=1; flash(); scl=1; flash(); sda=0; flash(); scl=0; flash();}

void stop() //停止(I方C)匯流排
{sda=0; flash(); scl=1; flash(); sda=1; flash();}

void writex(unsigned char j) //寫一個位元組
{ unsigned char i,temp;
temp=j;
for (i=0;i<8;i++)
{temp=temp<<1; scl=0; flash(); sda=CY; flash(); scl=1; flash();}
scl=0; flash(); sda=1; flash();
}

unsigned char readx() //讀一個位元組
{
unsigned char i,j,k=0;
scl=0; flash(); sda=1;
for (i=0;i<8;i++)
{
flash(); scl=1; flash();
if (sda==1) j=1;
else j=0;
k=(k<<1)|j;
scl=0;}
flash(); return(k);
}

void clock() //(I方C)線時鐘
{
unsigned char i=0;
scl=1; flash();
while ((sda==1)&&(i<255))i++;
scl=0; flash();
}

//從24c02 的地址address 中讀取一個字
unsigned char x24c08_read(unsigned char address)
{
unsigned char i;
start(); writex(0xa0);
clock(); writex(address);
clock(); start();
writex(0xa1); clock();
i=readx(); stop();
delay1(10);
return(i);
}

//向24c02 的address 地址中寫入一位元組資料info
void x24c08_write(unsigned char address,
unsigned char info)
{
EA=0;
start(); writex(0xa0);
clock(); writex(address);
clock(); writex(info);
clock(); stop();
EA=1;
delay1(50);
}

/*////////////24C08 讀寫驅動程式完/////////////////////
void Delay2(unsigned int tc) //延時程式
{
while( tc != 0 )
{unsigned int i;
for(i=0; i<100; i++);
tc--;}
}
*/

//////////*顯示延時程式*///////////////
void Delay(unsigned int tc)
{while( tc != 0 )
{unsigned int i;
for(i=0; i<80; i++);
tc--;}
}
 
////////////延時部分///////////////
void yanshi (unsigned int count)
{
unsigned char i;
while(count--)
{for(i=0;i<115;i++);}
}
 
/////////////傳送復位/////////////// 
void fashong (void)
{
unsigned char i;
TMDAT = 0; for(i=0;i<103;i++);
TMDAT = 1; for(i=0;i<4;i++);
}
  
bit tmrbit (void) //讀一位//
{                      
unsigned int i;
bit dat;
TMDAT = 0;
i++;
TMDAT = 1;
i++; i++; //微量延時 //
dat = TMDAT;
for(i=0;i<8;i++);
return (dat);
}
 
unsigned char tmrbyte (void) //讀一個位元組
{
unsigned char i,j,dat;
dat = 0;
for (i=1;i<=8;i++)
{ j = tmrbit(); dat = (j << 7) | (dat >> 1); }
return (dat);
}
//寫一個位元組 
void tmwbyte (unsigned char dat)
{
unsigned char j,i;
bit testb;
for (j=1;j<=8;j++)
{ testb = dat & 0x01;
dat = dat >> 1;
if (testb)
{ TMDAT = 0; //寫0
i++; i++;
TMDAT = 1;
for(i=0;i<8;i++); }
else
{ TMDAT = 0; //寫0
for(i=0;i<8;i++);
TMDAT = 1;
i++; i++;}
}
}
void tmstart (void) //傳送ds1820 開始轉換
{
fashong(); //復位
yanshi(1); //延時
tmwbyte(0xcc); //跳過序列號命令
tmwbyte(0x44); //發轉換命令 44H,
}                   
void tmrtemp (void) //讀取溫度
{
unsigned char a,b;
fashong (); //復位
yanshi (1); //延時
tmwbyte (0xcc); //跳過序列號命令
tmwbyte (0xbe); //傳送讀取命令
a = tmrbyte (); //讀取低位溫度
b = tmrbyte (); //讀取高位溫度
if(b>0x7f) //最高位為1 時溫度是負
{a=~a; b=~b+1; //補碼轉換,取反加一
fg=0; //讀取溫度為負時fg=0
}
sdata = a/16+b*16; //整數部分
xiaoshu1 = (a&0x0f)*10/16; //小數第一位
xiaoshu2 = (a&0x0f)*100/16%10;//小數
xiaoshu=xiaoshu1*10+xiaoshu2; //小數
}
void DS18B20PRO(void)
{
tmstart();
//yanshi(5); //如果是不斷地讀取的話可以不延
tmrtemp(); //讀取溫度,執行完畢溫度將存於
}
void Led()
{
if(fg==1) //溫度為正時顯示的資料
{
  P2=P2&0xef;
P0=seg7code[sdata/10]; //輸
Delay(2); P2=P2|0xf0; P2=P2&0xdf;
P0=seg7code[sdata%10]|0x80; //輸出個
Delay(2); P2=P2|0xf0; P2=P2&0xbf;
P0=seg7code[xiaoshu1]; //輸出小數點
Delay(2); P2=P2|0xf0; P2=P2&0x7f;
P0=seg7code[xiaoshu2]; //輸出小
Delay(1); P2=P2|0xf0;
Delay(2); P2=P2|0xf0;P2=P2&0xf7;
P0=seg7code[j/10]; //輸出十位
Delay(2); P2=P2|0x0f; P2=P2&0xfb;
P0=seg7code[j%10]|0x80; //輸出個位 
Delay(1); P2=P2|0x0f;
 
if(sdata<=j)
{
lan=0;
hong=1;
sheng=1;
};
if(sdata>=j)
{
lan=1;
hong=0;
sheng=0;
}; 
}
if(fg==0) //溫度為負時顯示的資料
{ P2=P2&0xef;
P0=seg7code[11]; //負號
Delay(8); P2=P2|0xf0; P2=P2&0xdf;
P0=seg7code[sdata/10]|0x80; //輸出十位
Delay(8); P2=P2|0xf0; P2=P2&0xbf;
P0=seg7code[sdata%10]; //輸出個位
Delay(8); P2=P2|0xf0; P2=P2&0x7f;
P0=seg7code[xiaoshu1]; //輸出小
Delay(4); P2=P2|0xf0;
}
}
main()
{fg=1;
x24c08_init(); //初始化24C08
j=x24c08_read(2);//讀出儲存的資料
while(1)
{
DS18B20PRO();
Led();
if(jia==0)
{Delay(200);j++;}
if(jian==0)
{Delay(200);j--;}
x24c08_write(2,j);
}
}

獲取完整課設資料,掃碼關注傳送【溫控報警】,海量雲盤資料等你下載。