DS18B20问题总结(驱动代码)

①检查DS18B20是否正常工作

初始化问题

如何检测初始化问题

可以通过在初始化返回的标志位,结合LED小灯或者串口,进而判断是否返回正确的标志位

bit ds_init() 
{
    bit i;
    DQ = 1;
    _nop_();
    DQ = 0;
    delay_us(500); //拉低总线499.45us 挂接在总线上的18B20将会全部被复位
    DQ = 1; //释放总线(检测到上升沿)
    delay_us(38); //延时37.95us 等待18B20发回存在信号(存在脉冲)
    i = DQ;
    delay_us(142); //141.95us
    DQ = 1;
    _nop_();
    return (i);    //返回一个存在信号
}

DS18B20初始化代码

可以通过判断函数返回的i值来判断DS18B20是否正常工作

主机给到DS18B20一个复位脉冲

再由DS18b20这个从机,将数据线DQ进行拉低

也就是说,如果返回i值为0,即DS18B20正常响应

void main(void)
{
	WTST = 0;		//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
	EAXSFR();		//扩展SFR(XFR)访问使能 
	CKCON = 0;      //提高访问XRAM速度
	GPIO_config();
	bit flag;  //调试ds18b20初始化是否正常标志位
	LED=1;     //默认LED熄灭
	while(1)
	{
				flag =ds_init();  //检查DS18B20初始化
		    if(flag==0)
				{
					LED=0; //LED点亮,工作正常
				}
				else
				{
					LED=1; //LED熄灭	
				}
	}
}

②数码管显示问题

主要是虚焊问题

驱动芯片和数码管虚焊

③矩阵按键无法正常工作

初始化端口定义错误

DS18B20驱动代码

//========================================================================
// 函数: ds_init
// 描述: 单总线初始化时序,出始化时序里包含了复位DS18B20和
// 参数: None.
// 返回: 接收DS18B20返回的存在信号
// 版本: V1.0, 2024-07-07
//========================================================================
bit ds_init() 
{
    bit i;
    DQ = 1;
    _nop_();
    DQ = 0;
    delay_us(500); //拉低总线499.45us 挂接在总线上的18B20将会全部被复位
    DQ = 1; //释放总线(检测到上升沿)
    delay_us(38); //延时37.95us 等待18B20发回存在信号(存在脉冲)
    i = DQ;
    delay_us(142); //141.95us
    DQ = 1;
    _nop_();
    return (i);    //返回一个存在信号
}
//========================================================================
// 函数: write_byte
// 描述: 写一个字节
// 参数: 写入数据
// 返回: None.
// 版本: V1.0, 2024-07-07
//========================================================================
void write_byte(u8 dat)
{
    u8 i;
    for(i=0;i<8;i++)
    {
        DQ = 0;
        _nop_();//产生些时序
        DQ = dat & 0x01; //0000 0001
        delay_us(77);//76.95us
        DQ = 1; //释放总线准备下一次数据写入
        _nop_();
        dat >>= 1;
    }
}
//========================================================================
// 函数: read_byte
// 描述: 读一个字节
// 参数: None.
// 返回: 返回一个字节
// 版本: V1.0, 2024-07-07
//========================================================================
u8 read_byte()
{
    u8 i, j, dat;
    for(i=0;i<8;i++)
    {
        DQ = 0;
        _nop_();//产生读时序 1us,延时一个指令周期,空指令
        DQ = 1;    //释放总线
        _nop_(); //延时时间可以通过单步调试来计算
        j = DQ;
        delay_us(77);//76.95us
        DQ = 1;
        _nop_();
        dat = (j<<7)|(dat>>1);    
    }
    return (dat);
}

//========================================================================
// 函数: read_temparature
// 描述: 读取温度值
// 参数: None.
// 返回: 返回温度值,无符号整型,保留两位小数
// 版本: V1.0, 2024-07-07
//========================================================================
u16 read_temparature(void)
{
	  u16 temp;
		u8 L, M;
		ds_init();//初始化DS18B20	    
		write_byte(0xcc);//发送跳跃ROM指令
		write_byte(0x44);//发送温度转换指令
		ds_init();//初始化DS18B20
		write_byte(0xcc);//发送跳跃ROM指令(注意:当只有一只从机在总线上时,无论如何,
		//忽略ROM指令之后只能跟着发出一条暂存器指令【BEh】)
		write_byte(0xbe);//读取DS18B20暂存器值,读取将从字节0开始,一直进行下去,直到第9字节(字节8,CRC)读完
		L = read_byte();//总线控制器在发出温度转换指令之后进行读时序
		M = read_byte();//总线控制器在发出温度转换指令之后进行读时序
		temp = M; //高速暂存器(共8位),详见中文手册
		temp <<= 8; //将最低位移至高位
		temp |= L;                        
		temp = temp * 0.0625 * 100 + 0.50;   // 显示两位小数  125.64  12564方便数据处理
		temp = abs(temp);                   //不考虑负温度
	  return temp;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是DS18B20驱动代码的示例: ```c #include <OneWire.h> // 定义引脚 #define ONE_WIRE_BUS 2 // 初始化 OneWire 对象 OneWire oneWire(ONE_WIRE_BUS); // DS18B20 的地址 byte addr[8]; void setup() { Serial.begin(9600); // 搜索 DS18B20 的地址 if (!oneWire.search(addr)) { Serial.println("No DS18B20 detected."); while (1); } // 判断 DS18B20 的地址是否正确 if (OneWire::crc8(addr, 7) != addr[7]) { Serial.println("Invalid DS18B20 address."); while (1); } // 输出 DS18B20 的地址 Serial.print("Found DS18B20 with address: "); for (byte i = 0; i < 8; i++) { Serial.print(addr[i], HEX); Serial.print(" "); } Serial.println(); // 启动温度转换 oneWire.reset(); oneWire.select(addr); oneWire.write(0x44); // 发送启动转换命令 } void loop() { // 等待温度转换完成 delay(1000); // 读取温度值 oneWire.reset(); oneWire.select(addr); oneWire.write(0xBE); // 发送读取温度命令 // 读取温度数据 byte data[9]; for (byte i = 0; i < 9; i++) { data[i] = oneWire.read(); } // 判断温度数据是否正确 if (OneWire::crc8(data, 8) != data[8]) { Serial.println("Invalid temperature data."); return; } // 计算温度值 int16_t raw = (data[1] << 8) | data[0]; float temp = (float)raw / 16.0; // 输出温度值 Serial.print("Temperature: "); Serial.print(temp); Serial.println(" C"); } ``` 以上代码使用了 `OneWire` 库来控制 DS18B20 温度传感器。首先,代码搜索 DS18B20 的地址,然后发送启动转换命令,等待温度转换完成,发送读取温度命令,读取温度数据,并计算出温度值。最后,代码输出温度值到串口。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值