ds18b20.c

/*
*******************************************************************************
* 文件名:DS18B20.c
* 描  述:温度传感器DS18B20驱动模块
*******************************************************************************
*/
#include <reg52.h>
#include <intrins.h>
#include "stdint.h"

sbit ds18b20_io = P3^2;  //DS18B20通信引脚
/* 软件延时函数,延时时间(t*10)us */
void delayX10us(uint16_t t) {
    t *= 6;
    do {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    } while (--t);
}
/* 复位总线,获取存在脉冲,以启动一次读写操作 */
bit getDs18b20Ack() {
    bit ack;

    EA = 0;   //禁止总中断
    ds18b20_io = 0;     //产生500us复位脉冲
    delayX10us(50);
    ds18b20_io = 1;
    delayX10us(6);    //延时60us
    ack = ds18b20_io;   //读取存在脉冲
    while (!ds18b20_io); //等待存在脉冲结束
    EA = 1;   //重新使能总中断

    return ack;
}
/* 向DS18B20写入一个字节,dat-待写入字节 */
void writeDs18b20(uint8_t dat) {
    uint8_t mask;

    EA = 0;   //禁止总中断
    //低位在先,依次移出8个bit
    for (mask = 0x01; mask != 0; mask <<= 1) {
        ds18b20_io = 0;         //产生2us低电平脉冲
        _nop_();
        _nop_();
        if ((mask & dat) == 0)  //输出该bit值
            ds18b20_io = 0;
        else
            ds18b20_io = 1;
        delayX10us(6);        //延时60us
        ds18b20_io = 1;         //拉高通信引脚
    }
    EA = 1;   //重新使能总中断
}
/* 从DS18B20读取一个字节,返回值-读到的字节 */
uint8_t readDs18b20() {
    uint8_t dat, mask;

    EA = 0;   //禁止总中断
    //低位在先,依次采集8个bit
    for (mask = 0x01; mask != 0; mask <<= 1) {
        ds18b20_io = 0;         //产生2us低电平脉冲
        _nop_();
        _nop_();
        ds18b20_io = 1;         //结束低电平脉冲,等待18B20输出数据
        _nop_();              //延时2us
        _nop_();
        if (ds18b20_io)        //读取通信引脚上的值
            dat |= mask;
        else
            dat &= ~mask;
        delayX10us(6);        //再延时60us
    }
    EA = 1;   //重新使能总中断

    return dat;
}
/* 启动一次18B20温度转换,返回值-表示是否启动成功 */
bit startDs18b20() {
    bit ack;

    ack = getDs18b20Ack();   //执行总线复位,并获取18B20应答
    //如18B20正确应答,则启动一次转换
    if (ack == 0) {
        writeDs18b20(0xCC);  //跳过ROM操作
        writeDs18b20(0x44);  //启动一次温度转换
    }
    return ~ack;   //ack==0表示操作成功,所以返回值对其取反
}
/* 读取DS18B20转换的温度值,返回值-表示是否读取成功 */
bit getDs18b20Temperature(int16_t * temp) { //温度有正负,有符号
    bit ack;
    uint8_t lowByte, highByte; //16bit温度值的低字节和高字节

    ack = getDs18b20Ack();    //执行总线复位,并获取18B20应答
    //如18B20正确应答,则读取温度值
    if (ack == 0) {
        writeDs18b20(0xCC);   //跳过ROM操作
        writeDs18b20(0xBE);   //发送读命令
        lowByte = readDs18b20();  //读温度值的低字节
        highByte = readDs18b20();  //读温度值的高字节
        *temp = ((int16_t)highByte << 8) | lowByte;  //合成为16bit有符号整型数
    }
    return ~ack;  //ack==0表示操作应答,所以返回值为其取反值
}

uint8_t getIntPart(int16_t temp) {  //温度是16位有符号数
    if (temp & 0x8000)  //温度是负数
        temp = -temp;   //取绝对值
    temp >>= 4;
    return (uint8_t)temp;
}

uint8_t getDecPart(int16_t temp) {  //精确到十进制的一位小数
    uint8_t lowByte;

    if (temp & 0x8000)  //温度是负数
        temp = -temp;   //取绝对值
    lowByte = temp;     //取低字节
    lowByte &= 0x0F;    //高4位清0
    return (lowByte * 10) >> 4; //乘以10,除以16
}

bit getSign(int16_t temp) {   //温度是16位有符号数
    return temp & 0x8000;
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是51单片机使用ds18b20温度传感器的C语言程序,包含ds18b20.c和ds18b20.h两个文件: ds18b20.h文件: ```c #ifndef __DS18B20_H__ #define __DS18B20_H__ #include <reg52.h> #define DQ P2_1 void Delay1ms(); bit Init_DS18B20(); void Write_DS18B20(unsigned char dat); unsigned char Read_DS18B20(); unsigned int Read_Temper(); #endif ``` ds18b20.c文件: ```c #include "ds18b20.h" void Delay1ms() { unsigned char i, j; for (i = 0; i < 20; i++) for (j = 0; j < 110; j++); } bit Init_DS18B20() { bit ack; DQ = 1; Delay1ms(); DQ = 0; Delay1ms(); DQ = 1; Delay1ms(); ack = DQ; Delay1ms(); return ack; } void Write_DS18B20(unsigned char dat) { unsigned char i; for (i = 0; i < 8; i++) { DQ = 0; DQ = dat & 0x01; Delay1ms(); DQ = 1; dat >>= 1; } } unsigned char Read_DS18B20() { unsigned char i, dat = 0; for (i = 0; i < 8; i++) { dat >>= 1; DQ = 0; DQ = 1; if (DQ == 1) dat |= 0x80; Delay1ms(); } return dat; } unsigned int Read_Temper() { bit flag; unsigned char high, low; unsigned int tp; Init_DS18B20(); Write_DS18B20(0xcc); Write_DS18B20(0x44); while (!DQ); Init_DS18B20(); Write_DS18B20(0xcc); Write_DS18B20(0xbe); low = Read_DS18B20(); high = Read_DS18B20(); tp = high; tp <<= 8; tp |= low; if (tp & 0x8000) { tp = ~tp + 1; flag = 1; } else flag = 0; tp *= 0.625; if (flag) return -tp; else return tp; } ``` 其中,delay1ms()函数是延时函数,Init_DS18B20()函数是初始化函数,Write_DS18B20()函数是写入函数,Read_DS18B20()函数是读取函数,Read_Temper()函数是读取温度函数。使用时只需包含头文件ds18b20.h,调用Read_Temper()函数即可得到温度值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值