|
源程序
#include <reg51.h>
#include<intrins.h>//頭文件
#define uchar unsigned char
#define uint unsigned int
uchar count;
//--定義使用的IO口--//
sbit DSPORT=P2^4;
sbit CS = P2^0;
sbit Clk = P3^6;
sbit DATI = P3^7;
sbit DATO = P3^7;
sbit key1=P1^4;//按鍵設(shè)置
sbit key2=P1^5;//按鍵加
sbit key3=P1^6;//按鍵減
sbit beep=P1^7;
//--聲明全局函數(shù)--//
void Delay1ms(uint );
uchar Ds18b20Init();
void Ds18b20WriteByte(uchar com);
uchar Ds18b20ReadByte();
void Ds18b20ChangTemp();
void Ds18b20ReadTempCom();
int Ds18b20ReadTemp(),T;
#define datlcd P0 ;
sbit lcdrs = P2^1; //液晶讀
sbit lcdrw = P2^2; //液晶寫(xiě)
sbit lcden = P2^3;//液晶選擇
long ch0_temp; //定義變量
unsigned char dat = 0x00;
unsigned char count = 0x00;
unsigned char CH;
signed int MIN=200;
signed int MAX=1500;
uchar page=0;
unsigned char adc0832(unsigned char CH) //ADC測(cè)量程序
{
unsigned char i,test,adval;
adval = 0x00;
test = 0x00;
Clk = 0;
DATI = 1;
_nop_();
CS = 0;
_nop_();
Clk = 1;
_nop_();
if ( CH == 0x00 )
{
Clk = 0;
DATI = 1;
_nop_();
Clk = 1;
_nop_();
Clk = 0;
DATI = 0;
_nop_();
Clk = 1;
_nop_();
}
else
{
Clk = 0;
DATI = 1;
_nop_();
Clk = 1;
_nop_();
Clk = 0;
DATI = 1;
_nop_();
Clk = 1;
_nop_();
}
Clk = 0;
DATI = 1;
for( i = 0;i < 8;i++ )
{
_nop_();
adval <<= 1;
Clk = 1;
_nop_();
Clk = 0;
if (DATO)
adval |= 0x01;
else
adval |= 0x00;
}
for (i = 0; i < 8; i++)
{
test >>= 1;
if (DATO)
test |= 0x80;
else
test |= 0x00;
_nop_();
Clk = 1;
_nop_();
Clk = 0;
}
if (adval == test)
dat = test;
_nop_();
CS = 1;
DATO = 1;
Clk = 1;
return dat;
}
/*******************************************************************************
* 函 數(shù) 名 : Delay1ms
* 函數(shù)功能 : 延時(shí)函數(shù)
* 輸 入 : 無(wú)
* 輸 出 : 無(wú)
*******************************************************************************/
void Delay1ms(uint y)
{
uint x;
for( ;y>0;y--)
{
for(x=110;x>0;x--);
}
}
/*******************************************************************************
* 函 數(shù) 名 : Ds18b20Init
* 函數(shù)功能 : 初始化
* 輸 入 : 無(wú)
* 輸 出 : 初始化成功返回1,失敗返回0
*******************************************************************************/
uchar Ds18b20Init()
{
uchar i;
DSPORT = 0; //將總線拉低480us~960us
i = 70;
while(i--);//延時(shí)642us
DSPORT = 1; //然后拉高總線,如果DS18B20做出反應(yīng)會(huì)將在15us~60us后總線拉低
i = 0;
while(DSPORT) //等待DS18B20拉低總線
{
Delay1ms(1);
i++;
if(i>5)//等待>5MS
{
return 0;//初始化失敗
}
}
return 1;//初始化成功
}
/*******************************************************************************
* 函 數(shù) 名 : Ds18b20WriteByte
* 函數(shù)功能 : 向18B20寫(xiě)入一個(gè)字節(jié)
* 輸 入 : 無(wú)
* 輸 出 : 無(wú)
*******************************************************************************/
void Ds18b20WriteByte(uchar dat)
{
uint i, j;
for(j=0; j<8; j++)
{
DSPORT = 0; //每寫(xiě)入一位數(shù)據(jù)之前先把總線拉低1us
i++;
DSPORT = dat & 0x01; //然后寫(xiě)入一個(gè)數(shù)據(jù),從最低位開(kāi)始
i=6;
while(i--); //延時(shí)68us,持續(xù)時(shí)間最少60us
DSPORT = 1; //然后釋放總線,至少1us給總線恢復(fù)時(shí)間才能接著寫(xiě)入第二個(gè)數(shù)值
dat >>= 1;
}
}
/*******************************************************************************
* 函 數(shù) 名 : Ds18b20ReadByte
* 函數(shù)功能 : 讀取一個(gè)字節(jié)
* 輸 入 : 無(wú)
* 輸 出 : 無(wú)
*******************************************************************************/
uchar Ds18b20ReadByte()
{
uchar byte, bi;
uint i, j;
for(j=8; j>0; j--)
{
DSPORT = 0;//先將總線拉低1us
i++;
DSPORT = 1;//然后釋放總線
i++;
i++;//延時(shí)6us等待數(shù)據(jù)穩(wěn)定
bi = DSPORT; //讀取數(shù)據(jù),從最低位開(kāi)始讀取
/*將byte左移一位,然后與上右移7位后的bi,注意移動(dòng)之后移掉那位補(bǔ)0。*/
byte = (byte >> 1) | (bi << 7);
i = 4; //讀取完之后等待48us再接著讀取下一個(gè)數(shù)
while(i--);
}
return byte;
}
/*******************************************************************************
* 函 數(shù) 名 : Ds18b20ChangTemp
* 函數(shù)功能 : 讓18b20開(kāi)始轉(zhuǎn)換溫度
* 輸 入 : 無(wú)
* 輸 出 : 無(wú)
*******************************************************************************/
void Ds18b20ChangTemp()
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc); //跳過(guò)ROM操作命令
Ds18b20WriteByte(0x44); //溫度轉(zhuǎn)換命令
//Delay1ms(100); //等待轉(zhuǎn)換成功,而如果你是一直刷著的話,就不用這個(gè)延時(shí)了
}
/*******************************************************************************
* 函 數(shù) 名 : Ds18b20ReadTempCom
* 函數(shù)功能 : 發(fā)送讀取溫度命令
* 輸 入 : 無(wú)
* 輸 出 : 無(wú)
*******************************************************************************/
void Ds18b20ReadTempCom()
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc); //跳過(guò)ROM操作命令
Ds18b20WriteByte(0xbe); //發(fā)送讀取溫度命令
}
/*******************************************************************************
* 函 數(shù) 名 : Ds18b20ReadTemp
* 函數(shù)功能 : 讀取溫度
* 輸 入 : 無(wú)
* 輸 出 : 無(wú)
*******************************************************************************/
int Ds18b20ReadTemp()
{
int temp = 0;
uchar tmh, tml;
Ds18b20ChangTemp(); //先寫(xiě)入轉(zhuǎn)換命令
Ds18b20ReadTempCom(); //然后等待轉(zhuǎn)換完后發(fā)送讀取溫度命令
tml = Ds18b20ReadByte(); //讀取溫度值共16位,先讀低字節(jié)
tmh = Ds18b20ReadByte(); //再讀高字節(jié)
temp = tmh;
temp <<= 8;
temp |= tml;
return temp;
}
/*******************************************************************************
* 函 數(shù) 名 : datapros()
* 函數(shù)功能 : 溫度讀取處理轉(zhuǎn)換函數(shù)
* 輸 入 : temp
* 輸 出 : 無(wú)
*******************************************************************************/
void datapros(int temp)
{
float tp;
// if(temp< 0) //當(dāng)溫度值為負(fù)數(shù)
// {
//因?yàn)樽x取的溫度是實(shí)際溫度的補(bǔ)碼,所以減1,再取反求出原碼
// temp=temp-1;
// temp=~temp;
// tp=temp;
// temp=tp*0.0625*100+0.5;
//留兩個(gè)小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語(yǔ)言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時(shí)候把小數(shù)點(diǎn)
//后面的數(shù)自動(dòng)去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
//算加上0.5,還是在小數(shù)點(diǎn)后面。
//}
//else
//{
tp=temp;//因?yàn)閿?shù)據(jù)處理有小數(shù)點(diǎn)所以將溫度賦給一個(gè)浮點(diǎn)型變量
//如果溫度是正的那么,那么正數(shù)的原碼就是補(bǔ)碼它本身
temp=tp*0.0625*100+0.5;
//留兩個(gè)小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語(yǔ)言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時(shí)候把小數(shù)點(diǎn)
//后面的數(shù)自動(dòng)去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
//算加上0.5,還是在小數(shù)點(diǎn)后面。
}
//}
void DS(temp)
{
float E1,E2,E;
E1=ch0_temp*17.942/255;
E2=temp*0.0065-0.0149;
E=E1+E2;
}
void ZWD(float E)
{
if(0<=E<1.874)
{
T=E*133.4;
}
else if(1.874<=E<5.239)
{
T=E*104.01+55.082;
}
else if(5.239<=E<9.014)
{
T=E*92.715+114.26;
}
else if(9.014<=E<13.159)
{
T=E*84.439+188.87;
}
else if(13.159<=E<17.942)
{
T=E*83.63+199.52;
}
//return T ;
}
// 0 1 2 3 4 5 6 7 8 9
//================================定時(shí)器0/1初始化函數(shù)================================
void T0_T1_init()
{
TMOD = 0x11;//定時(shí)器0/1均工作于方式1,16位計(jì)時(shí)方式
EA = 1;//開(kāi)總中斷
TR1=0; //打開(kāi)定時(shí)器
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
ET1=1;
}
//****1MS延時(shí)函數(shù)********
void delay(uint z)
{
uint i,j;
for(i=0;i<z;i++)
for(j=0;j<124;j++);
}
void lcdwc(uchar lcd_cmd) //液晶命令
{
lcden=0;
lcdrs=0;
lcdrw=0;
P0=lcd_cmd;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void lcdwd(uchar lcd_data) //液晶數(shù)據(jù)
{
lcden=0;
lcdrs=1;
lcdrw=0;
P0=lcd_data;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void lcdxy(uchar hlcd,uchar addlcd,uchar dtlcd) //液晶指定位置寫(xiě)數(shù)據(jù)
{
if (hlcd==1)
{
lcdwc(0x80+addlcd); //第一行地址
lcdwd(dtlcd);
}
else
{
lcdwc(0xc0+addlcd); //第二行地址
lcdwd(dtlcd);
}
}
void init_1602() //初始化
{
delay(5);
lcdwc(0x01);//清屏
lcdwc(0x38); //顯示模式
lcdwc(0x0c); //顯示開(kāi)
lcdwc(0x06); //顯示光標(biāo)移動(dòng)設(shè)置
}
void xs_ad(uint aaa,uint bbb,uint ccc)//顯示函數(shù)
{
lcdxy(1,0,'T');
lcdxy(1,1,'e');
lcdxy(1,2,'m');
lcdxy(1,3,'p');
//lcdxy(1,4,'u');
lcdxy(1,5,':');
lcdxy(1,6,aaa/1000+0x30); //測(cè)量值百位
lcdxy(1,7,aaa%1000/100+0x30); // 十位
lcdxy(1,8,aaa%1000%100/10+0x30);//個(gè)位
lcdxy(1,9,aaa%10+0x30);//個(gè)位
lcdxy(1,10,0xdf);//個(gè)位
lcdxy(1,11,'C');//個(gè)位
lcdxy(2,0,'L');
lcdxy(2,1,':');
lcdxy(2,2,bbb/1000+0x30); //測(cè)量值百位
lcdxy(2,3,bbb%1000/100+0x30); // 十位
lcdxy(2,4,bbb%1000%100/10+0x30);//個(gè)位
lcdxy(2,5,bbb%10+0x30);//個(gè)位
lcdxy(2,8,'H');
lcdxy(2,9,':');
lcdxy(2,10,ccc/1000+0x30); //測(cè)量值百位
lcdxy(2,11,ccc%1000/100+0x30); // 十位
lcdxy(2,12,ccc%1000%100/10+0x30);//個(gè)位
lcdxy(2,13,ccc%10+0x30);//個(gè)位
}
void key()//按鍵掃描
{
if(key1==0) //加按鍵按下
{
delay(2); //延時(shí),消除按鍵抖動(dòng)
if(key1==0)
{
while(!key1); //判斷按鍵可釋放
page++;
if(page>2)
page=0;
}
}
if(key2==0) //減同理
{
delay(2);
if(key2==0)
{
if(page==1)
{
MIN++;
if(MIN>1500)MIN=0;
}
if(page==2)
{
MAX++;
if(MAX>1500)MAX=0;
}
delay(1000);
while(!key2)
{
delay(10);
if(page==1)
{
MIN=MIN+10;
if(MIN>1500)MIN=0;
}
if(page==2)
{
MAX=MAX+10;
if(MAX>1500)MAX=0;
}
}
}
}
if(key3==0) //加按鍵按下
{
delay(2); //延時(shí),消除按鍵抖動(dòng)
if(key3==0)
{
if(page==1)
{
MIN--;
if(MIN<0)MIN=1500;
}
if(page==2)
{
MAX--;
if(MAX<0)MAX=1500;
}
delay(1000);
while(!key3)//判斷按鍵可釋放
{
if(page==1)
{
MIN=MIN-10;
if(MIN<0)MIN=1500;
}
if(page==2)
{
MAX=MAX-10;
if(MAX<0)MAX=1500;
}
}
}
}
}
//******主函數(shù)*********
void main()
{ long temp;
Init_DS18B20(); //DS18B20初始化
init_1602() ; //1602初始化
T0_T1_init(); //中斷
beep=0;
while(1)
{
key();
//datapros(Ds18b20ReadTemp()); //數(shù)據(jù)處理函數(shù)
//ch0_temp=2.69*adc0832(0)*55/25; //把測(cè)量的模轉(zhuǎn)換成數(shù)字量 線性化
xs_ad(T,MIN,MAX);
if((T<MIN)||(T>MAX))
{
TR1=1;
}
else
TR1=0;
}
}
void time1() interrupt 3 //蜂鳴器報(bào)警
{
static uchar count=0;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
count++;
if(count==4) //0.2S
{
count=0;
beep=~beep;
}
} |
|