⑴ DS18B20的程序
接上18B20溫度感測器後數碼管顯示出當前溫度
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P2^2; //define interface
uint temp; // variable of temperature
uchar flag1; // sign of the result positive or negative
sbit la=P2^6;
sbit wela=P2^7;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef};
void delay(uint count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
///////功能:串口初始化,波特率9600,方式///////
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;
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
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //write 0
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //DS18B20 begin change
{
dsreset();
delay(1);
tmpwritebyte(0xcc); // address all drivers on bus
tmpwritebyte(0x44); // initiates a single temperature conversion
}
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;
temp=tt*10+0.5;
return temp;
}
void readrom() //read the serial
{
uchar sn1,sn2;
dsreset();
delay(1);
tmpwritebyte(0x33);
sn1=tmpread();
sn2=tmpread();
}
void delay10ms() //delay
{
uchar a,b;
for(a=10;a>0;a--)
for(b=60;b>0;b--);
}
void display(uint temp) //顯示程序
{
uchar A1,A2,A2t,A3,ser;
ser=temp/10;
SBUF=ser;
A1=temp/100;
A2t=temp%100;
A2=A2t/10;
A3=A2t%10;
la=0;
P0=table[A1]; //顯示百位
la=1;
la=0;
wela=0;
P0=0x7e;
wela=1;
wela=0;
delay(1);
la=0;
P0=table1[A2]; //顯示十位
la=1;
la=0;
wela=0;
P0=0x7d;
wela=1;
wela=0;
delay(1);
P0=table[A3]; //顯示個位
la=1;
la=0;
P0=0x7b;
wela=1;
wela=0;
delay(1);
}
void main()
{
uchar a;
Init_Com();
do
{
tmpchange();
// delay(200);
for(a=10;a>0;a--)
{ display(tmp());
}
} while(1);
}
⑵ 18b20和51單片機實現溫度顯示,求程序
//按照我的電路圖我這是四位有負溫度顯示你可以看一下。有什麼問題可以問我?
/********************************************************************
created:2010/07/27
created:27:7:201010:27
filename:D:KeilDebugds18b20.c
filepath:D:KeilDebug
filebase:ds18b20
fileext:c
author:HonguoZHU
purpose:
//DS18B20的讀寫程序,數據腳P2.7
//溫度感測器18B20匯編程序,採用器件默認的12位轉化
//最大轉化時間750微秒,顯示溫度-55到+125度,顯示精度
//為0.1度,顯示採用4位LED共陽顯示測溫值
//P0口為段碼輸入,P34~P37為位選
**************************************************/
#include"reg51.h"
#include"intrins.h"//_nop_();延時函數用
#defineDisdataP0//段碼輸出口
#definediscanP3//掃描口
#defineucharunsignedchar
#defineuintunsignedint
#defineREADROM_18b20_CM0x33
#defineMATCHROM_18b20_CM0x55
#defineSKIPROM_18b20_CM0xCC
#defineSEARCHROM_18b20_CM0xF0
#defineALARMSEARCH_18b20_CM0xEC
#defineCONVERTT_CM0x44
#defineRSCRATCHPAD_CM0xBE
#defineWSCRATCHPAD_CM0x4E
#defineCSCRATCHPAD_CM0x48
#defineRECALLE2_CM0xB8
#defineRPOWERSUNNLY_CM0xB4
sbitDQ=P2^7;//溫度輸入口
sbitDIN=P0^7;//LED小數點控制
//
//
//**************溫度小數部分用查表法***********//
ucharcodeditab[16]=
{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//
ucharcodedis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
//共陽LED段碼表"0""1""2""3""4""5""6""7""8""9""不亮""-"
ucharcodescan_con[4]={0x8f,0x4f,0x2f,0x1f};//列掃描控制字
uchardatatemp_data[2]={0x00,0x00};//讀出溫度暫放
uchardatadisplay[5]={0x00,0x00,0x00,0x00,0x00};//顯示單元數據,共4個數據和一個運算暫用
//
//
//
/*****************11us延時函數*************************/
//
voiddelay(uintt)
{
for(;t>0;t--);
}
//
/****************顯示函數******************************/
scan()
{
chark;
for(k=0;k<4;k++)//4位LED掃描控制
{
Disdata=0xff;//
discan=scan_con[k];//位選
Disdata=dis_7[display[k]];//數據顯示
if(k==1)
{
DIN=0;
}//小數點顯示
delay(300);
}
}
//
//
/****************DS18B20復位函數************************/
ow_reset(void)
{
charpresence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();//從高拉倒低
DQ=0;
delay(50);//550us
DQ=1;
delay(6);//66us
presence=DQ;//presence=0復位成功,繼續下一步
}
delay(45);//延時500us
presence=~DQ;
}
DQ=1;//拉高電平
}
//
//
/****************DS18B20寫命令函數************************/
//向1-WIRE匯流排上寫1個位元組
voidwrite_byte(ucharval)
{
uchari;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();//從高拉倒低
DQ=0;_nop_();_nop_();_nop_();_nop_();//5us
DQ=val&0x01;//最低位移出
delay(6);//66us
val=val/2;//右移1位
}
DQ=1;
delay(1);
}
//
/****************DS18B20讀1位元組函數************************/
//從匯流排上取1個位元組
ucharread_byte(void)
{
uchari;
ucharvalue=0;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ=0;_nop_();_nop_();_nop_();_nop_();//4us
DQ=1;_nop_();_nop_();_nop_();_nop_();//4us
if(DQ)
{value|=0x80;}
delay(6);//66us
}
DQ=1;
return(value);
}
//
/****************讀出溫度函數************************/
//
uintread_temp()
{
uinttemp;
//ow_reset();//匯流排復位
//delay(200);
//write_byte(SKIPROM_18b20_CM);//發命令
//write_byte(CONVERTT_CM);//發轉換命令
ow_reset();
delay(1);
write_byte(SKIPROM_18b20_CM);//發命令
write_byte(RSCRATCHPAD_CM);
temp_data[0]=read_byte();//讀溫度值的第位元組
temp_data[1]=read_byte();//讀溫度值的高位元組
temp=temp_data[1];
temp<<=8;
temp=temp|temp_data[0];//兩位元組合成一個整型變數。
returntemp;//返回溫度值
}
//
/****************溫度數據處理函數************************/
//二進制高位元組的低半位元組和低位元組的高半位元組組成一位元組,這個
//位元組的二進制轉換為十進制後,就是溫度值的百、十、個位值,而剩
//下的低位元組的低半位元組轉化成十進制後,就是溫度值的小數部分
/********************************************************/
work_temp(uinttem)
{
ucharn=0;
if(tem>6348)//溫度值正負判斷
{
tem=65536-tem;
n=1;
}//負溫度求補碼,標志位置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;
/******************符號位顯示判斷**************************/
if(!display[3])
{
display[3]=0x0a;//最高位為0時不顯示
if(!display[2])
{
display[2]=0x0a;//次高位為0時不顯示
}
}
if(n)
{
display[3]=0x0b;
}//負溫度時最高位顯示"-"
}
//
//
/****************主函數************************/
main()
{
uinth;
Disdata=0xff;//初始化埠
discan=0xff;
for(h=0;h<4;h++)//開機顯示"0000"
{display[h]=0;}
ow_reset();//開機先轉換一次
write_byte(SKIPROM_18b20_CM);//SkipROM
write_byte(CONVERTT_CM);//發轉換命令
for(h=0;h<100;h++)//開機顯示"0000"
{scan();}
while(1)
{
work_temp(read_temp());//處理溫度數據
scan();//顯示溫度值
}
}
//
//***********************結束**************************//