需要有 通讯协议,可以自己设计 一个 如 多机通讯
指令码 机器号 数据1 数据2 - - - 数据n 校验码 结束码
这样 单片机可以判断 接收的数据 类型,接收到数据 先存放在 缓冲区,收到结束码后
再判断 指令 是否是 本机数据,是再按照 数据类型处理。#include <stdioh>
int main(void)
{
char ch[9];
int i = 0, j;
while (i < 9)
{
for (j = 0; j < 3; j++)
ch[i++] = getchar();
getchar(); // 消去\n
}
i = 0;
printf("输出\n");
while (i < 9)
{
for (j = 0; j < 3; j++)
putchar(ch[i++]);
putchar('\n');
}
return 0;
}void init_ser(){ TMOD=0X20;//定时器1工作在方式2 TH1=0XFD; TL1=0XFD; //波特率9600 TR1=1; EA=1; SM0=0; SM1=1; REN=1;//允许串口接收 ES=1;//开串口 中断 }void delay(unint z){ unint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); }void ser() interrupt 4 //中断函数不用声明 { if(RI==1) { RI=0; ser_receive=SBUF; if(ser_receive=='a') { m=1; } if( m==1 && ser_receive!='z') { receive_data[i]=ser_receive; i++;// if(i==36)// {// i=0;// ser_flag=1;// } } else if (ser_receive=='z') { i=0; m=0; ser_flag=1; xianshi=1; } } }void uart(){ if(ser_flag==1) { ES=0; ser_flag=0; for(j=0;j<57;j++) { SBUF=receive_data[j]; while(!TI); TI=0; delay(10); } ES=1; }}我刚写的,接受以a开始,以z结束的字符串,测试没问题。<!DOCTYPE HTML>
<html>
<head>
<meta >#include<reg51h>
#define uchar unsigned char
uchar recive[];
main()
{
uchar dat,i;
TMOD=0x20;
SCON=0x50;
TR1=1;
while(1)
{
if(RI)
{
RI=0;
dat=SBUF;
recive[i]=dat;
i++;
if(dat=='#')i=0;
}
}
}在51单片机中,我们使用上下位机时,我们通常会发送一串字符串,将它作为信号发给单片机处理。
因为串口通信时,发送信息是以一个个字符的形式发送过来的,所以接收的就是一个个字符,通常我们是一个字符数组保存,在进行下一步处理,同时字符数组长度固定有限,但是如果上位机发送的字符不满足我们想要处理的数据时,其接收的数据多出的部分就有可能保存在SBUF中, 影响接下来的数据接收,以至于接下来的数据不满足我们的要求。或是发送数据少于数组长度时,也会出错。
在这里我的解决办法(以下以STC12C5A60S2芯片为例):
void serial_port_one_init()
{ //根据自己单片机设置;
//221184M 波特率: 115200
SCON = 0x50;
BRT = 0xFA;
AUXR |= 0x04;
AUXR |= 0x01;
AUXR |= 0x10;
ES = 1;
EA = 1;
}
#define Data_SIZE 10 //数据长度 9位数据 + /r/n - /n =10位
char RevBuf[Data_SIZE]; //数据接收缓冲区
char temp[Data_SIZE]; //防数据抵消缓冲区
unsigned char flished_flag=0; //数据接收符合要求标志
int data_count=0; //数据长度
int temp_length; //数据长度
int data_flished_count = 0; //
char data_flished; //
void UART_one_Interrupt_Receive(void) interrupt 4
{
uchar temp;
if(RI==1)
{
RI=0;
temp=SBUF;
// senduart(temp); //用来测试过数据接收是否正确
if(temp!='\n') //判断是否接收到结束符
{
RevBuf[data_count]=temp;// 否,就存到RevBuf数组中
data_count++;
}
else
{
temp_length=data_count;//是,记录其数据长度
data_count=0;
}
}
}
void main(void)
{
serial_port_one_init(); //串口初始化
while(1)
{
if(Data_SIZE == temp_length) //判断数据长度是否满足我们的要求。
{
for(i=0;i<Wifi_Data_SIZE;i++)
{
temp[i]=RevBuf[i]; // 同时我们将temp作为缓冲区,防止数据被冲到
}
flished_flag=1; //数据接收成功标志
}
if(1==flished_flag) // 数据接收完整成功
{
wifi_flished_flag=0; //
//
//你想要实现的功能
/
switch(temp[1])
//我常把数据第一位或前几位作为指令,后几位作为数据,你也可以把整个发送的数据就作为指令。
{
case 'A' :
//具体 *** 作
break;
}
/
}
}
while(1);
}
同时某些特殊情况,我们会将数据写成:数据头+数据
分析数据头,实现其代表的功能
上位机中 要在发送数据的最后加上 ‘/n’这个字符
用串口工具测试时, 发送数据为:数据+enter键(其代表的是两个字符 /r /n)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)