51蛋骗鸡DS18B20测温

ds18b20时序图

#include<intrins.h>
#include"peizhi/WenDu_DS18B20.H"
//extern bit Bz;	/*调用主文件变量*/
extern bit Xz;
void YanShiUs(unsigned int j){while(--j);}
bit ChuShiHua_DS18B20(/*单总线初始化时序*/)
{
	bit i;
	if(!Xz)DS0 = 1; else DS1 = 1;
	_nop_();
	if(!Xz)DS0 = 0; else DS1 = 0;
	YanShiUs(75); //拉低总线499.45us 挂接在总线上的18B20将会全部被复位
	if(!Xz)DS0 = 1; else DS1 = 1; //释放总线,如果DS18B20做出反应会将在15us~60us后总线拉低
	YanShiUs(4);  //延时37.95us 等待18B20发回存在信号
	i = Xz?DS1:DS0;		  //DS18B20拉低总线,赋值作为判断
	YanShiUs(20); //等待141.95us
	/*while(DS){YanShiMs(5); i=1;	}	初始化失败标志*/
	if(!Xz)DS0 = 1; else DS1 = 1;
	_nop_(); /**/
	return (i);
}

void DS18B20_Xie_ZhiJie(unsigned int ZhiJie/*写一个字节*/)
{
	unsigned char i=8;
	do
	{
		if(!Xz)DS0 = 0; else DS1 = 0;				 //每写入一位数据之前先把总线拉低
		_nop_();             //产生5us时序
		if(!Xz)DS0 = ZhiJie & 0x01;	 //然后写入一个数据,从最低位开始
		else   DS1 = ZhiJie & 0x01;	 //然后写入一个数据,从最低位开始
		YanShiUs(10);        //76.95us
					         //11.0592Mz的晶振一个机器周期时间1.085us,12*1/11059200一个循环2.17US
		if(!Xz)DS0 = 1; else DS1 = 1; //释放总线至少1us给总线恢复时间才能准备下一个数据写入
		_nop_();			 //指令ZhiJie的最低位赋予给总线,必须在拉低总线后的15us内,因为15us后DS18B20会对总线采样。
		ZhiJie >>= 1;		 //数据右移
	}while(--i);
}

unsigned int DS18B20_Du_ZhiJie(/*读数据字节*/)
{
	unsigned char i = 8, j; unsigned int ZhiJie;
	do
	{
		if(!Xz)DS0 = 0; else DS1 = 0;		 //先将总线拉低1us
		_nop_();     //产生读时序
		if(!Xz)DS0 = 1; else DS1 = 1;		 //释放总线
		_nop_();     //读数据时,数据以字节的最低有效位先从总线移出
		j = Xz?DS1:DS0;		 //读取数据,从最低位开始读取
		YanShiUs(10);//76.95us
		if(!Xz)DS0 = 1; else DS1 = 1;
		_nop_();/*将ZhiJie右移一位,然后与逻辑运算左移7位后的J,注意移动之后移掉那位补0。*/
		ZhiJie = (j<<7)|(ZhiJie>>1);	
	}while(--i);
	return (ZhiJie);
}

void DS18B20_Xie(bit X/*发送读取温度命令*/)
{	
	ChuShiHua_DS18B20();        //初始化DS18B20  
	DS18B20_Xie_ZhiJie(0xcc);   //发送跳过ROM操作命令
	DS18B20_Xie_ZhiJie(X?0xbe:0x44);   //发送读取DS18B20暂存器值命令/发送温度转换指令
}

unsigned int DS18B20_WenDu(/*Ds18b20转换温度*/)
{
	unsigned int L,M,i;
	DS18B20_Xie(0);          //先写入转换命令
	DS18B20_Xie(1);		     //然后等待转换完后发送读取温度命令
	L = DS18B20_Du_ZhiJie(); //读取温度值共16位,先读低字节,读取到的第一个字节为温度LSB
	M = DS18B20_Du_ZhiJie(); //再读高字节,读取到的第一个字节为温度MSB
	i = M;
	i <<= 8;				 //把以上8位数据从i低八位移到高八位
	i |= L;					 //两字节合成一个整型变量	
	if(i > 2048)             //当温度值为负数				
	{
//		Bz = 1; 
		//--i;i ^= 0xffff;//因为读取的温度是实际温度的补码,所以减1,再异或求出原码
		i=~i;++i; //负数的绝对值等于: 取反 + 1
		i = i * 0.0625 * 100 + 0.5;	
		/*留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
		后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
		算加上0.5,还是在小数点后面。*/
	}
 	else {i = i * 0.0625 * 100 + 0.5;}//Bz = 0;
  	//因为数据处理有小数点所以将温度赋给一个浮点型变量,如果温度是正的那么正数的原码就是补码它本身
	return (i);
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一些关于51单片机DS18B20测温以及LCD显示的基本知识和代码实现。 1. DS18B20测温原理 DS18B20是一款数字温度传感器,采用单总线接口进行通信,具有精度高、精度可调、线长可达100米等特点,常用于温度测量和控制领域。 DS18B20测温的原理是通过传感器内部的温度传感器将温度转换成数字信号,然后通过单总线接口将数字信号发送到单片机单片机再将数字信号转化为实际温度值进行处理。 2. 51单片机DS18B20测温的连接 DS18B20采用单总线接口进行通信,与51单片机的连接如下: - DS18B20的VCC引脚连接到51单片机的5V电源 - DS18B20的GND引脚连接到51单片机的GND - DS18B20的DQ引脚连接到51单片机的任意I/O口 需要注意的是,DS18B20的DQ引脚需要使用上拉电阻将其拉高。 3. 51单片机和LCD显示的连接 51单片机和LCD显示的连接如下: - LCD的VSS引脚连接到51单片机的GND - LCD的VDD引脚连接到51单片机的5V电源 - LCD的VEE引脚连接到51单片机的可调电位器 - LCD的RS引脚连接到51单片机的任意I/O口 - LCD的RW引脚连接到51单片机的任意I/O口 - LCD的E引脚连接到51单片机的任意I/O口 - LCD的D0-D7引脚连接到51单片机的任意I/O口 需要注意的是,LCD的VEE引脚需要通过可调电位器进行调节,以控制LCD显示的亮度。 4. 代码实现 下面是51单片机通过DS18B20测温并通过LCD显示温度值的代码实现: ``` #include <reg52.h> #include <intrins.h> #define LCD_DPORT P0 sbit LCD_RS = P1^0; sbit LCD_RW = P1^1; sbit LCD_E = P1^2; sbit DQ = P3^7; void delay(unsigned int i) //延时函数 { while(i--); } void lcd_init() //LCD初始化函数 { delay(1000); lcd_cmd(0x38); lcd_cmd(0x0c); lcd_cmd(0x06); lcd_cmd(0x01); } void lcd_cmd(unsigned char cmd) //LCD指令函数 { LCD_RS = 0; LCD_RW = 0; LCD_DPORT = cmd; delay(5); LCD_E = 1; _nop_(); _nop_(); LCD_E = 0; delay(5); } void lcd_data(unsigned char dat) //LCD数据函数 { LCD_RS = 1; LCD_RW = 0; LCD_DPORT = dat; delay(5); LCD_E = 1; _nop_(); _nop_(); LCD_E = 0; delay(5); } void lcd_string(unsigned char *str) //LCD字符串函数 { while(*str != '\0') { lcd_data(*str); str++; } } void lcd_float(float f) //LCD浮点数函数 { unsigned char str[16]; sprintf(str, "%f", f); lcd_string(str); } unsigned char ds18b20_read() //DS18B20读取函数 { unsigned char i; unsigned char dat = 0; for(i = 0; i < 8; i++) { DQ = 0; _nop_(); _nop_(); dat >>= 1; DQ = 1; _nop_(); _nop_(); if(DQ == 1) { dat |= 0x80; } _nop_(); _nop_(); } return dat; } void ds18b20_write(unsigned char dat) //DS18B20写入函数 { unsigned char i; for(i = 0; i < 8; i++) { DQ = 0; _nop_(); _nop_(); if(dat & 0x01) { DQ = 1; } dat >>= 1; _nop_(); _nop_(); DQ = 1; _nop_(); _nop_(); } } void ds18b20_convert() //DS18B20转换函数 { ds18b20_write(0xcc); ds18b20_write(0x44); } void main() //主函数 { unsigned char temp_l, temp_h; int temp; float ftemp; lcd_init(); while(1) { ds18b20_convert(); delay(1000); ds18b20_write(0xcc); ds18b20_write(0xbe); temp_l = ds18b20_read(); temp_h = ds18b20_read(); temp = temp_h; temp <<= 8; temp |= temp_l; ftemp = (float)temp / 16.0; lcd_cmd(0x01); lcd_string("Temp: "); lcd_float(ftemp); lcd_string(" C"); delay(1000); } } ``` 上述代码实现了通过DS18B20测温并通过LCD显示温度值。其中ds18b20_convert()函数用于触发DS18B20转换温度值,ds18b20_write()函数用于向DS18B20写入命令或数据,ds18b20_read()函数用于从DS18B20读取温度值。同时,lcd_float()函数可以将浮点数转化为字符串并在LCD上显示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值