51单片机多机通信代码
时间: 2023-09-16 09:16:02 浏览: 82
以下是基于串口通信的51单片机多机通信的示例代码,其中包括了主从模式和广播模式的实现:
主机代码:
```
#include <STC89C5xRC.H>
#include <intrins.h>
#define FOSC 11059200L
#define BAUD 9600L
#define TIMER_1MS_RELOAD_VALUE (65536UL - (FOSC/1000UL))
unsigned char code SlaveAddress = 0x01; // 从机地址
unsigned char code Command = 0x01; // 控制命令
void UART_Init(void)
{
SCON = 0x50; // 串口工作在模式1
TMOD &= 0x0F; // 清除定时器1的控制位
TMOD |= 0x20; // 定时器1工作在模式2
TH1 = TL1 = -(FOSC/12/32/BAUD); // 为定时器1设置重载值,波特率9600
TR1 = 1; // 启动定时器1
ES = 1; // 使能串口中断
EA = 1; // 开启总中断
}
void Timer1_Init(void)
{
TMOD &= 0xF0; // 清除定时器1的控制位
TMOD |= 0x01; // 定时器1工作在模式1
TH1 = TIMER_1MS_RELOAD_VALUE / 256;
TL1 = TIMER_1MS_RELOAD_VALUE % 256;
ET1 = 1; // 使能定时器1中断
TR1 = 1; // 启动定时器1
}
void SendData(unsigned char addr, unsigned char cmd)
{
while (!TI); // 等待上一次发送完成
TI = 0; // 清除发送标志位
SBUF = addr; // 发送地址
while (!TI); // 等待上一次发送完成
TI = 0; // 清除发送标志位
SBUF = cmd; // 发送命令
}
void main(void)
{
UART_Init();
Timer1_Init();
while (1)
{
SendData(SlaveAddress, Command);
Delay(1000); // 延时1s
}
}
void UART_ISR(void) interrupt 4
{
if (RI)
{
RI = 0; // 清除接收标志位
unsigned char data = SBUF; // 读取接收到的数据
// 处理接收到的数据
}
if (TI)
{
TI = 0; // 清除发送标志位
}
}
void Timer1_ISR(void) interrupt 3
{
TH1 = TL1 = TIMER_1MS_RELOAD_VALUE / 256;
// 定时器1中断服务程序
}
void Delay(unsigned int count)
{
unsigned int i;
for (i = 0; i < count; i++);
}
```
从机代码:
```
#include <STC89C5xRC.H>
#include <intrins.h>
#define FOSC 11059200L
#define BAUD 9600L
unsigned char code MasterAddress = 0x00; // 主机地址
void UART_Init(void)
{
SCON = 0x50; // 串口工作在模式1
TMOD &= 0x0F; // 清除定时器1的控制位
TMOD |= 0x20; // 定时器1工作在模式2
TH1 = TL1 = -(FOSC/12/32/BAUD); // 为定时器1设置重载值,波特率9600
TR1 = 1; // 启动定时器1
ES = 1; // 使能串口中断
EA = 1; // 开启总中断
}
void SendData(unsigned char addr, unsigned char cmd)
{
while (!TI); // 等待上一次发送完成
TI = 0; // 清除发送标志位
SBUF = addr; // 发送地址
while (!TI); // 等待上一次发送完成
TI = 0; // 清除发送标志位
SBUF = cmd; // 发送命令
}
void main(void)
{
UART_Init();
while (1)
{
// 接收数据
}
}
void UART_ISR(void) interrupt 4
{
if (RI)
{
RI = 0; // 清除接收标志位
unsigned char addr = SBUF; // 读取接收到的地址
while (!TI); // 等待上一次发送完成
TI = 0; // 清除发送标志位
SBUF = 0x06; // 发送确认应答
while (!TI); // 等待上一次发送完成
TI = 0; // 清除发送标志位
unsigned char cmd = SBUF; // 读取接收到的命令
if (addr == MasterAddress)
{
// 处理接收到的命令
}
}
if (TI)
{
TI = 0; // 清除发送标志位
}
}
```