赞
踩
关于DS18B20的详细介绍说明已经转移到这组文章下
GND -> GND
P35 -> DQ
3.3V -> VDD
这个模式下
GND -> GND -> VDD
P35 -> DQ
5V
寄生模式下, 发起温度转换后不能查询完成情况, 如果查询, 会导致测温不成功, 读数不变, 需要等待一个合理的时间, 例如1000毫秒, 然后直接读出温度值.
代码可以从GitHub或者Gitee下载
只需要一个Pin, 在STC8H中, 注意要将其设置为上拉, 否则读出来的全是0
#define DS18B20_DQ P35
#define DS18B20_DQ_PULLUP() GPIO_SetPullUp(GPIO_Port_3, GPIO_Pin_5, HAL_State_ON)
#define DS18B20_DQ_INPUT() GPIO_P3_SetMode(GPIO_Pin_5, GPIO_Mode_Input_HIP)
#define DS18B20_DQ_OUTPUT() GPIO_P3_SetMode(GPIO_Pin_5, GPIO_Mode_InOut_OD)
#define DS18B20_DQ_LOW() DS18B20_DQ=RESET
#define DS18B20_DQ_HIGH() DS18B20_DQ=SET
读一个bit和一个byte
__BIT DS18B20_ReadBit(void) { __BIT b = RESET; /* Line low */ DS18B20_DQ = RESET; DS18B20_DQ_OUTPUT(); SYS_DelayUs(2); /* Release line */ DS18B20_DQ_INPUT(); SYS_DelayUs(10); /* Read line value */ if (DS18B20_DQ) { /* Bit is HIGH */ b = SET; } /* Wait 50us to complete 60us period */ SYS_DelayUs(50); /* Return bit value */ return b; } uint8_t DS18B20_ReadByte(void) { uint8_t i = 8, byte = 0; while (i--) { byte >>= 1; byte |= (DS18B20_ReadBit() << 7); } return byte; }
写一个bit和一个byte
void DS18B20_WriteBit(__BIT b) { if (b) { /* Set line low */ DS18B20_DQ = RESET; DS18B20_DQ_OUTPUT(); SYS_DelayUs(10); /* Bit high */ DS18B20_DQ_INPUT(); /* Wait for 55 us and release the line */ SYS_DelayUs(55); DS18B20_DQ_INPUT(); } else { /* Set line low */ DS18B20_DQ = RESET; DS18B20_DQ_OUTPUT(); SYS_DelayUs(65); /* Bit high */ DS18B20_DQ_INPUT(); /* Wait for 5 us and release the line */ SYS_DelayUs(5); DS18B20_DQ_INPUT(); } } void DS18B20_WriteByte(uint8_t byte) { uint8_t i = 8; /* Write 8 bits */ while (i--) { /* LSB bit is first */ DS18B20_WriteBit(byte & 0x01); byte >>= 1; } }
初始化, 注意设置上拉, 以及输入和输出模式的切换
void DS18B20_Init(void)
{
DS18B20_DQ_PULLUP();
DS18B20_DQ_OUTPUT();
DS18B20_DQ = SET;
SYS_DelayUs(1000);
DS18B20_DQ = RESET;
SYS_DelayUs(1000);
DS18B20_DQ = SET;
SYS_DelayUs(2000);
}
读取温度, 这样读出的值并非温度值, 需要根据上面的温度转换, 乘以对应的温度单元值(默认为0.0625摄氏度)
// 发起转换 DS18B20_StartAll(); // 读取总线, 当转换完成时会变为高电平 while (!DS18B20_AllDone()) { UART1_TxChar('.'); SYS_Delay(1); } // 重置总线 DS18B20_Reset(); // 跳过ROM选择 DS18B20_WriteByte(ONEWIRE_CMD_SKIPROM); // 写入读取暂存器指令 DS18B20_WriteByte(ONEWIRE_CMD_RSCRATCHPAD); // 读出9个字节的数据 for (i = 0; i < 9; i++) { /* Read byte by byte */ data[i] = DS18B20_ReadByte(); } // 温度值位于第1和第2个字节 temperature = data[1]; temperature = temperature << 8 | data[0];
读取ROM
// 重置总线
DS18B20_Reset();
// 写入读取ROM指令, 注意这个命令不能用于连接多个设备的总线, 否则结果读数是无意义的
DS18B20_WriteByte(ONEWIRE_CMD_READROM);
// 读出数据
for (i = 0; i < 8; i++)
{
*buf++ = DS18B20_ReadByte();
}
指定设备地址, 读取温度
// 重置总线 DS18B20_Reset(); // 根据地址选择设备 DS18B20_Select(addr); // 对选中的设备, 发起转换 DS18B20_WriteByte(DS18B20_CMD_CONVERTTEMP); // 等待转换结束 // 重置总线 DS18B20_Reset(); // 根据地址选择设备 DS18B20_Select(addr); // 写入读取暂存器指令 DS18B20_WriteByte(ONEWIRE_CMD_RSCRATCHPAD); // 读取数据 for (i = 0; i < 9; i++) { *buf++ = DS18B20_ReadByte(); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。