TMS320F28335获取DS18B20温度

小插曲

在网上翻阅了STM32代码,移植到到TMS320F28335上一直读取到的温度值一直显示固定值,查阅半天资料翻阅DSB18B20产品手册都没有解决,偶尔看到论坛中说TMS320F28335中的延迟函数DELAY_US在RAM调试时是准确的,但下载到FLASH中并不准确,会出现比设定值多延迟几微秒的结果,看到这个之后就不断调延迟,但是之后想了一下,多这几微秒在DS18B20允许时序内,按理说应该能够获取到温度。

解决方案

注意DS18B20数据端要外接一个上拉电阻,仅仅单片机配置IO口上拉不够,我的接线图如下所示

代码

ds18b20.c & ds18b20.h

#ifndef __DS18B20_H
#define __DS18B20_H

#include "DSP2833x_Device.h"     // DSP2833x Headerfile
#include "DSP2833x_Examples.h"   // DSP2833x Examples
typedef unsigned char u8;


//IO方向
#define DS18B20_IO_IN()  {EALLOW;GpioCtrlRegs.GPCDIR.bit.GPIO77 = 0;EDIS;}
#define DS18B20_IO_OUT() {EALLOW;GpioCtrlRegs.GPCDIR.bit.GPIO77 = 1;EDIS;}
//IO操作
#define DS18B20_DQ_OUT_1 (GpioDataRegs.GPCSET.bit.GPIO77 = 1) //数据端口GPIO77
#define DS18B20_DQ_OUT_0 (GpioDataRegs.GPCCLEAR.bit.GPIO77 = 1) //数据端口GPIO77
//读取IO
#define DS18B20_DQ_IN  (GpioDataRegs.GPCDAT.bit.GPIO77) //数据端口GPIO77

u8 DS18B20_Init(void);          //初始化
float DS18B20_Get_Temp(void);   //获取温度
void DS18B20_Start(void);       //开始温度转换
void DS18B20_Write_Byte(u8 dat);
u8 DS18B20_Read_Byte(void);
u8 DS18B20_Read_Bit(void);
u8 DS18B20_Check(void);
void DS18B20_Rst(void);
#endif
#include "ds18b20.h"

//复位DS18B20
void DS18B20_Rst(void)
{
    DS18B20_IO_OUT();   //GPIO77 OUTPUT
    DS18B20_DQ_OUT_0;   //拉低DQ
    DELAY_US(750);      //拉低总线480~960 us ,对 DS18B20 芯片进行复位
    DS18B20_DQ_OUT_1;   //DQ=1
    DELAY_US(15);       //释放总线15~60 us
}
/*
 * 等待DS18B20的回应
 * 返回1:未检测到DS18B20的存在
 * 返回0:存在
 *
 * */

u8 DS18B20_Check(void)
{
    u8 retry=0;
    DS18B20_IO_IN();    //GPIO77 INPUT
    while (DS18B20_DQ_IN && retry<240)  //等待DS18B20 拉低总线 (60~240 us 响应复位信号)
    {
        retry++;
        DELAY_US(1);
    };
    if(retry>=240)return 1;
    else retry=0;
    while (!DS18B20_DQ_IN && retry<240)  //判断DS18B20是否释放总线(60~240 us 响应复位信号之后会释放总线)
    {
        retry++;
        DELAY_US(1);
    };
    if(retry>=240)return 1;
    return 0;
}
//从DS18B20读取一个位
u8 DS18B20_Read_Bit(void)
{
    u8 data;
    DS18B20_IO_OUT();
    DS18B20_DQ_OUT_0;
    DELAY_US(8);
    DS18B20_DQ_OUT_1;
    DS18B20_IO_IN();
    DELAY_US(12);
    if(DS18B20_DQ_IN)data=1;
    else data=0;
    DELAY_US(50);  //延时确保DS18B20采样周期已经过去(非常重要)
    return data;
}
//从DS18B20读取一个字节
u8 DS18B20_Read_Byte(void)
{
    u8 i,j,dat;
    dat=0;
    for (i=1;i<=8;i++)
    {
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }
    return dat;
}
//写一个字节到DS18B20
//dat:写入的字节
void DS18B20_Write_Byte(u8 dat)
 {
    u8 j;
    u8 testb;
    DS18B20_IO_OUT();
    for (j=1;j<=8;j++)
    {
        testb=dat & 0x01;
        dat=dat>>1;
        if (testb)
        {
            DS18B20_DQ_OUT_0;   // Write 1
            DELAY_US(2);
            DS18B20_DQ_OUT_1;
            DELAY_US(60);
        }
        else
        {
            DS18B20_DQ_OUT_0;   // Write 0
            DELAY_US(60);
            DS18B20_DQ_OUT_1;
            DELAY_US(2);
        }
    }
}
//开始温度转换
void DS18B20_Start(void)
{
    DS18B20_Rst();
    DS18B20_Check();
    DS18B20_Write_Byte(0xcc);
    DS18B20_Write_Byte(0x44);
}
//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在
u8 DS18B20_Init(void)
{
    EALLOW; //关闭写保护

    //开启GPIO时钟
    SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;

    //GPIO配置
    GpioCtrlRegs.GPCMUX1.bit.GPIO77 = 0;    //选择通用GPIO功能
    GpioCtrlRegs.GPCDIR.bit.GPIO77 = 1; //设置为输出
    GpioCtrlRegs.GPCPUD.bit.GPIO77 = 1;  //上拉电阻

    GpioDataRegs.GPCSET.bit.GPIO77 = 1; //起始设置输出为高

    EDIS;   //打开写保护

    DS18B20_Rst();

    return DS18B20_Check();
}
//从ds18b20得到温度值
//精度:0.1C
float DS18B20_Get_Temp(void)
{
    u8 TL,TH;
    short s_tem;
    float f_tem;

    DS18B20_Start();

    DS18B20_Rst();
    DS18B20_Check();
    DS18B20_Write_Byte(0XCC);    /* 跳过 ROM */
    DS18B20_Write_Byte(0XBE);    /* 读温度值 */

    TL=DS18B20_Read_Byte();     // LSB
    TH=DS18B20_Read_Byte();     // MSB

    s_tem = TH<<8;
    s_tem = s_tem | TL;
    if( s_tem < 0 )     /* 负温度 */
        f_tem = (~s_tem+1) * 0.0625;
    else
        f_tem = (s_tem * 0.0625);

    return f_tem;
}

主函数里只需要在前面初始化DS18B20_Init();然后就可以在while循环里用DS18B20_Get_Temp()函数读取传感器的温度。

最后结果

前面两个为整数部分,后面两位为小数部分。为什么不加小数点,因为懒。

  • 16
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
合宙ESP32是一款基于ESP32芯片的开发板,而DS18B20是一款数字温度传感器。你可以通过连接DS18B20传感器到ESP32开发板来实现温度监测功能。 以下是连接合宙ESP32和DS18B20传感器的步骤: 1. 确保你已经购买了合适的DS18B20传感器,并且了解了其引脚定义。 2. 将DS18B20传感器的引脚连接到合宙ESP32开发板上。根据引用中提供的引脚定义,将DS18B20的引脚连接到合适的ESP32引脚上。例如,将DS18B20的VCC引脚连接到ESP32的3.3V引脚,将DS18B20的GND引脚连接到ESP32的GND引脚,将DS18B20的DATA引脚连接到ESP32的27引脚。 3. 在你的ESP32开发环境中,导入并使用适当的库来与DS18B20传感器进行通信。你可以使用Arduino IDE和OneWire库来实现这一点。确保你已经安装了OneWire库。 4. 在你的代码中,初始化OneWire对象并将其连接到DS18B20传感器的引脚。然后,使用DS18B20库中的函数来读取温度值。 5. 编写代码来读取DS18B20传感器的温度值,并将其打印出来或进行其他处理。 以下是一个示例代码,演示了如何在合宙ESP32上使用DS18B20传感器来读取温度值: ```python #include <OneWire.h> #include <DallasTemperature.h> // 定义DS18B20传感器连接的引脚 #define ONE_WIRE_BUS 27 // 初始化OneWire对象 OneWire oneWire(ONE_WIRE_BUS); // 初始化DallasTemperature对象 DallasTemperature sensors(&oneWire); void setup() { // 初始化串口通信 Serial.begin(9600); // 启动DS18B20传感器 sensors.begin(); } void loop() { // 请求温度数据 sensors.requestTemperatures(); // 读取温度值 float temperature = sensors.getTempCByIndex(0); // 打印温度值 Serial.print("Temperature: "); Serial.print(temperature); Serial.println(" °C"); // 延迟一段时间 delay(1000); } ``` 请注意,上述代码使用了OneWire库和DallasTemperature库来与DS18B20传感器进行通信。你需要在Arduino IDE中安装这些库。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值