📄 good2.c
字号:
/*该驱动程序是基于------ATMEL89C52-----单片机实现*/
#include<reg52.h>
#include<stdio.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6; //段选端口
sbit wela=P2^7; //位选端口
sbit dq=P2^2; //DS18B20数据端口
sbit feng=P2^3; //蜂鸣器
uint c1_temper,c2_temper; //记录两个温度传感器的温度
uint L_temper; //温度下限值
uint H_temper; //温度上限值
unsigned char aa[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //记录传感器A的序列号
unsigned char bb[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //记录传感器B的序列号
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f};
void delay_ms(uint z);
void delay_us();
void write_cmd(uchar z);
void get_firstid();
void get_seconedid();
void write_bit(uchar dd);
void deal_temper();
void deal_ds1();
void deal_ds2();
void display_temper(uint wengdu,uchar fc);
void init();
void warn_temper(uchar z);
uchar dq_reset();
uchar keyscanf();
uchar read_byte();
uint get_temper(uchar z);
uchar read_bit();
uchar read_date();
/******************延迟****************/
void delay_ms(uint z)//毫秒级的延迟
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void delay_us()//延时微秒
{
_nop_();
}
/*****************复位*************************/
uchar dq_reset()
{
uchar t;
uchar dd;
dq=0;
for(t=250;t>0;t--);
dq=1;
for(t=5;t>0;t--);
dd=dq;
for(t=150;t>0;t--);
return dd;
}
/******************(bit)位操作**********************/
uchar read_bit()//读一个位
{
uchar t;
uchar dd;
dq=0;
delay_us();delay_us();
dq=1;
for(t=3;t>0;t--);
dd=dq;//get the signal
for(t=20;t>0;t--);
return dd;
}
void write_bit(uchar dd)//写一个位
{
uchar t;
if(dd==1)
{
dq=0;
delay_us();
dq=1;
for(t=30;t>0;t--);
}
else
{
dq=0;
for(t=30;t>0;t--);
dq=1;
delay_us();
delay_us();
}
}
/********************字节操作**************************/
uchar read_byte()//读字节
{
uchar i;
uchar temp;
uchar dd;
temp=0x00;
for(i=0;i<8;i++)
{
temp=_cror_(temp,1);
dd=read_bit();
if(dd==1)
{
temp=temp|0x80;
}
else
{
temp=temp|0x00;
}
}
return(temp);
}
/******************命令与数据***********************/
void write_cmd(uchar z)//发送命令或数据
{
uchar i,t;
uchar temp;
uchar cd=z;
for(i=0;i<8;i++)
{
temp=cd&0x01;
if(temp)
{
dq=0;
delay_us();delay_us();//
dq=1;
for(t=40;t>0;t--);
}
else
{
dq=0;
for(t=40;t>0;t--);
dq=1;
delay_us(); delay_us();
}
cd=_cror_(cd,1);
}
}
/*****************温度******************************/
uint get_temper(uchar z)//从暂存器中获取温度值
{
uchar LSB_temper=0x00;
uchar MSB_temper=0x00;
uchar i;
uint c_temp=0;
float f_temp=0;
dq_reset();
write_cmd(0x55);
if(z==1)//发送传感A的序列号
{
for(i=1;i<=8;i++)
{
write_cmd(aa[i]);
}
}
else //发送传感器B的序列号
{
for(i=1;i<=8;i++)
{
write_cmd(bb[i]);
}
}
delay_ms(1);
write_cmd(0xbe);//读存储器内的温度
LSB_temper=read_byte();//读低温度字节
MSB_temper=read_byte();//读高温度字节
dq_reset();
c_temp=MSB_temper;
c_temp=(c_temp<<8);
c_temp=c_temp|LSB_temper;
f_temp=c_temp*0.0625;
c_temp=f_temp*10+0.5;
return (c_temp);
}
/******************获取序列号************************/
/*这里采用简单的“消除”算法*/
void get_firstid()//获取传感器A的序列号
{
uchar t;
uchar w=1;
uchar d1,d2;
uchar temp=0x00;
dq_reset();
write_cmd(0xf0);//搜索序列号命令
for(t=1;t<=64;t++)
{
d1=read_bit();
d2=read_bit();
temp=_cror_(temp,1);
if( (d1==1) && (d2==0) )
{
temp=temp|0x80;
write_bit(1);
}
else if( (d1==0) && (d2==1))
{
temp=temp|0x00;
write_bit(0);
}
else if( (d1==0) && (d2==0) )
{
temp=temp|0x00;
write_bit(0);
}
if(t%8==0)
{
aa[w]=temp;
w=w+1;
temp=0x00;
}
}
}
void get_seconedid() //获取传感器B的序列号
{
uchar t;
uchar w=1;
uchar d1,d2;
uchar temp=0x00;
dq_reset();
write_cmd(0xf0);//搜索序列号命令
for(t=1;t<=64;t++)
{
d1=read_bit();
d2=read_bit();
temp=_cror_(temp,1);
if( (d1==1) && (d2==0) )
{
write_bit(1);
temp=temp|0x80;
}
else if( (d1==0) && (d2==1))
{
write_bit(0);
temp=temp|0x00;
}
else if( (d1==0) && (d2==0) )
{
write_bit(1);
temp=temp|0x80;
}
if(t%8==0)
{
bb[w]=temp;
w=w+1;
temp=0x00;
}
}
}
/*******************温度处理**************************/
void deal_temper()
{
uchar key=0;
while(1)
{
key=keyscanf(); //键盘扫描
if(key!=0)
{
deal_ds1();//处理传感器A
deal_ds2();//处理传感器B
}
key=0;
}
}
void deal_ds1() //处理传感器A
{
uchar t;
uchar key;
while(1)
{
dq_reset(); //复位
write_cmd(0xcc); //跳过ROM命令
write_cmd(0x44);//温度转换命令
key=keyscanf();//检测按键
if(key==2) break;
c1_temper=get_temper(1);
if(c1_temper>H_temper) warn_temper(1); //传感器A温度超出上限则进入 warn_temper(1)警告函数
for(t=20;t>0;t--)
{
display_temper(get_temper(1),1); //显示传感器A的温度
}
}
}
void deal_ds2() //处理传感器B
{
uchar t;
uchar key;
while(1)
{
dq_reset();
write_cmd(0xcc); //跳过ROM命令
write_cmd(0x44);//温度转换
key=keyscanf();//按键检测
if(key==1) break;
if(c2_temper>H_temper) warn_temper(2);
for(t=20;t>0;t--)
{
display_temper(get_temper(2),2); //显示传感器B的温度
}
}
}
void warn_temper(uchar z) //温度警告函数
{
uchar t;
uint c_temper;
while(1)
{
feng=0; //蜂鸣器响
dq_reset();
write_cmd(0xcc); //跳过ROM命令
write_cmd(0x44);//温度转换
c_temper=get_temper(z);
for(t=5;t>0;t--)
{
display_temper(get_temper(z),z);
}
if(c_temper<H_temper)
{
feng=1; //关闭蜂鸣器
break;
}
}
}
/*********************键盘************************/
uchar keyscanf() //键盘扫描函数
{
uchar temp;
uchar ke=0;
P3=0xf7; //P3为4*4矩阵键盘与89C52单片机的接口
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0) //判断有无按键情况
{
switch(temp)
{
case 0xe0: ke=1;break;
case 0xd0: ke=2;break;
case 0xb0: ke=3;break;
case 0x70: ke=4;break;
}
temp=P3;
temp=temp&0xf0;
delay_ms(2);
}
return ke;
}
/******************温度显示***********************/
void display_temper(uint wengdu,uchar fc)//显示当前温度值
{
uchar xx,yy,zz;
uint temp;
temp=wengdu;
xx=temp/100;
yy=temp%100/10;
zz=temp%10;
wela=1;
P0=0xfe;
wela=0;
P0=0x00;
dula=1;
P0=table[xx];
dula=0;
delay_ms(1);
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
P0=0x00;
dula=1;
P0=(table[yy]+0x80);
dula=0;
delay_ms(1);
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
P0=0x00;
dula=1;
P0=table[zz];
dula=0;
delay_ms(1);
P0=0xff;
wela=1;
P0=0xdf;
wela=0;
P0=0x00;
dula=1;
P0=table[fc];
dula=0;
delay_ms(1);
}
/****************初始化与主函数******************/
void init()//初始化
{
L_temper=100;
H_temper=320; //设定上限温度
c1_temper=200; //随意定义的初值
c2_temper=200;
dula=0;
wela=0;
}
void main()
{
init();
while(1)
{
uchar t,k;
get_firstid(); //获取传感器A的序列号
get_seconedid(); //-------B---------
for(t=1;t<=8;t++) //通过流水灯,蜂鸣器,数码管观察是否获取了序列号。DS18B20家族码28H是固定的
{
P1=aa[t];
for(k=0;k<10;k++) { delay_ms(100);}
feng=0;
wela=1; P0=0xfe; wela=0;
delay_ms(2);
dula=1; P0=table[1]; dula=0;
delay_ms(100);
feng=1;
}
for(t=1;t<=8;t++)
{
P1=bb[t];
for(k=0;k<10;k++) delay_ms(100);
feng=0;
wela=1; P0=0xfe; wela=0;
delay_ms(2);
dula=1; P0=table[2]; dula=0;
delay_ms(100);
feng=1;
}
wela=1;P0=0xff;wela=0;
P1=0xff;
deal_temper(); //温度处理
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -