当前位置:首页单片机与硬件 > 正文

51单片机基础之DS18B20温度传感器

作者:野牛程序员:2023-12-26 12:00:45单片机与硬件阅读 4156

DS18B20温度传感器是一种数字温度传感器,常用于嵌入式系统和电子项目中。它采用单总线通信协议,可以通过单一引脚与主控芯片(如51单片机)连接。以下是使用51单片机与DS18B20温度传感器进行通信的基本步骤:

  1. 引脚连接

    • DS18B20的引脚包括VDD(电源正极)、DQ(数据引脚,单总线)、GND(地)。将这些引脚连接到51单片机的相应引脚上。

  2. 上拉电阻

    • 在DQ引脚上连接一个4.7kΩ的上拉电阻,将其连接到VDD引脚。这有助于保持单总线在高电平状态。

  3. 编写初始化代码

    • 在程序中初始化单总线通信。具体来说,需要配置51单片机的IO口为单总线模式。

  4. 发起温度转换

    • 发送指令给DS18B20,要求其进行温度转换。这可以通过向DS18B20发送0x44指令实现。

  5. 等待转换完成

    • DS18B20需要一定时间来完成温度转换。可以通过查询DS18B20的忙碌标志位,或者使用延时等待的方法。

  6. 读取温度数据

    • 一旦转换完成,就可以从DS18B20读取温度数据。这可以通过向DS18B20发送0xBE指令,并读取返回的温度值实现。

  7. 温度计算

    • 温度数据是以16位的形式存储在DS18B20的寄存器中的,需要进行一些计算以获取实际温度值。具体的计算方式可以参考DS18B20的数据手册。

  8. 显示或存储温度值

    • 最后,将计算得到的温度值显示在数码管、LCD屏幕上,或者通过串口发送给其他设备。

以上是基本的步骤,实际的代码编写可能会因具体的硬件连接和控制方式而有所不同。建议查阅DS18B20的数据手册以获取更详细的信息,并根据51单片机的型号和具体情况进行相应的编程。

汇编代码:

; 51单片机与DS18B20温度传感器通信的汇编代码示例

; 定义DS18B20相关的常量
DQ_PIN      equ P1.0    ; DS18B20数据引脚连接到P1.0

; 定义DS18B20命令字
SKIP_ROM    equ 0xCC    ; 跳过ROM地址
CONVERT_T   equ 0x44    ; 启动温度转换
READ_SCRATCHPAD equ 0xBE ; 读取寄存器

; 定义延时常量
DELAY_1US   equ 1       ; 1微秒延时
DELAY_1MS   equ 1       ; 1毫秒延时

ORG 0H
JMP Main

; 初始化单总线通信
Init_DS18B20:
    MOV DQ_PIN, 1      ; 设置DQ_PIN为高电平
    NOP
    NOP
    NOP
    MOV P1M1, P1M1 ORB 00000001B ; 配置P1.0为开漏输出
    MOV P1M2, P1M2 AND 11111110B

    RET

; 发送一个脉冲到DS18B20
Send_Pulse:
    MOV DQ_PIN, 0      ; 拉低数据线
    NOP
    NOP
    MOV DQ_PIN, 1      ; 拉高数据线
    NOP
    NOP

    RET

; 发送一个字节到DS18B20
Send_Byte:
    MOV R7, #8         ; 初始化位计数器
Send_Loop:
    RLC                ; 将数据的最低位放入Carry位
    MOV C, ACC.7       ; 将Carry位送到进位标志
    MOV DQ_PIN, C      ; 将进位标志送到数据线
    CALL Delay_1US     ; 等待一段时间
    CALL Send_Pulse    ; 发送脉冲
    DJNZ R7, Send_Loop ; 继续发送下一位
    RET

; 从DS18B20接收一个字节
Receive_Byte:
    MOV R7, #8         ; 初始化位计数器
    MOV ACC, #0        ; 清零ACC
Receive_Loop:
    CALL Delay_1US     ; 等待一段时间
    RLC                ; 将数据线的状态放入ACC
    RLC                ; 将数据的最低位放入Carry位
    MOV DQ_PIN, C      ; 将Carry位送到数据线
    CALL Delay_1US     ; 等待一段时间
    DJNZ R7, Receive_Loop ; 继续接收下一位
    RET

; 启动温度转换
Start_Conversion:
    CALL Send_Byte     ; 发送跳过ROM地址命令
    MOV A, #CONVERT_T
    CALL Send_Byte     ; 发送启动转换命令

    RET

; 读取DS18B20的温度数据
Read_Temperature:
    CALL Send_Byte     ; 发送跳过ROM地址命令
    MOV A, #READ_SCRATCHPAD
    CALL Send_Byte     ; 发送读取寄存器命令
    CALL Receive_Byte  ; 读取温度的低字节
    MOV B, ACC         ; 保存低字节
    CALL Receive_Byte  ; 读取温度的高字节
    MOV A, B           ; 将低字节放入ACC的低四位
    MOV B, ACC         ; 将高字节放入ACC的高四位

    RET

; 主程序
Main:
    CALL Init_DS18B20  ; 初始化单总线通信
    CALL Start_Conversion ; 启动温度转换
    ; 等待转换完成,具体时间根据DS18B20的特性而定
    ; 这里可以使用延时函数或其他方式等待
    ; 例如:CALL Delay_1MS

    CALL Read_Temperature ; 读取温度数据

    ; 此时,温度数据已经存储在寄存器中,可以进行后续处理
    ; 例如,将温度值显示在数码管、LCD屏幕上,或通过串口发送
    ; 具体显示和处理方式取决于具体的硬件和需求

    JMP $

; 延时函数,延时1微秒
Delay_1US:
    MOV R0, #DELAY_1US
Delay_Loop_US:
    NOP
    NOP
    DJNZ R0, Delay_Loop_US
    RET

; 延时函数,延时1毫秒
Delay_1MS:
    MOV R1, #DELAY_1MS
Delay_Loop_MS:
    MOV R0, #245
Delay_Loop_US_MS:
    NOP
    NOP
    DJNZ R0, Delay_Loop_US_MS
    DJNZ R1, Delay_Loop_MS
    RET

c语言代码

#include <reg51.h>

// 定义DS18B20相关的常量
#define DQ_PIN P1_0   // DS18B20数据引脚连接到P1.0

// 定义DS18B20命令字
#define SKIP_ROM 0xCC   // 跳过ROM地址
#define CONVERT_T 0x44   // 启动温度转换
#define READ_SCRATCHPAD 0xBE // 读取寄存器

// 定义延时函数
void delay_us(unsigned int us) {
    while(us--) {
        // 1微秒延时
        _nop_();
        _nop_();
    }
}

// 发送一个脉冲到DS18B20
void send_pulse() {
    DQ_PIN = 0;      // 拉低数据线
    delay_us(2);     // 等待一段时间
    DQ_PIN = 1;      // 拉高数据线
    delay_us(2);     // 等待一段时间
}

// 发送一个字节到DS18B20
void send_byte(unsigned char byte) {
    unsigned char i;
    for (i = 0; i < 8; i++) {
        DQ_PIN = byte & 0x01;  // 将字节的最低位送到数据线
        byte >>= 1;            // 右移一位
        send_pulse();          // 发送脉冲
    }
}

// 从DS18B20接收一个字节
unsigned char receive_byte() {
    unsigned char i, byte = 0;
    for (i = 0; i < 8; i++) {
        byte >>= 1;            // 右移一位
        if (DQ_PIN)             // 读取数据线的状态
            byte |= 0x80;       // 如果数据线为高电平,将最高位设为1
        delay_us(2);            // 等待一段时间
        send_pulse();           // 发送脉冲
    }
    return byte;
}

// 启动温度转换
void start_conversion() {
    send_byte(SKIP_ROM);    // 发送跳过ROM地址命令
    send_byte(CONVERT_T);   // 发送启动转换命令
}

// 读取DS18B20的温度数据
unsigned int read_temperature() {
    unsigned char low_byte, high_byte;
    send_byte(SKIP_ROM);        // 发送跳过ROM地址命令
    send_byte(READ_SCRATCHPAD); // 发送读取寄存器命令
    low_byte = receive_byte();  // 读取温度的低字节
    high_byte = receive_byte(); // 读取温度的高字节
    return (high_byte << 8) | low_byte; // 将高字节和低字节组合成16位温度值
}

void main() {
    start_conversion(); // 启动温度转换

    // 等待转换完成,具体时间根据DS18B20的特性而定
    // 这里可以使用延时函数或其他方式等待
    // 例如:delay_ms(500);

    unsigned int temperature = read_temperature(); // 读取温度数据

    // 此时,温度数据已经存储在temperature变量中,可以进行后续处理
    // 例如,将温度值显示在数码管、LCD屏幕上,或通过串口发送
    // 具体显示和处理方式取决于具体的硬件和需求

    while (1) {
        // 程序主循环
    }
}


野牛程序员教少儿编程与信息学奥赛-微信|电话:15892516892
野牛程序员教少儿编程与信息学竞赛-微信|电话:15892516892
相关推荐

最新推荐

热门点击