📄 ds18b20_c51.c
字号:
#include <reg51.h>
#define uchar unsigned char
uchar bdata write_char;
uchar bdata read_char;
sbit read_b=read_char^7;
sbit write_b=write_char^0;
uchar ds1820[9];//存放从DS18B20读取的9字节数据
uchar rom_code[8];//存放DS18B20的64位序列号
uchar i,crc;
uchar dot;
const uchar led_code[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//存放LED的显示码
uchar LED[5]={0x3f,0x3f,0x3f,0x3f,0x3f};
sbit DQ=P1^0;
sbit PSW_5=PSW^5;
unsigned int ds1820_temp;//存放温度读数
uchar *asc2p;
uchar shift;
int kk=0,initnum;
sbit p00=P0^1;
void delay15u(int x)
{
uchar data i=1;
while(--x){while(i!=0)i--;}
}
void reset_1820()
{
DQ=0;delay15u(32);DQ=1;
delay15u(4);PSW_5=0;
if(DQ==0)PSW_5=1;
}
void LED_write(uchar tem)
{
P2=tem;//输出
}
void write_1820(uchar x)
{
uchar i;
write_char=x;
for(i=0;i<8;i++){
DQ=0;delay15u(1);DQ=write_b;
write_char>>=1;delay15u(1);
DQ=1;
}
}
void start_convert()
{
initnum=0;PSW_5=0;
while(!PSW_5&&initnum++<10)reset_1820();if(initnum>10)return;
delay15u(256);write_1820(0xcc);write_1820(0x44);
}
int read_1820()
{
uchar i;
for(i=0;i<8;i++){
DQ=0;DQ=1;
delay15u(1);
read_char>>=1;read_b=DQ;DQ=1;
}
return read_char;
}
void get_temperature()
{
int i;
for(i=0;i<9;i++)ds1820[i]=0x00;
while(DQ!=1)initnum=0;PSW_5=0;
while(!PSW_5&&initnum++<10)reset_1820();if(initnum>9)return;
delay15u(256);write_1820(0xcc);write_1820(0xbe);
for (i=0;i<9;i++)
{
ds1820[i]=read_1820();
}
reset_1820();
}
void ds1820_match(unsigned char *p)
{
unsigned char i;
reset_1820();
write_1820(0x55);
for(i=0;i<8;i++)
write_1820(p[i]);
}
unsigned char crccheck(unsigned char *p,unsigned char len)
{
unsigned char bit0,cbit,r,temp,i,j,byte;
temp=0;
for (j=0;j<len;j++)
{
byte=p[j];
for(i=0;i<8;i++)
{
cbit=temp&0x01;
bit0=byte&0x01;
temp=temp>>1;
r=cbit^bit0;
if(r==1)
temp=temp^0x8c;
byte=byte>>1;
}
}
return temp;
}
void delay_ms(int time)
{
do
{
delay15u(70);time--;
}
while (time>1);
}
void asc2con(unsigned char *p)
{
unsigned char temp;
temp=p[1]&0xf0;temp=temp>>4;
LED[1]=led_code[temp];
temp=p[1]&0x0f;
LED[2]=led_code[temp];
temp=p[2]&0xf0;
temp=temp>>4;
LED[3]=led_code[temp];
temp=p[2]&0x0f;
LED[4]=led_code[temp];
delay_ms(2000);
temp=p[3]&0xf0;
temp=temp>>4;
LED[1]=led_code[temp];
temp=p[3]&0x0f;
LED[2]=led_code[temp];
temp=p[4]&0xf0;
temp=temp>>4;
LED[3]=led_code[temp];
temp=p[4]&0x0f;
LED[4]=led_code[temp];
delay_ms(2000);
temp=p[5]&0xf0;
temp=temp>>4;
LED[1]=led_code[temp];
temp=p[5]&0x0f;
LED[2]=led_code[temp];
temp=p[6]&0xf0;
temp=temp>>4;
LED[3]=led_code[temp];
temp=p[6]&0x0f;
LED[4]=led_code[temp];
delay_ms(2000);
}
void service2(void) interrupt 3
{kk=kk%5;
shift=(1<<kk);
P0=0xff-shift;
LED_write(LED[kk]);
kk++;
}
void main(void)
{
TMOD=0x20;
TL1=0x00; //波特率为9600
TH1=0x00;
LED[0]=0x3f;
LED[1]=0x06;
LED[2]=0x5b;
LED[3]=0x4f;
LED[4]=0x66;
TR1=1;
IE=0X88;
delay_ms(1000);
write_1820(0x33);
for (i=0;i<8;i++)
{
rom_code[i]=read_1820();//读出64位序列号
}
asc2p=&rom_code[0];
crc=crccheck(asc2p,8); //计算CRC校验和
asc2p=&rom_code[0];
asc2con(asc2p);
delay_ms(4000); //延时
if (crc==0x00) //CRC校验正确,显示序列号
{
asc2p=&rom_code[0];
asc2con(asc2p);
delay_ms(1000); //延时
}
start_convert();
get_temperature();
/* asc2p=&rom_code[0];
ds1820_match(asc2p);//匹配DS182
write_1820(0x44); //启动DS1820转换
delay_ms(1000); //延时ms
write_1820(0xbe); //读转换后温度
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -