?? ds18b20.c
字號:
#include<reg51.h>
#include<intrins.h> //_nop_();延時函數用;
#define Disdata P0 //段碼輸出口
#define discan P2 //掃描口
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P1^0; //溫度輸入口
sbit DIN=P0^7; //led 小數點控制
sbit P20=P2^0;
sbit P37=P3^7;
uint h,count,jingjie1,jingjie2,jingjie;
uchar sound;
//****溫度小數部分用查表法***//
uchar code ditab[16]=
{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,
0x08,0x08,0x09,0x09};
uchar code dis_7[12]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
/*"0","1", "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"*/
uchar code scan_con[4]={0x80,0x40,0x20,0x10}; //位控
uchar data temp_data[2]={0x00,0x00}; //讀出溫度暫放
uchar data display[5]={0x00,0x00,0x00,0x00,0x00};//顯示單元數據,共4個,一個運算暫存用
/***11us延時函數****/
void delay(uint t)
{
for(;t>0;t--);
}
/***顯示掃描函數***/
scan()
{
char k;
for(k=0;k<4;k++)
{
Disdata =dis_7[display[k]];
if(k==1){DIN=0;}
discan=scan_con[k];delay(90);discan=0x00;
}
}
/****DS18B20復位函數***/
ow_reset(void)
{
char presence =1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();
DQ=0;
delay(50);
DQ=1;
delay(6);
presence=DQ;
}
delay(45);
presence=~DQ;
}
DQ=1;
}
/****DS18B20寫命令函數****/
void write_byte(uchar val)
{
uchar i;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_();//延時5us
DQ=val&0x01; //取出最低位
delay(6);
val=val/2;
}
DQ=1;
delay(1);
}
/******DS18B20讀1字節函數****/
uchar read_byte(void)
{
uchar i;
uchar value =0;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ=0;
_nop_();_nop_();_nop_();_nop_();
DQ=1;_nop_();_nop_();_nop_();_nop_();
if(DQ) value|=0x80;
delay(6);
}
DQ=1;
return(value);
}
/*****讀出溫度函數****/
read_temp()
{
ow_reset();
write_byte(0xcc);
write_byte(0xbe);
temp_data[0]=read_byte();
temp_data[1]=read_byte();
ow_reset();
write_byte(0xcc);
write_byte(0x44);
}
/****溫度數據處理函數*****/
work_temp()
{
uchar n=0;
if(temp_data[1]>127)
//以下一行是負溫度求補碼
{temp_data[1]=(256-temp_data[1]);temp_data[0]=(256-temp_data[0]);n=1;}
display[4]=temp_data[0]&0x0f;display[0]=ditab[display[4]];
//顯示小數一位,由于小數是16進制,所以要簡化成10進制--ditab
jingjie2=display[4];
display[4]= ((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
//右移4位變成低四位 "或合并" 左移4位變成高四位
jingjie1=display[4];
jingjie=(jingjie1<<4)|(jingjie2);
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]=0x00;if(! display[2]){display[2]=0x00;}}
//最高位為0時都不顯示
if(n){display[3]=0x40;}
}
/****中斷獲得發聲頻率*****/
void initial()
{
TMOD=0x01;
TH0=(65536-500)/256;
TL0=(65536-500)%256;
EA=1;
ET0=1;
TR0=0;
}
/****主函數*****/
main()
{initial();
P37=0;
Disdata=0x00;
discan=0x00; //初始化端口
for(h=0;h<4;h++){ display[h]=8;} //開機顯示888
ow_reset(); //開機先轉換一次
write_byte(0xcc);
write_byte(0x44);
for(h=0;h<500;h++)
{scan();}
while(1)
{TR0=0;
P37=0;
read_temp();
work_temp();
for(h=0;h<250;h++) //顯示溫度1s
{scan();
if((jingjie1>=25&jingjie2>=1)|jingjie1>=26){TR0=1;}
//只要溫度超過25.1度就會響鈴
}
}
}
void tO(void) interrupt 1
{TH0=(65536-100)/256;
TL0=(65536-100)%256;
P37=~P37;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -