单片机与PC机串口通讯

我用51单片机做了一个板子,是89C51的芯片,通过MAX232与电脑串口通讯,通过串口发送来一个6位数,比如是发送123456,在串口调试助手数据发送区里直接写上ff1... 我用51单片机做了一个板子,是89C51的芯片,通过MAX232与电脑串口通讯,通过串口发送来一个6位数,比如是发送123456,在串口调试助手数据发送区里直接写上ff 12 34 56(中间有空格),点十六进制发送,然后点手动发送,单片机通过串口接收之后将6位数在数码管上显示出来。(具体情况是主机电脑直接发送过来一个数据包,先发送十六进制的ff,作为一个发送标志,接着发送12 34 56,整个数据包的格式就是十六进制的ff 12 34 56)

现在我做出来了一个程序,能将串口发送过来的两位十六进制数据在单片机上显示出来。具体情况是:先在串口调试助手数据发送区写上ff,点发送,单片机收到标志之后开始接收数据,接着我把ff清除,写入12,点发送,单片机接收到12之后在前面两个数码管显示出来;接着我把12清除,写入34,点发送,单片机接收到34之后在中间两个数码管显示出来;再接着我把34清除,写入56,点发送,单片机接收到56之后在后面两个数码管显示出来,这样123456这个六位数就通过我4次输入才在数码管上显示出来。这个程序目前已经在我的实验板上试验好使了。

但是问题是我在串口调试助手数据发送区里直接写上ff 12 34 56(中间有空格)之后在点发送,单片机显示的却是乱码(不能正确的显示出123456),不知道是什么原因。我的串口调试助手波特率设置的是9600,跟单片机一样。

整个单片机板子的作用就是接收串口传过来的六位数,在数码管上显示出来。我用的是Keil uVision2软件编的程序。本来我想用51单片机的串口寄存器接收串口数据之后直接显示出来,后来发现串口寄存器只有8位,即只能接收8位二进制或两位十六进制,我只好把六位数拆成三个两位数,一个一个的发送。但现在直接发送数据包的话单片机又会出错(即直接发送ff 12 34 56),不知道是什么原因呢?

如果这个无法解决的话也可以告诉我一个别的办法,即单片机能一下子接收六位数(如123456),而不用拆成两位两位的发送。

寻求解决办法,不胜感激!
上面写错了一点,用的是RS232与电脑通讯。

对了,我想知道串口调试助手里面的空格代表什么意思,能否具体说明一下。

我用的是查询的方式来接收的数据,定义4个全局变量来存储接收到的4个两位数据。
当我查询到RI为1之后,便按循序将接收到的第几个数据存储到第几个全局变量里。比如我定义了dat,dat0,dat1,dat2,当查询到串口有数据时,即RI==1时,此时如果电脑发送的是第一个数据ff,便将ff保存到dat,如果是第二个数据12,便将12保存到dat0,接下去同理。查询了一次之后便调用数码管显示子程序。

感谢科尔兄的帮忙,我找出原因来了,果然是DELAY的延时太长,从而导致数据丢失。
问题已经解决了,分给你。
再次谢谢了。
展开
 我来答
科尔Ker
2009-01-07 · TA获得超过731个赞
知道小有建树答主
回答量:130
采纳率:0%
帮助的人:0
展开全部
1,你的程序delay是如何实现的,是不是长时间占用CPU资源的?因为串行数据传送是连续的,第一个数据ff接收到之后在SHUMA1()函数中delay了这么久再查询串口,之后的数据早就发送完毕了,你可能接收不到之后的了。这样可以解释为什么你一位一位发送的话显示没有问题。因为你手动发送的延时肯定>SHUMA1()函数中delay的总时间。
2,你的程序中SHUMA1()函数是在大循环中循环的。每次运行到if(RI)这行的之间的时间间隔都很久了。不利于连续接收数据。
3,还有其他的可能,我发你一个串口监控软件,可以第三方监控串口通讯。便于你调试。
4,基本上所有的串口调试助手在十六进制发送的情况下,里面空格都是无意义,只是用来把两个字节间隔开。
6,查邮件peanot@163.com
7,有问题再补充
peanot1
2009-01-07
知道答主
回答量:1
采纳率:0%
帮助的人:0
展开全部
由于字数限制,我另外附上我的部分程序:

if ( RI ) //扫描判断是否接收到数据,
{
if(a==0)
{
temp1=SBUF; //接收数据SBUF赋与dat0
RI=0; //RI清零
if(temp1==0xff)
a++;
}

else if(a==1)
{
dat0 = SBUF;
RI=0;
a++;
}

else if(a==2)
{
dat1 = SBUF;
RI=0;
a++;
}

else if(a==3)
{
dat2 = SBUF;
RI=0;
a++;
}

else if(a==4)
{
temp=SBUF;
str0=temp;
RI=0;
}
a=0;
}

SHUMA1(); //显示接收到的数据

我的数码管显示子程序如下:

sbit gewei=P2^2; //个位选通定义
sbit shiwei=P2^3; //十位选通定义
sbit baiwei=P2^4; //百位选通定义
sbit qianwei=P2^5; //千位选通定义
sbit wanwei=P2^6; //万位选通定义
sbit shiwanwei=P2^7; //十万位选通定义

void SHUMA1() //数码管显示接收到的数据
{
shiwanwei=0;
P0=table[dat0/16]; //十万位
Delay(8);
shiwanwei=1;

wanwei=0;
P0=table[dat0%16];//万位
Delay(5);
wanwei=1;

qianwei=0;
P0=table[dat1/16]; //千位
Delay(5);
qianwei=1;

baiwei=0;
P0=table[dat1%16]; //百位
Delay(5);
baiwei=1;

shiwei=0;
P0=table[dat2/16]; //十位
Delay(5);
shiwei=1;

gewei=0;
P0=table[dat2%16]; //个位
Delay(5);
gewei=1;

}

现在我还不清楚串口调试助手里面空格的意义,以及它是如何发送数据包的。我用的是串口调试助手V2.1。
另外补充一下,板子的功能就是快速的接收电脑发送过来的一个又一个的大量的数据包,并快速的在数码管上显示出来,数码管不断的快速刷新一个又一个的数据,直到显示出最后一个数据。大体作用就是这样。

我的邮箱是:peanot@163.com
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
dreamcan
2009-01-06 · 超过23用户采纳过TA的回答
知道答主
回答量:57
采纳率:0%
帮助的人:79.3万
展开全部
最好附上程序来看看。你是用中断来做吧?中断一次接受一个8位数据,比如12,然后存储在一个单元,再中断一次再存储在下一个单元(34),依次类推。。最后判断接受完所有数据了,再进行数据的处理,你这样就可以一次性发送123456这串数据了。
在串口调试助手里,在发送选项里如果没选以16进制发送,那空格就代表ASCII码的20,选中以16进制发送好像空格没影响,这点待验证
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
simonray1986
2009-01-05 · TA获得超过284个赞
知道小有建树答主
回答量:232
采纳率:50%
帮助的人:172万
展开全部
RS232的波特率也要设置的!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式