两个stc89c52单片机进行串口通信主机显示温度从机测温
首先,需要确定主从机的串口通信参数,包括波特率、数据位、校验位等。假设主机和从机的串口通信参数均为9600波特率、8个数据位、无校验位和1个停止位。
主机的程序流程如下:
- 初始化串口通信,设置波特率、数据位、校验位等参数;
- 循环发送请求测温命令给从机;
- 等待从机回复测温数据;
- 解析并显示从机回复的测温数据。
从机的程序流程如下:
- 初始化串口通信,设置波特率、数据位、校验位等参数;
- 等待主机发送测温命令;
- 收到测温命令后进行温度测量,并将数据发送给主机;
- 循环等待主机发送下一次测温命令。
下面是主机和从机的部分代码实现:
主机代码:
#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; // 清除发送中断标志位
}
}
``
原文地址: https://www.cveoy.top/t/topic/epzF 著作权归作者所有。请勿转载和采集!