51单片机串口接收数据包函数 给我个标准的吧

2025-04-02 12:55:39
推荐回答(3个)
回答1:

惜忆泪情 的方式不可取。将收到的数据显示到数码管上,如果是动态扫描,那麽有一个问题,扫描间隔会有个几ms,这就会影响下一个数据进入中断,因此带来丢包问题。如果是静态显示,不知道有何意义。

一般类似于这种情况,建议你建立个数组存放。
#include

#define DataLen 10 //定义为10个数据为一帧,产生一次标志位。
unsigned char Data[DataLen];
unsigned char Datai; //用于记录当前接收了多少
bit Flag; //产生接收完成标志位。
void InitUART(void)
{
TMOD = 0x20;
SCON = 0x50;
TH1 = 0xFD;
TL1 = TH1;
PCON = 0x00;
EA = 1;
ES = 1;
TR1 = 1;
}

void main(void)
{
InitUART();
while(1)
{
if(Flag)
{
Flag=0;
//表示 收到十个数据了。你该干啥就干啥,在这里加入你的代码。
}
}
}
void UARTInterrupt(void) interrupt 4
{
if(RI)
{
RI = 0;
Data[Datai++]=SBUF;
if(Datai==DataLen)
{
Flag=1;
Datai=0;
}
}
}

这是一种方式,不过一种具有协议的话,都会加上一个定时器,就是你一开始接收第一个数据开始,我就开始计时,每进来一个,我就清零一次定时器,如果定时大于5ms我就认为你收完了,再判断数据包的长度,如果长度不够,就表示 丢包了。 协议上一般需要用到这种方式,叫接收超时计数。

这个代码我一直在用,没什么问题。

希望可以帮到你,有什么问题欢迎一起探讨。

回答2:

//初始化串口
void init_serialcomm(void)
{
SCON=0x50; //在11.0592MHz下,设置串行口波特率为9600,方式1,并允许接收
PCON=0x00;
ES=1; //开串口中断
TMOD=0x21; //定时器工作于方式2,自动装载方式
TL1=0XFD;
TH1=0XFD;
TR1=1;
EA=1;

}
//中断服务程序
void serial () interrupt 4 using 3

{
if(RI)
{
RI=0;//清中断标志
ch=SBUF;//读取接收寄存器
ch=SBUF;
leddisp(ch);//调用数码管显示子程序,将接收到的数据显示到数码管上
}
if(TI)
{
TI=0;//清发送标志位
}
}

回答3:

void init() //中断初始化
{
TMOD=0x20;
TH1=0xfd; //晶振11.0592下,波特率9600
TL1=0xfd;
SCON=0x50;
ES=1;
EA=1;
TR1=1;
}
void send(unsigned char dat)//发送数据
{
SBUF = dat;
while(!TI);
TI = 0;
}
void serie() interrupt 4 //中断处理接收
{
int cou=0xff;
if(RI==1)
{
cou=SBUF;
RI=0;
}

}