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;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值