51单片机串口通信实现led灯的开关

首先需要了解的是,单片机的P3.1/TXD引脚可以实现发送数据的功能,P3.0/RXD可以实现接收数据的功能。
工作原理大致就是将一组引脚的通过开关控制高低电平,利用TXD引脚将数据发送给另一块芯片,芯片通过接收到的数据来控制led的状态。
发送方电路:
![控制电路](https://img-blog.csdnimg.cn/20190929184848675.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMwMjQ3OTQ5,size_16,color_FFFFFF,t_70

接收方电路:
![显示电路](https://img-blog.csdnimg.cn/20190929184918336.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMwMjQ3OTQ5,size_16,color_FFFFFF,t_70
两块芯片分别用TXD引脚/RXD引脚进行发送数据和接收数据。发送方只需要编写一个发送函数,通过while(1)循环,不断更新发送并更新缓存区的数据,达到实时发送数据的目的。
发送方代码:
#include <reg51.h>

void init(unsigned int bps)//初始化,设置不同波特率下计数器的初始值
{
unsigned char t;
SCON=0x50; //设置寄存器工作方式
PCON=0x00;//smod=0,波特率不倍增
TI=0;//软件清零
EA=1;//总中断开启
ET1=1;//计数器中断开启
ES=1;//串口中断开启
TMOD=0x20;//设置中断模式
switch(bps)//设置不同波特率下计数器初值
{
case 1200:t=0xe8;break;
case 2400:t=0xf4;break;
case 4800:t=0xfa;break;
case 9600:t=0xfd;break;
}
TH1=t;
TL1=t;//设置计数初值
TR1=1;//开启计数器
}
void send(unsigned char ch)
{
ES=0;//关闭串口中断
SBUF=ch;//发送数据到缓存区(ch可以看成是一个指向需要发送数据的指针)
while(TI==0);//等待数据发送完成
TI=0;//清除中断标记
ES=1;//开启串口中断
}
void main()
{
init(9600);//初始化,设置波特率
while(1)
{
send(P0);//循环发送P0口的数据
}
}

接收方所需要做的就是不断接收并读取缓存区的数据,并更新P0引脚的状态。
#include <reg51.h>
void init(unsigned int bps)
{
unsigned char t;
SCON=0x50;//设置寄存器工作方式
PCON=0x00;//smod=0,波特率不倍增
TI=0;//软件清零
EA=1;//总中断开启
ET1=1;//计数器中断开启
ES=1; //串口中断开启
TMOD=0x20;//设置中断模式
switch(bps)//设置不同波特率下计数器初值
{ case 1200:t=0xe8;break;
case 2400:t=0xf4;break;
case 4800:t=0xfa;break;
case 9600:t=0xfd;break;
}
TH1=t;
TL1=t;//设置计数初值
TR1=1;//开启计数器
}

void main()
{
init(9600);//初始化,设置波特率
while(1)
{
while(RI= =0);//等待接受完成 }
}
void receive() interrupt 4
{
if(RI= =1)
{
RI=0;
P0=SBUF;//接收到的数据赋值给P0
}
}

效果图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190929185127413.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMwMjQ3OTQ5,size_16,color_FFFFFF,t_70
使用开关控制U1的P0引脚的电平的高低来改变P0引脚的值。通过TXD发送数据到U2,将U2接收到的数据发送赋值给P0引脚控制小灯的开关。

  • 23
    点赞
  • 150
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,以下是基于51单片机串口通信的控制流水的程序: ```c #include <reg51.h> #include <stdio.h> #define uchar unsigned char #define uint unsigned int sbit LED1 = P0^0; sbit LED2 = P0^1; sbit LED3 = P0^2; sbit LED4 = P0^3; void InitUART() { // 初始化串口 TMOD |= 0x20; // 设置定时器1为模式2 TH1 = 0xFD; // 波特率为9600,TH1=(256-11059200/12/32/9600) TL1 = 0xFD; TR1 = 1; // 启动定时器1 SCON = 0x50; // 串口工作在模式1 ES = 1; // 使能串口中断 EA = 1; // 使能总中断 } void SendData(uchar dat) { // 发送一个字节的数据 TI = 0; // 清除发送完成标志 SBUF = dat; // 将数据写入发送缓冲区 while(!TI); // 等待发送完成 } void main() { uchar ch; // 用于接收串口数据的变量 uchar i = 0; // 计数变量 InitUART(); // 初始化串口 while(1) { if(RI) { // 如果接收到了数据 ch = SBUF; // 读取接收缓冲区的数据 RI = 0; // 清除接收中断标志 switch(ch) { case '1': // 收到1表示启动流水 while(1) { LED1 = 1; LED2 = 0; LED3 = 0; LED4 = 0; for(i = 0; i < 100; i++); // 延时一段时间 LED1 = 0; LED2 = 1; LED3 = 0; LED4 = 0; for(i = 0; i < 100; i++); LED1 = 0; LED2 = 0; LED3 = 1; LED4 = 0; for(i = 0; i < 100; i++); LED1 = 0; LED2 = 0; LED3 = 0; LED4 = 1; for(i = 0; i < 100; i++); } break; case '0': // 收到0表示关闭流水 LED1 = 0; LED2 = 0; LED3 = 0; LED4 = 0; break; default: // 收到其他字符,回复错误信息 SendData('E'); SendData('R'); SendData('R'); SendData('O'); SendData('R'); break; } } } } void UART() interrupt 4 { // 串口中断服务程序 if(RI) RI = 0; // 清除接收标志 if(TI) TI = 0; // 清除发送标志 } ``` 在程序中,我们通过串口接收PC端发送的数据来控制流水开关。如果收到字符'1',则将LED设置为流水模式,如果收到字符'0',则关闭流水,如果收到其他字符,则发送错误信息。 需要注意的是,在使用串口通信时,需要让单片机和PC端的波特率、数据位、停止位和校验位等参数一致,否则通信会出现问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿来如此yyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值