首先,需要确定主从机的串口通信参数,包括波特率、数据位、校验位等。假设主机和从机的串口通信参数均为9600波特率、8个数据位、无校验位和1个停止位。

主机的程序流程如下:

  1. 初始化串口通信,设置波特率、数据位、校验位等参数;
  2. 循环发送请求测温命令给从机;
  3. 等待从机回复测温数据;
  4. 解析并显示从机回复的测温数据。

从机的程序流程如下:

  1. 初始化串口通信,设置波特率、数据位、校验位等参数;
  2. 等待主机发送测温命令;
  3. 收到测温命令后进行温度测量,并将数据发送给主机;
  4. 循环等待主机发送下一次测温命令。

下面是主机和从机的部分代码实现:

主机代码:

#include <STC89C5xRC.H>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

sbit DQ = P1^3; // DS18B20数据线
sbit LED = P1^4; // LED指示灯

uchar temp[2]; // 存储温度数据

void InitUART()
{
    TMOD = 0x20; // 设置定时器1为模式2
    TH1 = 0xfd; // 波特率9600
    TL1 = 0xfd;
    TR1 = 1; // 启动定时器1
    SM0 = 0; // 设置串口为模式1
    SM1 = 1;
    REN = 1; // 允许接收
    EA = 1; // 允许全局中断
    ES = 1; // 允许串口中断
}

void SendData(uchar dat)
{
    SBUF = dat; // 将数据写入发送缓冲区
    while (!TI); // 等待发送完成
    TI = 0; // 清除发送完成标志位
}

void RequestTemp()
{
    uchar i;
    unsigned int j;
    for (i = 0; i < 8; i++) // 发送复位信号
    {
        DQ = 0;
        _nop_();
        _nop_();
        DQ = 1;
        _nop_();
        _nop_();
    }
    SendData(0x01); // 发送测温命令
    for (j = 0; j < 5000; j++); // 延时等待从机回复
}

void main()
{
    InitUART();
    while (1)
    {
        RequestTemp(); // 发送测温命令
        while (!RI); // 等待接收数据
        temp[0] = SBUF; // 读取高位温度数据
        RI = 0;
        while (!RI); // 等待接收数据
        temp[1] = SBUF; // 读取低位温度数据
        RI = 0;
        LED = 1; // 点亮LED指示灯
        // 解析并显示温度数据
        SendData(temp[0]);
        SendData(temp[1]);
        LED = 0; // 熄灭LED指示灯
    }
}

void UART_ISR() interrupt 4
{
    if (RI) // 接收中断
    {
        RI = 0; // 清除接收中断标志位
    }
    if (TI) // 发送中断
    {
        TI = 0; // 清除发送中断标志位
    }
}

从机代码:

#include <STC89C5xRC.H>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

sbit DQ = P1^3; // DS18B20数据线

uchar temp[2]; // 存储温度数据

void InitUART()
{
    TMOD = 0x20; // 设置定时器1为模式2
    TH1 = 0xfd; // 波特率9600
    TL1 = 0xfd;
    TR1 = 1; // 启动定时器1
    SM0 = 0; // 设置串口为模式1
    SM1 = 1;
    REN = 1; // 允许接收
    EA = 1; // 允许全局中断
    ES = 1; // 允许串口中断
}

void SendData(uchar dat)
{
    SBUF = dat; // 将数据写入发送缓冲区
    while (!TI); // 等待发送完成
    TI = 0; // 清除发送完成标志位
}

void ReadTemp()
{
    uchar i, j;
    unsigned int temp_value;
    for (i = 0; i < 8; i++) // 发送复位信号
    {
        DQ = 0;
        _nop_();
        _nop_();
        DQ = 1;
        _nop_();
        _nop_();
    }
    for (i = 0; i < 8; i++) // 发送读取温度命令
    {
        DQ = 0;
        _nop_();
        _nop_();
        DQ = 1;
        _nop_();
        _nop_();
    }
    for (i = 0; i < 16; i++) // 读取16位温度数据
    {
        DQ = 0;
        _nop_();
        _nop_();
        temp_value = temp_value >> 1;
        if (DQ)
        {
            temp_value |= 0x8000;
        }
        DQ = 1;
        _nop_();
        _nop_();
    }
    temp[0] = temp_value >> 8; // 提取高位温度数据
    temp[1] = temp_value & 0xff; // 提取低位温度数据
}

void main()
{
    InitUART();
    while (1)
    {
        while (!RI); // 等待接收测温命令
        if (SBUF == 0x01)
        {
            RI = 0;
            ReadTemp(); // 读取温度
            // 发送温度数据
            SendData(temp[0]);
            SendData(temp[1]);
        }
    }
}

void UART_ISR() interrupt 4
{
    if (RI) // 接收中断
    {
        RI = 0; // 清除接收中断标志位
    }
    if (TI) // 发送中断
    {
        TI = 0; // 清除发送中断标志位
    }
}
``
两个stc89c52单片机进行串口通信主机显示温度从机测温

原文地址: https://www.cveoy.top/t/topic/epzF 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录