A. ds18b20溫度報警程序
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P3^7; //define interface 定義DS18B20介面
uint temp; // variable of temperature
uchar flag1; // sign of the result positive or negative
sbit p0_5=P0^5;
sbit p2_7=P2^7;
sbit p2_4=P2^4;
sbit p2_5=P2^5;
sbit p2_6=P2^6;
unsigned char code TABLE[]={
0xd7,0x11,0xcd,0x5d,0x1b,
0x5e,0xde,0x15,0xdf,0x5f,
0x9f,0xdf,0xc6,0xd7,0xce,0x8e};
void delay(uint count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
void Init_Com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}
void dsreset(void) //send reset and initialization command
{
uint i; //DS18B20初始化
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bit tmpreadbit(void) //read a bit 讀一位
{
uint i;
bit dat;
DS=0;i++; //i++ for delay 小延時一下
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
uchar tmpread(void) //read a byte date 讀一個位元組
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //讀出的數據最低位在最前面,這樣剛好
//一個位元組在DAT里
}
return(dat); //將一個位元組數據返回
}
void tmpwritebyte(uchar dat) //write a byte to ds18b20
{ //寫一個位元組到DS18B20里
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1 寫1部分
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //write 0 寫0部分
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //DS18B20 begin change 發送溫度轉換命令
{
dsreset(); //初始化DS18B20
delay(1); //延時
tmpwritebyte(0xcc); // 跳過序列號命令
tmpwritebyte(0x44); //發送溫度轉換命令
}
uint tmp() //get the temperature 獲得溫度
{
float tt;
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe); //發送讀取數據命令
a=tmpread(); //連續讀兩個位元組數據
b=tmpread();
temp=b;
temp<<=8; //two byte compose a int variable
temp=temp|a; //兩位元組合成一個整型變數。
tt=temp*0.0625; //得到真實十進制溫度值,因為DS18B20
//可以精確到0.0625度,所以讀回數據的最低位代表的是
//0.0625度。
temp=tt*10+0.5; //放大十倍,這樣做的目的將小數點後第一位
//也轉換為可顯示數字,同時進行一個四捨五入操作。
return temp; //返回溫度值
}
void delay10ms() //delay
{
uchar a,b;
for(a=10;a>0;a--)
for(b=60;b>0;b--);
}
void display(uint temp)
{
uchar a,b,c,d;
a=temp/100;
b=temp/10-a*10;
d=temp%10;
c=(temp%100-d)/10;
P0=TABLE[d];
p0_5=0;
p2_7=0;
delay(1);
p2_7=1;
P0=TABLE[c];
p2_4=0;
delay(1);
p2_4=1;
P0=TABLE[b];
p0_5=1;
p2_5=0;
delay(1);
p2_5=1;
P0=TABLE[a];
p2_6=0;
delay(1);
p2_6=1;
}
void main() //主函數
{
uchar a;
Init_Com(); //初始化串口
do
{
tmpchange(); //溫度轉換
for(a=10;a>0;a--)
{
display(tmp()); //顯示十次
}
}
while(1);
}
B. 關於C51單片機溫度報警程序的問題 誰能幫我在每段程序後加漢字解釋 及怎麼實現溫度顯示及蜂鳴器報警的
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define out P0 ;
#define INT8U unsigned char //宏定義
#define INT16U unsigned int
sbit smg1=P2^0;
sbit smg2=P2^1;
sbit smg3=P2^2;
sbit smg4=P2^3;
sbit Beep=P1^5; //蜂鳴器引腳定義
sbit led=P1^6;
sbit led1=P1^7; //設置燈光報警鍵
sbit DQ=P2^4; //ds18b20埠
void init_ds18b20(void); //ds18b20初始化子程序
void delay(uchar); //ds18b20工作延時子程序
uchar readbyte(void);//向ds18b20讀一個位元組數據
/*******************************************************************************/
void writebyte(uchar);//向ds18b20寫一個位元組數據
uint retemp();//計數變數
uchar key;
uchar a,b,c,d; //計數變數
uchar x[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uint retemp()
{
uint a,b,t;
init_ds18b20(); //初始化ds18b20
writebyte(0xcc); // 跳過讀序列號的操作
writebyte(0x44); // 啟動溫度轉換
init_ds18b20();
writebyte(0xcc); //跳過讀序號列號的操作
writebyte(0xbe); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
a=readbyte(); //讀出溫度低位LSB
b=readbyte(); //讀出溫度高位MSB
t=b; //將溫度高八位送t
t<<=8; //乘以256移到高八位
t=t|a; //高低八位組合成溫度值
if(t<0x8000) //如果溫度為正計算正溫度值
{
key=0;
t=t*0.625;
}
else //否則溫度為負,取反
{
key=1;
t=(~t+1)*0.625;
}
return(t); //返回溫度值
}
void main()
{
uint i,t;
EA = 1; //開總中斷
TMOD = 0x01; //定時器0工作方式1
TR0=1;
delay(100);
while(1)
{
t=retemp(); 讀溫度值
a=x[t/1000]; //溫度千位數
b=x[t/100%10]; //溫度百位數
c=x[t/10%10]-0x80; //溫度十位數
d=x[t%10]; //溫度個位數
if(key==1) //如果key=1
a=0xbf; //a為「負號"
if((key==0)&&(t>320)) //如果key=0 且t大於320
{
led1=0; //點亮led1
ET0=1; //開啟定時器0中斷
}
else if(t<290) //如果溫度小於290
{
led=0; //點亮led
ET0=1; //開啟定時器0中斷
}
else //否則
{
led1=1; //關閉led1
led=1; //關閉led
ET0=0; //關閉定時器0中斷
}
for(i=0;i<50;i++) //循環50次
{smg1=1;P0=a;delay(100);smg1=0; //顯示千位
smg2=1;P0=b;delay(100);smg2=0; //顯示百位
smg3=1;P0=c;delay(100);smg3=0; //顯示十位
smg4=1;P0=d;delay(100);smg4=0; //顯示個位
}
}
}
/*ds18b20工作延時子程序*/
void delay (uchar i)
{
do
{_nop_();
_nop_();
_nop_();
i--;
}
while(i);}
/*ds18b20初始化子程序*/
void init_ds18b20()
{
uchar x=0;
DQ=0; //單片機將DQ拉低
delay (120);
DQ=1; //拉高匯流排
delay(16);
delay(80);
}
/*讀一個位元組*/
uchar readbyte ()
{uchar i=0,date=0;
for(i=8;i>0;i--)
{
DQ=0; // 給脈沖信號
delay(1);
DQ=1; // 給脈沖信號
date>>=1;
if(DQ)date|=0x80;
delay(11);
}
return(date);
}
/*寫一個位元組*/
void writebyte(uchar dat)
{uchar i=0;
for(i=8;i>0;i--) //寫8位數
{
DQ=0;
DQ=dat&0x01; //寫dat的D0位
delay(12);
DQ=1;
dat>>=1;
delay(5);
}
}
/**************************************************
*函數名:中斷函數
*描 述:產生矩形脈沖使蜂鳴器發聲
**************************************************/
void BeepTimer0(void) interrupt 1
{
Beep = ~Beep;
TH0 = 65335 / 256; //定時器賦初值
TL0 = 65335 % 256;
}
C. 求用AT89C51單片機和DS18B20做溫度報警器,報警器用蜂鳴器,溫度顯示用數碼管,用c語言編寫程序最好有注釋
#include < reg51.h >
#include < intrins.h >
#define uchar unsigned char
#define uint unsigned int
#define temp_high 60 //溫度報警限設置
uchar data temph;
uchar data templ;
uchar data dat;
uchar temp_buzzer,b,fuhao;
uchar code tab[]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};
uchar shi,ge,shifen; //全局變數
bit flag;
sbit DQ=P1^0;
sbit buzzer=P1^7;
void delay_50us(unsigned int t) //每次延時,最大誤差13us
{
unsigned char j;
for(;t>0;t--)
for(j=19;j>0;j--)
;
}
void delay_2us(unsigned char i) //每次2us精確延時,最大誤差6us
{
while(--i);
}
void buzzer_sound() //蜂鳴器報警函數
{
if (temp_buzzer>temp_high)
buzzer=0;
else
buzzer=1;
}
void Display() //LCD 顯示函數
{
P2=tab[shi];
P3=0xfd;
delay_50us(20);//十位 延時1ms
P3=0xff;
P2=tab[ge]+0x80;
P3=0xfb;
delay_50us(20);//個位 延時1ms
P3=0xff;
P2=tab[shifen];
P3=0xf7;
delay_50us(20);//十分位 延時1ms
P3=0xff;
}
Ds_Reset() //初始化
{
DQ=1;
_nop_();
_nop_();
DQ=0;
delay_50us(10); //延時513us
DQ=1;
delay_2us(23);//延時53us
flag=DQ;
delay_50us(4);//延時200us
DQ=1;//拉伸至高電平
return(flag);
}
Ds_Read() //讀函數
{
uint i;
uchar dat=0x00;
for(i=0;i<8;i++)
{
DQ=0;
_nop_(); //延時1us
dat>>=1;
DQ=1; //釋放
_nop_();
_nop_();
_nop_();
if(DQ)
{
dat|=0x80;}
delay_2us(30); // 延時67us
DQ=1;
}
return(dat);
}
void Ds_Write(unsigned char datt)
{
uchar j;
bit bitt;
for(j=0;j<8;j++)
{
bitt=datt&0x01;
DQ=0;
_nop_();
_nop_(); //延時2us
if(bitt)
{
DQ=1;
delay_2us(28);
}
else delay_2us(28); //延時56us
datt>>=1;
DQ=1;
_nop_();
}
}
void Set_Tempchange() //溫度轉換指令
{
Ds_Reset();
Ds_Write(0xcc);// 跳過讀序號列號的操作
Ds_Write(0x44);// 啟動溫度轉?
}
void Read_Temp() //讀出溫度
{
Ds_Reset();
Ds_Write(0xcc);// 跳過讀序號列號的操作
Ds_Write(0xBE);// 讀RAM數據
templ=Ds_Read();//溫度的低八位
temph=Ds_Read();//溫度的高八?
}
void Change_Temp() //轉換溫度
{
uchar intn,xiaoshu;
uchar k,temp;
fuhao=temph&0xf8;
if(!fuhao) //正數
{
intn=(temph<<4)|(templ>>4);
xiaoshu=(templ&0x0f)*625;
}
else //負數
{
intn=((~temph<<4)|(~templ>>4))+1;
xiaoshu=(((~templ)&0x0f)+1)*625;
}
k=templ;
temp=intn;
temp=temp&0x80;
if(temp==0x80)
k=~k+1;
k=k&0x0f;
temp_buzzer=intn;
switch (k)
{
case 0x00: b=0;break;
case 0x01: b=1;break;
case 0x02: b=1;break;
case 0x03: b=2;break;
case 0x04: b=2;break;
case 0x05: b=3;break;
case 0x06: b=3;break;
case 0x07: b=4;break;
case 0x08: b=4;break;
case 0x09: b=5;break;
case 0x0a: b=5;break;
case 0x0b: b=6;break;
case 0x0c: b=7;break;
case 0x0d: b=8;break;
case 0x0e: b=9;break;
case 0x0f: b=9;break;
}
shi=intn%100/10;//十位
ge=intn%10; //個位
shifen=b;//xiaoshu/1000;//十分位
buzzer_sound();
}
void main()
{
uchar i,j;
while(1)
{
for(i=0;i<8;i++)
{
Set_Tempchange();
_nop_();
for(j=0;j<250;j++)
{
Display();
}
Read_Temp(); //將讀RAM的函數放到這兒是因為溫度的轉換要用750ms時間,這里用Display()函數來達到延時效果
Change_Temp();
}
}
}
參考一下喔