51单片机串口接收数组数据有误

我用VB做为上位机通过串口发送一组数据给51单片机,让单片机去控制其他设备,遇到如下问题:

VB的发送程序如下:
Private Sub Command3_Click()
Dim echoch
Dim kz(9) As Byte
If Text7.Text <> "" Then
echoch = Text7.Text
kz(0) = &H3
kz(1) = echoch
MSComm1.Output = kz
End If
Label22.Caption = echoch
End Sub

单片机的接收程序如下:
void serial () interrupt 4 using 3

{ uchar a;

a=0;

RI=0;

str[a++] =SBUF;

mc=str[0];

n=str[1];

}

遇到问题如下:

1、接收时每次都是str[0]=SBUF,不能使n=str[1],即总是将数据赋值给str[0],str[0]不断更新。而我是想将发送的第一个数据给str[0],第二个数据给str[1],这个问题该如何解决?

2、 Text7.Text中输入7,那么我想在单片机上,用7参与运算,但是串口发送时,会有数据类型转换,那么如何使n=str[1]后,把n的值转换成可以参加运算的数字7
Text7.Text中输入7是举个例子,Text7.Text输入任何数值,都要转化成能够参与运算的数字

单片机的接收程序作了如下改动,但还是不行
void serial() interrupt 4 using 3
{
uchar a = 0;

if(RI)
{
RI=0;
str3[a++]=SBUF;
}

mc=str[0];

n=str[1];

}

你使用这种方式发送VB数据的I话,发送的是ascii码,比如发送的数据是123的话,计算机会连续发送0X31,0X32,0X33,所以单片机接收程序,需要重新转换一下,你可是试着换一种方式发送十六进制数据

对于单片机接收程序,由于你发送的数据量比较小,而且发送数据时,相邻两个数据的时间间隔也很短,你可以在中断里面通过查询的方式接收数据包
void serial () interrupt 4 using 3

{ uchar a,cnt;

a=0;
cnt=250;//如果你的波特率比较低,而系统时钟又快的话,cnt应定义为int型,并把值设置的更大些

RI=0;
ES=0;//关闭串口中断
str[a++] =SBUF;
while(cnt--){//如果cnt等于0时退出循环
if(RI){
RI=0;
str[a++] =SBUF;
cnt=250;//接收到新的数据,重新设定超时
}
}

ES=1;//重新开串口中断
//这里可以做一个接收到数组的标志位,用于主程序查询处理相关数据
mc=str[0];

n=str[1];

}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-12-28
在你的串口中断子程序void serial () interrupt 4 using 3 中,
有: a=0;
这说明,你的串口中断子程序总是从0开始,也就是:
1。“接收时每次都是str[0]=SBUF,不能使n=str[1],即总是将数据赋值给str[0],str[0]不断更新。”
你只需去掉a=0即可。
2。Text7.Text中输入7,实际上你输入的是0x37,
如何使n=str[1]后,把n的值转换成可以参加运算的数字7?
将n=str[1] 改成:n=str[1]-0x30 即可。追问

用了你的方法,上位机发送数据,单片机就没有反应了。
Text7.Text中输入7是举个例子,我想Text7.Text输入任何数值,都要转化成能够参与运算的数字,该如何解决呢?

追答

将你单片机的程序改为如下:
void serial () interrupt 4
{
uchar a;
RI=0;
str[a] =SBUF;
a++;
mc=str[0];
n=str[1];
}

你的上位机
Dim kz(9) As Byte
。。。
kz(0) = &H3
kz(1) = echoch
MSComm1.Output = kz
。。。
似乎有点问题。

第2个回答  2011-12-28
void serial () interrupt 4 using 3
{
static uchar a = 0; //用static方式存储
RI=0;
str[a++] =SBUF;
mc=str[0];
n=str[1];
}
收到字符‘7’ 只要减掉‘0’ 就是数字 7了 即 n=str[1] -'0'
注意static方式a会一直累加,需要加判断,什么时候a要重新置0追问

用了您的方法,还是出现上述问题。
Text7.Text中输入7是举个例子,Text7.Text输入任何数字,都要转化成能够参与运算的数字,该如何解决呢?

追答

你打算使用多少个str[ ],就两个? 0 1 还是一直填充直到数组填满?
都说static 下a会一直增加,每收一个字节都会加1并保持,所以要考虑当前收到的SBU要放str[]位置。
你上位机不管充文件里读到什么,只要是用asc码方式发送下去,那么单片机收到的一定是字符‘7’。字符‘7’ -字符‘0’ 就过就转换称数字7 , 如果这个你都搞明白就自己去查ascII表去。

你单片机如何定位输入的数据?即收到上位机发的东西后如何确定要放到str[]的哪个位置?或者你读str[]的时候如何知道上位机的意图?简单的自定义协议总有吧?要不收到的数据放str[0]或者 str[1]乱了怎么办?

第3个回答  2011-12-29
问题1,将a定义为全局变量
问题2,将收到的数据进行格式转化,
str3[a++]=SBUF;后面加条 str3[a-1]=str3[a-1]-0x30;
还有个提示:就是你通信时数据可能有误码,需要加校验代码,只是说可能,
比如(不包括起始位和终止位):0xf0,,0x0f两个字节 bit:1111 0000 0000 1111
如果前面的 1111没有收到的话 就可能是 0000 0000 1111 xxxx 即0x00 0xf*,xxxx为未知。
第4个回答  2012-04-21
对于第一个问题,每进入一次中断,a赋值为0一次,故只有str[0]能收到数据,可以将uchar a;改为static uchar a;静态变量只能被初始化一次,故第二次及第N次进入中断的话不能改变上一次的值,但要注意a的清零
对第二个,我不知道,不好意思
第5个回答  2012-01-01
发送接收适当加入延时
相似回答