打印
[PIC®/AVR®/dsPIC®产品]

【CuriosityNano测评报告】AVR128DB48+DS18B20测温

[复制链接]
2708|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 zhouminjie 于 2021-4-15 13:09 编辑

本次实现开发板挂载1个DS18B20测量温度,硬件如下:


VDD接到电源,DQ接MCU引脚,GND接地,由于DQ引脚为开漏输出,不具有输出高电平的能力,必须要接一个上拉电阻
①新建工程

②初始化DS18B20
初始化时序如下:

MCU拉低总线至少480us,产生复位脉冲,然后释放总线(拉高电平);这时DS8B20检测到请求之后,会拉低信号,大约60~240us表示应答;DS8B20拉低电平的60~240us之间,单片机读取总线的电平,如果是低电平,那么表示初始化成功;DS18B20拉低电平60~240us之后,会释放总线
代码实现:
//复位DS18B20
void DS18B20_Rst(void)
{
    DS18B20_SetDigitalOutput(); //输出模式
    DS18B20_SetLow(); //拉低DQ
     _delay_us(750); //拉低750us(480~960us)
    DS18B20_SetHigh(); //拉高DQ
}

//等待DS18B20应答,有应答返回0,无应答返回1
uint8_t DS18B20_Check(void)
{
    uint8_t retry = 0;
    //进入接收模式,等待应答信号
    //等待时间
    DS18B20_SetDigitalInput(); //输入模式
    _delay_us(15); //等待15~60us
    while(DS18B20_GetValue() && retry<120) //最多再等待120us
    {
        retry++;
        _delay_us(1);
    };
    if(retry >= 120)
        return 1; //120us未响应,则判断未检测到
    else
        retry = 0;
    //DS18B20开始拉低DQ
    while(!DS18B20_GetValue() && retry<240) //最长拉低240us
    {
        retry++;
        _delay_us(1);
    };
    if(retry >= 240)
        return 1;
    return 0;
}
③写DS18B20时序
写时序如下:

MCU给DS18B20写0时,MCU引脚拉低,延时60us,然后释放总线,延时2us
MCU给DS18B20写1时,MCU引脚拉低,延时2us,然后释放总线,延时60us
在写时序起始后15μs到60μs期间,DS18B20处于采样单总线电平状态。如果在此期间总线为高电平,则向DS18B20写入1;如果总线为低电平,则向DSl8B20写入0
代码实现:
//写字节到DS18B20
void DS18B20_Write_Byte(uint8_t dat)
{
    uint8_t j;
    uint8_t temp;

    DS18B20_SetDigitalOutput(); //输出模式
    for(j=1; j<=8; j++)
    {
        temp = dat & 0x01;
        dat = dat >> 1;
        if (temp) //输出高
        {
            DS18B20_SetLow(); //拉低DQ
            _delay_us(2); //延时2us
            DS18B20_SetHigh(); //拉高DQ
            _delay_us(60); //延时60us
        }
        else //输出低
        {
            DS18B20_SetLow(); //拉低DQ
            _delay_us(60); //延时60us
            DS18B20_SetHigh(); //拉高DQ
            _delay_us(2); //延时2us
        }
    }
    DS18B20_SetDigitalInput(); //输入模式
}
④读DS18B20时序
读时序如下:

MCU拉低电平,延时2us;MCU转为输入模式,延时12us;然后读取单总线当前的电平,延时50us
代码实现:
//从DS18B20读位
uint8_t DS18B20_Read_Bit(void)
{
    uint8_t data;

    DS18B20_SetDigitalOutput(); //输出模式
    DS18B20_SetLow(); //拉低DQ
    _delay_us(2); //延时2us
    DS18B20_SetHigh(); //拉高DQ
    DS18B20_SetDigitalInput(); //输入模式
    _delay_us(12); //延时12us
    if(DS18B20_GetValue()) //读DQ数据
        data = 1;
    else
        data = 0;
    _delay_us(50); //延时50us
    return data;
}

//从DS18B20读字节
uint8_t DS18B20_Read_Byte(void)
{
    uint8_t i, j, dat = 0;

    for(i=1; i<=8; i++)
    {
        j = DS18B20_Read_Bit();
        dat = (j << 7) | (dat >> 1);
    }
    return dat;
}
⑤温度读取
MCU发送复位信号,发送SKIP ROM命令(0XCC,匹配指令)
发开始转换命令(0X44)
延时等待转换完成(12bit分辨率时需要750ms)
MCU发送复位信号,发送SKIP ROM命令(0XCC)
发读存储器命令(0XBE),读取暂存器内容
连续读出两个字节数据
对读取的温度值进行转换
代码实现:
//开始温度转换
void DS18B20_Start(void)
{
    DS18B20_Rst();
    DS18B20_Check();
    DS18B20_Write_Byte(0xcc);
    DS18B20_Write_Byte(0x44);
}

//读取温度值
uint16_t DS18B20_Get_Temp(void)
{
    uint8_t sign; //温度符号,0为-,1为+
    uint8_t TL, TH;
    uint16_t temp;
    float temp1;

    DS18B20_Start ();
    _delay_ms(800); //等待转换完成
    DS18B20_Rst();
    DS18B20_Check();
    DS18B20_Write_Byte(0xcc);
    DS18B20_Write_Byte(0xbe);
    TL = DS18B20_Read_Byte();
    TH = DS18B20_Read_Byte();
    if(TH > 7)
    {
        TH = ~TH;
        TL = ~TL;
        sign = 0; //温度为负
    }
    else
        sign = 1; //温度为正
    temp = TH; //高八位
    temp <<= 8;
    temp += TL; //低八位
    temp1 = (float)temp * 0.625 + 0.5; //转换实际温度(放大10倍),+0.5四舍五入
    temp = (uint16_t)temp1;
    if(sign)
        return temp; //返回温度值
    else
        return -temp;
}
⑥实现如下:

测试代码:
AVR_DS18B20.X.rar (149.58 KB)

使用特权

评论回复
沙发
wanduzi| | 2021-4-11 10:09 | 只看该作者
非常不错,这个用的多

使用特权

评论回复
板凳
pzsh| | 2021-4-20 22:20 | 只看该作者
谢谢分享源代码

使用特权

评论回复
地板
kkzz| | 2021-5-3 13:20 | 只看该作者
DS18B20的技术参数  

使用特权

评论回复
5
hudi008| | 2021-5-3 13:21 | 只看该作者

基于DS18B20单线多点温度测量系统  

使用特权

评论回复
6
lzmm| | 2021-5-3 13:21 | 只看该作者
ds18b20和单片机之间的距离多少  

使用特权

评论回复
7
minzisc| | 2021-5-3 13:21 | 只看该作者
ds18b20正常工作的工作电压是多少?

使用特权

评论回复
8
selongli| | 2021-5-3 13:22 | 只看该作者
ds18b20精度怎么设置

使用特权

评论回复
9
fentianyou| | 2021-5-3 13:22 | 只看该作者
要加10k上拉电阻   

使用特权

评论回复
10
xiaoyaodz| | 2021-5-3 13:22 | 只看该作者

用DS18B20单总线温度传感器实现一个温度计  

使用特权

评论回复
11
febgxu| | 2021-5-3 13:23 | 只看该作者
通过模拟时序来完成单线读写  

使用特权

评论回复
12
sdlls| | 2021-5-3 13:24 | 只看该作者
18B20是可以用数据线供电的  

使用特权

评论回复
13
pixhw| | 2021-5-3 13:25 | 只看该作者
  感谢分享。

使用特权

评论回复
14
lzmm| | 2021-5-3 13:25 | 只看该作者
温度传感器使用方  

使用特权

评论回复
15
hudi008| | 2021-5-3 13:25 | 只看该作者
如何实现多个DS18B20并联在唯一的单线上

使用特权

评论回复
16
minzisc| | 2021-5-3 13:25 | 只看该作者
为什么要上拉电阻  

使用特权

评论回复
17
kkzz| | 2021-5-3 13:25 | 只看该作者
单线通信的经典。   

使用特权

评论回复
18
sdlls| | 2021-5-3 13:25 | 只看该作者
单线挂多个DS18B20  

使用特权

评论回复
19
febgxu| | 2021-5-3 13:25 | 只看该作者
通过这根线的电平高低以及延时时间的情况来告知从机下一步的动作。

使用特权

评论回复
20
pixhw| | 2021-5-3 13:25 | 只看该作者
就是延时不好控制的。  

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

32

主题

136

帖子

3

粉丝