DS18B20使用心得 反码 补码 原码

这篇博客详细介绍了DS18B20温度传感器的编程实现,包括初始化过程、写入和读取函数的编写。初始化涉及到GPIO配置和时序控制,确保了数据传输的正确性。同时,博客还阐述了温度数据的表示方式,16位带符号扩展的二进制补码形式,并提供了读取温度的函数,将补码转换为浮点温度值。
摘要由CSDN通过智能技术生成

1.

DS18B20温度传感器和DHT11类似 也是单总线进行数据的传输和控制

2. 编程 反码补码原码

1.反码补码原码

最高位为1 表示负数
最高位为0 表示正数

正数的原码的补码就是原码本身
负数的原码的补码是原码的反码加1

负数:
负数的补码反码的首位都是 表示为1

例如得到的是-5
表示的是1000 0000 0101 0000
补码进行表示的就是
        1111 1111 1010 1111
        1111 1111 1011 0000
得到的补码如下
但是我们要得到原码 需要进行转换 即通过补码的反码加一
        1000 0000 0100 1111
		1000 0000 0101 0000
		得到负数现在的函数值
负数的原码 = 负数补码的反码 +1
负数的补码 = 负数原码的反码 +1

编程实现DS18B20

在这里插入图片描述
在每次调用,都需要进行初始化
创建初始化
因为需要读取数据和作为主机拉高
因此需要设置两种不同的GPIO输入输出模式
分别设置为推挽输出 和 上拉电阻输入
在这里插入图片描述

初始化过程的体现

主机向DS18B20发送低电平的时间为480us到960us
ds18b20等待信号的时间是15us到60us
ds18b20发送响应脉冲的信号是60us-240us
ds18b20进行读取的最短时间大于480us

在这里插入图片描述

15 75   15 255   60 120 60 300
因此得到的区间是60us到75us所有的等待时间都会经过此处
uint8_t DS18B20_Init(void)
{
	DS18B20_GPIO_Config ();
	
	DS18B20_DQ_1;     //先将DQ设置成高电平
	
	return DS18B20_Process();
}
static uint8_t DS18B20_Process(void)
{
	uint8_t stat=0;
	/* 将主机STM32设置成推挽输出*/
	DS18B20_Mode_Out_PP();
	
	/*产生一个大于480us小于960us的低电平复位信号*/
	DS18B20_DQ_0;
	DS18B20_DELAY_US(750);
	
	/*产生复位信号后,将电平拉高*/
	DS18B20_DQ_1;
	
	/*根据上面的区间进行推测 */
	DS18B20_DELAY_US(68);
	
	/*读取当前状态值 设置成上拉输入*/
	DS18B20_Mode_IPU();
	
	/* 读取当前的状态值*/
	stat=DS18B20_DQ_IN();
	
	/*延时Rx必须大于480us*/
	DS18B20_DELAY_US(500);
	
	return stat;
}

写函数的实现

在这里插入图片描述
写时序
DS18B20写入和读取都是LSB先行
每次写入的时间大于60us
写入0
主机发送一个60us-120us的低电平,然后延时一个大于1us的恢复时间
写入1
主机发送大于1us小于15us的低电平,然后延时让写入时间大于60us

static void DS18B20_WriteByte(uint8_t dat)
{
 uint8_t i,testb;
 /*设置成输出模式*/
 DS18B20_Mode_Out_PP();
 for(i=0;i<8;i++){
  testb = dat&0x01;//
  dat =dat >>1;
  if(testb ){
    DS18B20_DQ_0;
    DS18B20_DELAY_US(5);
    DS18B20_DQ_1;
    DS18B20_DELAY_US(58);
  }else{
    DS18B20_DQ_0;
    DS18B20_DELAY_US(80);
    DS18B20_DQ_1;
    DS18B20_DELAY_US(2);
  }
 }
}

读函数的实现

在这里插入图片描述
读时序
在第一个15us进行bit的读取
主机发送低电平信号的时间大于1us小于15us
读取一次的时间大于60us
当读取到的是0 则为低电平
当读取到的是1 则为高电平

static uint8_t DS18B20_ReadBit(void)
{
	uint8_t dat;
	
	/* 读0和读1的时间至少要大于60us */	
	DS18B20_Mode_Out_PP();
	/* 读时间的起始:必须由主机产生 >1us <15us 的低电平信号 */
	DS18B20_DQ_0;
	DS18B20_DELAY_US(10);

	/* 设置成输入,释放总线,由外部上拉电阻将总线拉高 */
	DS18B20_Mode_IPU();
//	DS18B20_DELAY_US(2); 
	/* 在第一段时间的15us 里 总线拉低的时间必须小于15us 然后读取ds18b20的值 */
	/* 总线在第一阶段的15us拉低 可以在第二个阶段的开始读取状态也可以直接读取状态值 */
	/* 判断此时ds18b20的值 */
	if( DS18B20_DQ_IN() == SET )
		dat = 1;
	else
		dat = 0;
	
	/* 这个延时参数请参考时序图 */
	DS18B20_DELAY_US(60); //保证读取一个的时间大于60us
	
	return dat;
}

温度的表示

在这里插入图片描述

/*
 * 存储的温度是16 位的带符号扩展的二进制补码形式
 * 当工作在12位分辨率时,其中5个符号位,7个整数位,4个小数位
 *
 *         |---------整数----------|-----小数 分辨率 1/(2^4)=0.0625----|
 * 低字节  | 2^3 | 2^2 | 2^1 | 2^0 | 2^(-1) | 2^(-2) | 2^(-3) | 2^(-4) |
 *
 *
 *         |-----符号位:0->正  1->负-------|-----------整数-----------|
 * 高字节  |  s  |  s  |  s  |  s  |    s   |   2^6  |   2^5  |   2^4  |
 *
 * 
 * 温度 = 符号位 + 整数 + 小数*0.0625
 */
 /**
  * @brief  在跳过匹配 ROM 情况下获取 DS18B20 温度值 
  * @param  无
  * @retval 温度值
  */
float DS18B20_GetTemp_SkipRom ( void )
{
	uint8_t tpmsb, tplsb;
	short s_tem; /* 占用两个字节 */
	float f_tem; /* 占用四个字节 */
	
	
	DS18B20_SkipRom ();
	DS18B20_WriteByte(0X44);				/* 开始转换 */
	
	
	DS18B20_SkipRom ();
  DS18B20_WriteByte(0XBE);				/* 读温度值 */
	
	/* ds18b20是低位先行因此先写入低8位 */
	tplsb = DS18B20_ReadByte();	
  /* 后写入高8位 */	
	tpmsb = DS18B20_ReadByte(); 
	
	
	s_tem = tpmsb<<8; /* 左移8位 */
	s_tem = s_tem | tplsb;/* 相或 */
	/* 0也可以写成2048*/
	if( s_tem < 0 )		/* 负温度 */
		f_tem = (~s_tem+1) * 0.0625;	
		f_tem = -f_tem;
	else
		f_tem = s_tem * 0.0625; 
	/* 2~0*0.0625
	   2~1*0.0625=0.125
	   2~2*0.0625=0.25
	   2~3*0.0625=0.5
	   2*4*0.0625=1
	   2~5*0.0625=2
	   ...........
	
	   通过上面的计算可以求得现在的温度的大小
	*/
	
	return f_tem; 	
	
	
}
在这里 负数是通过补码显示出来的 
因此看到的是FF..
进行计算温度需要转换成原码进行计算
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值