本文为博主 日月同辉,与我共生,csdn原创首发。希望看完后能对你有所帮助,不足之处请指正!一起交流学习,共同进步!
> 发布人:@日月同辉,与我共生_单片机-优快云博客
> 欢迎你为独创博主日月同辉,与我共生点赞❤❤❤+关注👍+收藏🌹+评论☺。
系列专栏: 优快云-单片机串口通信学习系列🎁
> 我的格言是:“尽最大努力,做最好的自己!💪
要转载,请提前告知!!!
版权声明:本文为优快云博主「日月同辉,与我共生」的原创文章,优快云独一份。
目录
一、项目设计
1.1功能设计
虚拟串口com3发送数据,由单片机com1接收,CPU处理接收到的数据,让对应的LED亮。com3发数据0x01给单片机时,第一个LED亮;com3发数据0x02给单片机时,第二个LED亮;com3发数据0x03给单片机时,第三个LED亮;com3发数据0x04给单片机时,第四个LED亮。
1.2硬件设计
1.2.1串口设计
由于是com1与com3相互传输数据,所以com1的发送端TXD接com2的发送端TXD,com1的接收端RXD接com2的接收端RXD即可。
1.2.2LED模块设计
LED是共阳极接法,所以公共端接电源,LED要导通,右端(IO口)要是低电平。
1.3软件设计
1.3.1初始化
串口工作方式为方式1(8位异步通信),定时器采用定时器T1的工作方式2(8位自动重载),波特率为9600bit/s,晶振频率为11.0592Mhz。接收一帧数据的初始化,采用中断法。
串口通信中断法文章回顾:串口通信(二)-查询法与中断法-优快云博客
1.3.2接收中断
当单片机com1接收到数据时,RI自动置1,从而触发接收中断,中断时别忘记将RI清0,以便单片机下次能够正确接收。因为接收完数据后要处理LED,所以要定义标志位recv_flag,用于判断接收是否完成。
二、代码展示
2.1初始化
void UartInit(void) //9600bps@11.0592MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式
TL1 = 0xFD; //设置定时初始值
TH1 = 0xFD; //设置定时重载值
ET1 = 0; //禁止定时器中断
ES=1;
EA=1;
TR1 = 1; //定时器1开始计时
}
2.2接收中断
void ES_timer() interrupt 4
{
if(RI) //接收中断
{
RI=0;//RI清0
recv_date=SBUF;//接收数据
recv_flag=1;//标志位,=1时说明接收完成
}
}
2.3主程序
/*****************************************************************************
功 能:使用串口通信,采用中断法实现一帧数据的接收,并完成对应灯泡点亮的简单通讯协议
时 间:2023/10/28
*****************************************************************************/
#include <reg51.h>
#include "delay.h"
#include "uart.h"
void main()
{
UartInit();
while(1)
{
if(recv_flag)
{
switch(recv_date)
{
case 0x1:
P1=0xfe;break;
case 0x2:
P1=0xfd;break;
case 0x3:
P1=0xfb;break;
case 0x4:
P1=0xf7;break;
}
}
}
}
2.4其他文件
#ifndef __UART_H__
#define __UART_H__
#include <reg51.h>
#include <stdio.h>
extern unsigned char recv_date;
extern unsigned char recv_flag;
void UartInit();
void sendByte(unsigned char dat);
void sendString(unsigned char *dat);
char putchar(char c);
#endif
三、结果展示
下图标注如何使用串口助手com3发送数据给单片机的步骤(共5步)。
com3发送0x01:
com3发送0x02:
com3发送0x03:
com3发送0x04:
四、回顾文章及下文预告
回顾:
下一文讲述如何接收一串数据。
五、模块整合
目前,串口通信已经写了三篇,里面涉及到的函数要整合到一个.c文件和.h文件中。
串口模块uart.c文件
#include "uart.h"
unsigned char recv_date;
unsigned char recv_flag=0;
void UartInit(void) //9600bps@11.0592MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式
TL1 = 0xFD; //设置定时初始值
TH1 = 0xFD; //设置定时重载值
ET1 = 0; //禁止定时器中断
ES=1;
EA=1;
TR1 = 1; //定时器1开始计时
}
void sendByte(unsigned char dat) //发送一帧数据功能函数
{
SBUF=dat;
while(!TI);
TI=0;
}
void sendString(unsigned char *dat)//发送字符串函数
{
while(*dat != '\0')
{
sendByte(*dat++);
}
}
char putchar(char c)
{
sendByte(c);
return c;
}
void ES_timer() interrupt 4
{
if(RI) //接收中断
{
RI=0;
recv_date=SBUF;
recv_flag=1;
}
}
串口模块uart.h文件:
#ifndef __UART_H__
#define __UART_H__
#include <reg51.h>
#include <stdio.h>
extern unsigned char recv_date;
extern unsigned char recv_flag;
void UartInit();
void sendByte(unsigned char dat);
void sendString(unsigned char *dat);
char putchar(char c);
#endif
延时模块delay.c
#include "delay.h"
/******************************************************************************************
函数名:delay
功能:延时函数
参数:unsigned char xms
返回值:无
******************************************************************************************/
void delay(unsigned char xms)
{
unsigned char i,j;
for(i=xms;i>0;i--)
for(j=124;j>0;j--);
}
延时模块delay.h
#ifndef __DELAY_H__
#define __DELAY_H__
void delay(unsigned char xms);//延时函数声明
#endif
亲爱的读者敬请期待,下一文更精彩!!!
一日不读书,胸臆无佳想。我叫不白吃,喜欢我的,可以支持我,博主名叫@日月同辉,与我共生