【小实验】C51单片机 DS18B20温度显示实验

实验内容: 

     利用单总线技术和数码管动态显示的原理,要求实现DS18B20温度采集并显示,能够设定温度值上限值27.5度,当超出上限值LED灯闪烁。 

 

实验前可先用protues绘制出原理图:

仿真图如下:

1408691656764ba4a9a9ec128fcdcf7a.jpeg

 

keil c51代码: 

#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^7;
sbit P2_0=P2^0;
sbit k2=P2^2;
sbit k4=P2^4;
sbit k3=P2^3;
uchar timp,F=0;
float c;
uchar a[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
uchar b[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
void delay5(uchar n)
{
do
	{
		_nop_();
		_nop_();
		_nop_();
		n--;
  }
  while(n);
}

void init_DS18B20()
{
  uchar x=0;
	DQ=0;
	delay5(120);
	DQ=1;
	delay5(16);
	delay5(80);
}

uchar readbyte()
{
  uchar i=0;
	uchar date=0;
	for(i=8;i>0;i--)
	{
	  DQ=0;
		delay5(1);
		DQ=1;
		date>>=1;
		if(DQ)
			date|=0x80;
		delay5(11);
	}
	return(date);
}

 void writebyte(uchar dat)
 {
	 uchar i=0;
	 for(i=8;i>0;i--)
	 {
		 DQ=0;
		 DQ=dat&0x01;
		 delay5(12);
		 DQ=1;
		 dat>>=1;
		 delay5(5);
	 }
 }

uchar retemp()
 {
   uchar a,b,tt;
	 uint t;
	 init_DS18B20();
	 writebyte(0xCC);
	 writebyte(0x44);
	 init_DS18B20();
   writebyte(0xCC);
	 writebyte(0xBE);
	 a=readbyte();
	 b=readbyte();
	 t=b;
	 t<<=8;
	 t=t|a;
	 if((t&0xf800)!=0xf800)
	 { F=0;
		 c=t*0.0625;
	 tt=t*0.0625;
	 timp=t*0.625-tt*10;
	 }
	 else
	 { F=1;
	   t=(~t)+1;
		 c=t*0.0625;
	 tt=t*0.0625;
	 timp=t*0.625-tt*10;
	 }
	 return tt;
 }

 void main()
 {
   uchar i,temp;
	 delay5(1000);
	 while(1)
	 {
	   temp=retemp();
		if(c>=25&&F==0)
			 P2_0=0;
		else
	     P2_0=1;
		 for(i=0;i<15;i++)
		 {
			 k2=1;k3=1;k4=1;
			 if(F==0)
		   P0=a[temp/100];
			 else
				 P0=a[10];
			 delay5(1000);
		   //	P2=0xfb;//11111011,0xfb
		   k2=0;k3=1;k4=1;
			 P0=a[temp%100/10];
		   delay5(1000);
			 //P2=0xf7;//11110111,0xf7
			 k2=1;k3=0;k4=1;
			 P0=b[temp%10];
			 delay5(1000);
		   //P2=0xf3;//11110011,0xf3
			 k2=0;k3=0;k4=1;
			 P0=a[timp];
		   delay5(1000);
			 
		 }
		 if(c>=25&&F==0)
				 P2_0=1;
			 else
	     P2_0=1;

	 }
 
 }

代码仅供参考,希望大家能够在此基础上优化代码,而不是ctrl+c,ctrl+v。

谢谢!!!

 

 

 

 

  • 4
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
C51单片机DS18B20温度传感器的通信可以使用1-Wire总线协议。以下是使用C语言编写的DS18B20温度转换程序示例: ``` #include <reg51.h> sbit DQ = P1^0; //定义1-wire总线的单个数据线 unsigned char temp; //存放温度值 void delay_us(unsigned int us) //延时函数,单位为微秒 { while(us--); } void init_ds18b20(void) //DS18B20初始化函数 { DQ = 1; delay_us(2); DQ = 0; delay_us(480); DQ = 1; delay_us(60); if(DQ == 0) //DS18B20存在 { delay_us(420); } } void write_byte(unsigned char dat) //写一个字节函数 { unsigned char i; for(i = 0; i < 8; i++) { DQ = 0; DQ = dat & 0x01; delay_us(60); DQ = 1; dat >>= 1; } } unsigned char read_byte(void) //读一个字节函数 { unsigned char i, dat = 0; for(i = 0; i < 8; i++) { dat >>= 1; DQ = 0; delay_us(6); DQ = 1; delay_us(9); if(DQ) { dat |= 0x80; } delay_us(55); } return dat; } void convert_ds18b20(void) //DS18B20温度转换函数 { init_ds18b20(); write_byte(0xcc); //跳过ROM操作 write_byte(0x44); //启动温度转换 } void read_ds18b20(void) //DS18B20读取温度函数 { unsigned char low, high; init_ds18b20(); write_byte(0xcc); //跳过ROM操作 write_byte(0xbe); //读取温度值 low = read_byte(); //读取温度低字节 high = read_byte(); //读取温度高字节 temp = ((high << 8) + low) * 0.0625; //计算温度值 } void main(void) { convert_ds18b20(); //启动温度转换 read_ds18b20(); //读取温度值 } ``` 上述程序中,init_ds18b20()函数用于初始化DS18B20,convert_ds18b20()函数用于启动温度转换,read_ds18b20()函数用于读取温度值。程序中使用了延时函数delay_us(),可以根据实际情况进行修改。在read_ds18b20()函数中,采用了16位计算温度值的方法,最后将结果乘以0.0625得到实际温度值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值