?? ds18b20.c
字號:
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P3^3; //定義DS18B20接口
int temp;
uchar flag1;
void display(unsigned char *lp,unsigned char lc);//數(shù)字的顯示函數(shù);lp為指向數(shù)組的地址,lc為顯示的個數(shù)
void delay();//延時子函數(shù),5個空指令
code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,
0x40,
0x39,
0x00};
//共陰數(shù)碼管顯示數(shù)的組成是 "0-9""0-9有小數(shù)點的" "-" "C" "空 表"
unsigned char l_tmpdate[8]={0,0,10,0,0,0,0,0};//定義數(shù)組變量,并賦值1,2,3,4,5,6,7,8,就是本程序顯示的八個數(shù)
int tmp(void);
void tmpchange(void);
void tmpwritebyte(uchar dat);
uchar tmpread(void);
bit tmpreadbit(void);
void dsreset(void);
void delayb(uint count);
void main() //主函數(shù)
{
uchar i;
int l_tmp;
while(1)
{
tmpchange(); //溫度轉(zhuǎn)換
l_tmp=tmp(); //讀取溫度值
if(l_tmp<0)
l_tmpdate[0]=20; //判斷溫度為負(fù)溫度,前面加"-"
else
{
l_tmpdate[0]=l_tmp/1000; //顯示百位,這里用1000,是因為我們之前乖以10了
if(l_tmpdate[0]==0)
l_tmpdate[0]=22;//判斷溫度為正溫度且沒有上百,前面不顯示,查表第12是空
}
l_tmp=l_tmp%1000;
l_tmpdate[1]=l_tmp/100;//獲取十位
l_tmp=l_tmp%100;
l_tmpdate[2]=l_tmp/10;//獲取個位再
l_tmpdate[2]+=10;//加入小數(shù)點,查表可得出有小數(shù)點的排在后10位,所以加10
l_tmpdate[3]=l_tmp%10;//獲取小數(shù)第一位
l_tmpdate[4]=21;
for(i=0;i<10;i++){ //循環(huán)輸出10次,提高亮度
display(l_tmpdate,5);
}
}
}
void display(unsigned char *lp,unsigned char lc)//顯示
{
unsigned char i; //定義變量
P2=0; //端口2為輸出
P1=P1&0xF8; //將P1口的前3位輸出0,對應(yīng)138譯門輸入腳,全0為第一位數(shù)碼管
for(i=0;i<lc;i++){ //循環(huán)顯示
P2=table[lp[i]]; //查表法得到要顯示數(shù)字的數(shù)碼段
delay(); //延時5個空指令
if(i==7) //檢測顯示完8位否,完成直接退出,不讓P1口再加1,否則進(jìn)位影響到第四位數(shù)據(jù)
break;
P2=0; //清0端口,準(zhǔn)備顯示下位
P1++; //下一位數(shù)碼管
}
}
void delay(void) //空5個指令
{
_nop_();_nop_();_nop_();_nop_();_nop_();
}
void delayb(uint count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
void dsreset(void) //DS18B20初始化
{
uint i;
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bit tmpreadbit(void) // 讀一位
{
uint i;
bit dat;
DS=0;i++; //小延時一下
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
uchar tmpread(void) //讀一個字節(jié)
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //讀出的數(shù)據(jù)最低位在最前面,這樣剛好//一個字節(jié)在DAT里
}
return(dat); //將一個字節(jié)數(shù)據(jù)返回
}
void tmpwritebyte(uchar dat)
{ //寫一個字節(jié)到DS18B20里
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) // 寫1部分
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //寫0部分
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //發(fā)送溫度轉(zhuǎn)換命令
{
dsreset(); //初始化DS18B20
delayb(1); //延時
tmpwritebyte(0xcc); // 跳過序列號命令
tmpwritebyte(0x44); //發(fā)送溫度轉(zhuǎn)換命令
}
int tmp() //獲得溫度
{
float tt;
uchar a,b;
dsreset();
delayb(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe); //發(fā)送讀取數(shù)據(jù)命令
a=tmpread(); //連續(xù)讀兩個字節(jié)數(shù)據(jù)
b=tmpread();
temp=b;
temp<<=8;
temp=temp|a; //兩字節(jié)合成一個整型變量。
tt=temp*0.0625; //得到真實十進(jìn)制溫度值,因為DS18B20
//可以精確到0.0625度,所以讀回數(shù)據(jù)的最低位代表的是
//0.0625度。
temp=tt*10+0.5; //放大十倍,這樣做的目的將小數(shù)點后第一位
//也轉(zhuǎn)換為可顯示數(shù)字,同時進(jìn)行一個四舍五入操作。
return temp; //返回溫度值
}
void readrom() //read the serial 讀取溫度傳感器的序列號
{ //本程序中沒有用到此函數(shù)
uchar sn1,sn2;
dsreset();
delayb(1);
tmpwritebyte(0x33);
sn1=tmpread();
sn2=tmpread();
}
void delay10ms()
{
uchar a,b;
for(a=10;a>0;a--)
for(b=60;b>0;b--);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -