两个51单片机串口通信,要求甲单片机的按键控制乙单片机的两个LED,按一下亮一个,再按一下切换到另一个LED;乙单片机按键计数显示在甲单片机连接的数码管上
时间: 2024-03-14 09:42:45 浏览: 104
51单片机串口通信详细教程_LED_51单片机_51单片机串口_51串口通信_
5星 · 资源好评率100%
下面是甲单片机和乙单片机的代码实现。甲单片机通过串口向乙单片机发送指令,控制乙单片机的LED灯亮灭状态。乙单片机通过计数器计算按键按下的次数,并将结果通过串口发送给甲单片机,甲单片机再将计数结果显示到连接的数码管上。
甲单片机代码:
```c
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit LED1 = P1^0;
sbit LED2 = P1^1;
sbit Key = P3^4; //按键接在P3.4口
void InitUART();
void UARTSend(uchar dat);
void UARTSendStr(uchar *str);
void delay(uint z);
void main()
{
uchar cnt = 0; //按键计数
uchar flag = 0; //LED灯状态标志
uchar recvData = 0; //接收到的数据
InitUART();
while(1)
{
if(Key == 0) //按键按下
{
delay(10); //消除抖动
if(Key == 0) //确保按键稳定按下
{
cnt++; //计数器加1
if(cnt > 2) cnt = 1; //计数器取值范围为1~2
if(cnt == 1)
{
flag = 0; //LED1亮,LED2灭
UARTSend('1'); //向乙单片机发送指令,控制LED1亮
}
else if(cnt == 2)
{
flag = 1; //LED2亮,LED1灭
UARTSend('2'); //向乙单片机发送指令,控制LED2亮
}
while(Key == 0); //等待按键释放
}
}
if(RI) //接收到数据
{
RI = 0; //清除接收中断标志
recvData = SBUF; //读取接收到的数据
if(recvData == 'C') //接收到乙单片机的计数数据
{
recvData = SBUF; //读取计数数据
P0 = recvData; //显示计数数据到数码管
}
}
}
}
void InitUART()
{
SCON = 0x50; //设置为8位数据位,无校验位,1位停止位,允许接收
TMOD &= 0x0F; //设置为定时器1工作方式1
TMOD |= 0x20;
TH1 = 0xFD; //设置波特率为9600
TL1 = 0xFD;
TR1 = 1; //启动定时器1
ES = 1; //允许串口中断
EA = 1; //开启总中断
}
void UARTSend(uchar dat)
{
SBUF = dat; //将数据写入发送缓存
while(!TI); //等待发送完成
TI = 0; //清除发送中断标志
}
void UARTSendStr(uchar *str)
{
while(*str)
{
UARTSend(*str++);
}
}
void delay(uint z)
{
uint x,y;
for(x = z;x > 0;x--)
for(y = 110;y > 0;y--);
}
void UARTInterrupt() interrupt 4
{
if(RI) //接收中断
{
RI = 0; //清除接收中断标志
}
if(TI) //发送中断
{
TI = 0; //清除发送中断标志
}
}
```
乙单片机代码:
```c
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit LED1 = P1^0;
sbit LED2 = P1^1;
sbit Key = P3^4; //按键接在P3.4口
void InitUART();
void UARTSend(uchar dat);
void UARTSendStr(uchar *str);
void delay(uint z);
void main()
{
uchar cnt = 0; //按键计数
uchar sendData = 0; //发送的数据
InitUART();
while(1)
{
if(Key == 0) //按键按下
{
delay(10); //消除抖动
if(Key == 0) //确保按键稳定按下
{
cnt++; //计数器加1
if(cnt > 2) cnt = 1; //计数器取值范围为1~2
if(cnt == 1)
{
LED1 = 1; //LED1亮,LED2灭
LED2 = 0;
}
else if(cnt == 2)
{
LED1 = 0; //LED2亮,LED1灭
LED2 = 1;
}
while(Key == 0); //等待按键释放
}
}
sendData = cnt + '0'; //将计数器转换为字符形式,用于发送
UARTSend('C'); //发送计数数据标志
UARTSend(sendData); //发送计数数据
delay(100); //延时一段时间,避免频繁发送数据
}
}
void InitUART()
{
SCON = 0x50; //设置为8位数据位,无校验位,1位停止位,允许接收
TMOD &= 0x0F; //设置为定时器1工作方式1
TMOD |= 0x20;
TH1 = 0xFD; //设置波特率为9600
TL1 = 0xFD;
TR1 = 1; //启动定时器1
ES = 1; //允许串口中断
EA = 1; //开启总中断
}
void UARTSend(uchar dat)
{
SBUF = dat; //将数据写入发送缓存
while(!TI); //等待发送完成
TI = 0; //清除发送中断标志
}
void UARTSendStr(uchar *str)
{
while(*str)
{
UARTSend(*str++);
}
}
void delay(uint z)
{
uint x,y;
for(x = z;x > 0;x--)
for(y = 110;y > 0;y--);
}
void UARTInterrupt() interrupt 4
{
if(RI) //接收中断
{
RI = 0; //清除接收中断标志
}
if(TI) //发送中断
{
TI = 0; //清除发送中断标志
}
}
```
需要注意的是,甲单片机和乙单片机之间的串口通信需要使用相同的波特率、数据位、校验位和停止位,以确保数据的正确传输。另外,在发送数据时需要注意数据的类型和范围,以免出现数据溢出或错误。
阅读全文