本文记录下使用CH592驱动DS18B20,
以下为ds18b20.c
#include "CH59x_common.h" #include "ds18b20.h" // 初始化 DS18B20 传感器 // 此函数用于复位 DS18B20 并检测其是否存在 // 返回值为 0 表示检测到 DS18B20,非 0 表示未检测到 uint8_t DS18B20_Init(void) { uint8_t presence; // 主机拉低总线 480 - 960us,这里选择 480us // 将引脚设置为输出模式 DS18B20_DQ_H; DelayUs(700); // 拉低引脚 DS18B20_DQ_L; DelayUs(480); // 主机释放总线,等待 15 - 60us,这里选择 60us // 将引脚设置为输入模式 DS18B20_DQ_IN; DelayUs(60); // 读取总线状态,判断是否有从机响应 presence = DS18B20_DQ_READ; DelayUs(420); return presence; } // 向 DS18B20 写入一个位 // 参数 bit 为要写入的位值(0 或 1) void DS18B20_WriteBit(uint8_t bit) { if (bit) { // 写 1 // 拉低总线 1us DS18B20_DQ_L; DelayUs(1); // 释放总线,保持 60us DS18B20_DQ_IN; DelayUs(60); } else { // 写 0 // 拉低总线 60us DS18B20_DQ_L; DelayUs(60); // 释放总线 DS18B20_DQ_IN; } } // 从 DS18B20 读取一个位 // 返回值为读取到的位值(0 或 1) uint8_t DS18B20_ReadBit(void) { uint8_t bit; // 拉低总线 2us DS18B20_DQ_L; DelayUs(2); // 释放总线 DS18B20_DQ_IN; DelayUs(12); // 读取总线状态 bit = DS18B20_DQ_READ; DelayUs(50); return bit; } // 向 DS18B20 写入一个字节 // 参数 byte 为要写入的字节值 void DS18B20_WriteByte(uint8_t byte) { for (uint8_t i = 0; i < 8; i++) { // 从最低位开始逐位写入 DS18B20_WriteBit(byte & 0x01); byte >>= 1; } } // 从 DS18B20 读取一个字节 // 返回值为读取到的字节值 uint8_t DS18B20_ReadByte(void) { uint8_t byte = 0; for (uint8_t i = 0; i < 8; i++) { byte >>= 1; if (DS18B20_ReadBit()) { byte |= 0x80; } } return byte; } // 启动 DS18B20 的温度转换 void DS18B20_StartConversion(void) { // 复位 DS18B20 uint32_t start=DS18B20_Init(); PRINT("start=%x\n",start); // 跳过 ROM 操作,适用于单总线只有一个 DS18B20 的情况 DS18B20_WriteByte(0xCC); // 启动温度转换 DS18B20_WriteByte(0x44); } // 读取 DS18B20 的温度值 // 返回值为读取到的温度值,单位为摄氏度 float DS18B20_ReadTemperature(void) { uint8_t temp_l, temp_h; int16_t temp; float temperature; // 复位 DS18B20 DS18B20_Init(); // 跳过 ROM 操作 DS18B20_WriteByte(0xCC); // 读取温度寄存器 DS18B20_WriteByte(0xBE); // 读取温度值的低 8 位 temp_l = DS18B20_ReadByte(); // 读取温度值的高 8 位 temp_h = DS18B20_ReadByte(); // 组合高低 8 位得到 16 位温度值 temp = (temp_h << 8) | temp_l; // 根据 DS18B20 的数据格式,将 16 位值转换为实际温度值 temperature = (float)temp / 16.0; return temperature; }
以下为以下为ds18b20.h
#ifndef __DS18B20_H__ #define __DS18B20_H__ // 定义 DS18B20 连接的引脚 #define DS18B20_PORT 1 //1为GPIOA 0为GPIOB #define DS18B20_PIN GPIO_Pin_4 #if (DS18B20_PORT==1) #define DS18B20_DQ_H {\ GPIOA_SetBits(DS18B20_PIN);\ GPIOA_ModeCfg(DS18B20_PIN, GPIO_ModeOut_PP_5mA);\ } #define DS18B20_DQ_L {\ GPIOA_ResetBits(DS18B20_PIN);\ GPIOA_ModeCfg(DS18B20_PIN, GPIO_ModeOut_PP_5mA);\ } #define DS18B20_DQ_IN GPIOA_ModeCfg(DS18B20_PIN, GPIO_ModeIN_PU); #define DS18B20_DQ_READ GPIOA_ReadPortPin(DS18B20_PIN); #endif #if (DS18B20_PORT==0) #define DS18B20_DQ_H {\ GPIOB_SetBits(DS18B20_PIN);\ GPIOB_ModeCfg(DS18B20_PIN, GPIO_ModeOut_PP_5mA);\ } #define DS18B20_DQ_L {\ GPIOB_ResetBits(DS18B20_PIN);\ GPIOB_ModeCfg(DS18B20_PIN, GPIO_ModeOut_PP_5mA);\ } #define DS18B20_DQ_IN GPIOB_ModeCfg(DS18B20_PIN, GPIO_ModeIN_PU); #define DS18B20_DQ_READ GPIOB_ReadPortPin(DS18B20_PIN); #endif extern uint8_t DS18B20_Init(void); extern void DS18B20_WriteBit(uint8_t bit); extern uint8_t DS18B20_ReadBit(void); extern void DS18B20_WriteByte(uint8_t byte); extern uint8_t DS18B20_ReadByte(void); extern void DS18B20_StartConversion(void); extern float DS18B20_ReadTemperature(void); #endif
mian函数:
while (1) { // 启动温度转换 DS18B20_StartConversion(); // 等待转换完成,最大转换时间为 750ms DelayMs(750); // 读取温度值 float temp = DS18B20_ReadTemperature(); PRINT("TEM=%f\n",temp); DelayMs(1000); }
浙公网安备 33010602011771号