串口发送十六进制问题

enix 2008-10-15 01:55:08
使用mscomm控件.
发送数据格式为 !S# & 十六进制 FF & 十六进制 FF & 十六进制 FF & @
中间有三个十六进制的数字,我的写法是
mscomm1.output = chr(XX) & chr(XX) & chr(XX) & chr(XX) & chr(XX) & chr(XX) & chr(XX)
然后出问题了,十六进制的数字如果超过128,就变成00了.
求助!谢谢大家的帮忙.

但是必须是mscomm1.output = chr(XX) & chr(XX) & chr(XX) & chr(XX) & chr(XX) & chr(XX) & chr(XX)格式的.
我试过用
dim cc(7) as bytes
cc(0)=XX
cc(1)=XX
cc(2)=XX
cc(3)=XX
cc(4)=XX
cc(5)=XX
cc(6)=XX
....
mscomm1.output=cc
这样不行,下位机不理我.
...全文
376 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
squller 2008-10-16
  • 打赏
  • 举报
回复
zdingyun 讲的把 text1.text\65536 改成 Val(text1)\65536.确实比较严谨一点.
但是如果还是又人要输入字符串,谁也没办法,所以我感觉使用 Val()也不见得是个什么好办法.
强烈建议 使用 On Error Resume Next 或者 Goto Err之类的.
不至于输入错误就报错退出.
squller 2008-10-16
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 enix 的回复:]
void comm_int() interrupt 4
{
unsigned char b1;
if(RI)
{
RI=0;
b1=SBUF;
com_buff[com_num]=b1;com_num++;
if(com_num==3)
{
if(com_buff[0]==0x21&&com_buff[1]==0x41&&com_buff[2]==0x40) //!A@
{check_flag=1;com_num=0;}
if(com_buff[0]==0x21&&com_buff[1]==0x52&&com_buff[2]==0x40) //!R@
{f_run=1;com_num=0;}
if(com_buff[0]==0x21&&com_buff[1]==0x54&&com_buff[…
[/Quote]

是51单片机吧?从这里来看,中断是没什么问题,而且是只收三个byte或者7个或者....就判断,给出标志位.
很明显是数组多发了一位造成的.相信我和楼上的.不相信你就试一下.
Dim a1, a2, a3 As Integer
Dim st1, st2, st3, st_all As String

ReDim matrix(6) //如果以前就定义过 matrix() 为byte的话,这里 as 不 as 无所谓了.但是要把下标改一下!必须的!
matrix(0) = &H21 '!
matrix(1) = &H31 '1
matrix(2) = &H25 '%
matrix(6) = &H40 '@

That's All
ly012659 2008-10-16
  • 打赏
  • 举报
回复
Public Sub SendingMessage(msg As String)
SendingMsg = True
msg = addrStr1 & msg
Dim Out1() As Byte ''msg=轴号+命令+地址+数目
Dim Lrc As Long
Dim a As Integer
Dim L As Integer
L = Len(msg)
Dim i As Integer
Lrc = 0
For i = 0 To L / 2 - 1
a = Val("&H" & Mid(msg, 2 * i + 1, 2))
Lrc = a + Lrc
Next i
Lrc = Lrc Mod 256
Lrc = 256 - Lrc
If Lrc = 256 Then
Lrc = 0
End If
ReDim Out1(L + 4) As Byte
For i = 1 To L
Out1(i) = Asc(Mid(msg, i, 1))
Next i
If Lrc < 16 Then
Out1(L + 1) = Asc(Mid("0" & Hex(Lrc), 1, 1))
Out1(L + 2) = Asc(Mid("0" & Hex(Lrc), 2, 1))
Else
Out1(L + 1) = Asc(Mid(Hex(Lrc), 1, 1))
Out1(L + 2) = Asc(Mid(Hex(Lrc), 2, 1))
End If
Out1(0) = Asc(":")
Out1(L + 3) = &HD ''为结束符
Out1(L + 4) = &HA ''为结束符
If MainWin.MSComm1.PortOpen = True Then
MainWin.MSComm1.OutBufferCount = 0
MainWin.MSComm1.Output = Out1 '
End If
End Sub
上面的程序是我写的基于modbus协议的代码,希望对你有帮助
zdingyun 2008-10-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 enix 的回复:]
请大家注意看题,我不能使用数组发指令,否则下位机是没有响应的.

所以只能是 mscomm1.output= XXXXXXX

我也弄不明白为什么使用数组发数据它会只响应一次.以后再怎么按都没有用.

Private Sub Command1_Click()
'MSComm1.PortOpen = True

Dim a1, a2, a3 As Integer
Dim st1, st2, st3, st_all As String

ReDim matrix(7)
matrix(0) = &H21 '!
matrix(1) = &H31 '1
matrix(2) = &H25 …
[/Quote]
LZ:
1)上位机无论按BYTE数组还是以字符发送,如果字节内容是同样的,那么输出端发出的字节(BYTE)流是完全相同的.
2)MSComm控件的InputMode设置仅指设置或返回 Input 属性取回的数据的类型,InputMode 属性确定 Input 属性如何取回数据。数据取回的格式或是字符串或是一数据组的二进制数据的数组。它与发送BYTE数组或字符串无任何关系.
3)从你的叙述看,没有涉及上下位机间的通信协议.请说明通信协议.
4)你贴出的代码处有几点错误,已经修改如下:
Private Sub Command1_Click()
'MSComm1.PortOpen = True
Dim a1, a2, a3 As Integer
Dim st1, st2, st3, st_all As String
ReDim matrix(6) As Byte '未将数组定义为BYTE数组以及下标错误,使的多发1字节
matrix(0) = &H21 '!
matrix(1) = &H31 '1
matrix(2) = &H25 '%
matrix(6) = &H40 '@
a1 = Val(Text1) \ 65536
If a1 < 15 Then
st1 = "0" & Hex(a1)
Else
st1 = Hex(a1)
End If
matrix(3) = "&H" & st1
a2 = (Val(Text1) Mod 65536) \ 256
If a2 < 15 Then
st2 = "0" & Hex(a2)
Else
st2 = Hex(a2)
End If
matrix(4) = "&H" & st2
a3 = (Val(Text1) Mod 65536) Mod 256
If a3 < 15 Then
st3 = "0" & Hex(a3)
Else
st3 = Hex(a3)
End If
matrix(5) = "&H" & st3
MDIForm1.MSComm1.OutBufferCount = 0 '清空发送缓冲区
MDIForm1.MSComm1.Output = matrix
Label8.Caption = MDIForm1.MSComm1.Input
End Sub

enix 2008-10-15
  • 打赏
  • 举报
回复
void comm_int() interrupt 4
{
unsigned char b1;
if(RI)
{
RI=0;
b1=SBUF;
com_buff[com_num]=b1;com_num++;
if(com_num==3)
{
if(com_buff[0]==0x21&&com_buff[1]==0x41&&com_buff[2]==0x40) //!A@
{check_flag=1;com_num=0;}
if(com_buff[0]==0x21&&com_buff[1]==0x52&&com_buff[2]==0x40) //!R@
{f_run=1;com_num=0;}
if(com_buff[0]==0x21&&com_buff[1]==0x54&&com_buff[2]==0x40) //!T@
{f_run=0;com_num=0;}
}
if(com_num==7)
{
if(com_buff[0]==0x21&&com_buff[1]==0x31&&com_buff[2]==0x25&&com_buff[6]==0x40)
{f_setime=1;com_num=0;}
}
if(com_num==6)
{
if(com_buff[0]==0x21&&com_buff[1]==0x32&&com_buff[2]==0x25&&com_buff[5]==0x40)
{f_setdisp=1;com_num=0;}
if(com_buff[0]==0x21&&com_buff[1]==0x33&&com_buff[2]==0x25&&com_buff[5]==0x40)
{f_setpower=1;com_num=0;}
}
if(com_num==5)
{
if(com_buff[0]==0x21&&com_buff[1]==0x34&&com_buff[2]==0x25&&com_buff[5]==0x40)
{f_seterr=1;com_num=0;}
if(com_buff[0]==0x21&&com_buff[1]==0x35&&com_buff[2]==0x25&&com_buff[5]==0x40)
{f_setmode=1;com_num=0;}
if(com_buff[0]==0x21&&com_buff[1]==0x36&&com_buff[2]==0x25&&com_buff[5]==0x40)
{f_setcur=1;com_num=0;}
}
}
// if(TI)
// {
// com1_send_byte(0x23);
// TI=0;
// }

}

这是下位机部分
enix 2008-10-15
  • 打赏
  • 举报
回复
我的字符串最后@就是结束符.
我也不知道,现在头晕,都不知道是下位机出问题了还是上位机出问题了.
打死不掉牙 2008-10-15
  • 打赏
  • 举报
回复
我以前做一个程控电源也是那样,好像结束时需要一个结束符,我的就是"回车"符,如果没有回车符结尾它只会返回一次,所以你试试看,我也不确定
打死不掉牙 2008-10-15
  • 打赏
  • 举报
回复
你试试
matrix(0) = &H21 '!
matrix(1) = &H31 '1
matrix(2) = &H25 '%
matrix(3) = &H45
matrix(4) = &H23
matrix(5) = &H56
matrix(6) = &H40 '@
matrix(7)= vbcr

mscomm1.output=matrix
enix 2008-10-15
  • 打赏
  • 举报
回复
MSComm0.InputMode = comInputModeBinary
在 form_load 的时候就已经加上了.
enix 2008-10-15
  • 打赏
  • 举报
回复
如果我直接发送

mscomm1.output= "!1%" & hex(45) & Hex(23) & Hex(56) & "@"

就更不对了.我曾经试用过
dim cc(256) as byte
for i =0 to 255
cc(i) =i
next

再使用 mscomm1.output= "!1%" & cc(45) & cc(23) & cc(56) & "@" 就有语法错误.怎么办啊?
打死不掉牙 2008-10-15
  • 打赏
  • 举报
回复
你把发送类型改了吗?发送二进制要先加上

MSComm0.InputMode = comInputModeBinary '//以二进制形式发送和接收
enix 2008-10-15
  • 打赏
  • 举报
回复
刚才我又尝试了一次,如果是

matrix(0) = &H21 '!
matrix(1) = &H31 '1
matrix(2) = &H25 '%
matrix(3) = &H45
matrix(4) = &H23
matrix(5) = &H56
matrix(6) = &H40 '@

mscomm1.output=matrix
下位机只相应一次,有一个组数的反馈这个里面,我把该数据设置为 45*65536+23*256+56=4531030
但是这个数据只反馈一次.
如果我把写法改成

mscomm1.output= "!1%" & chr(69) & chr(35) & chr(86) & "@"
就没有任何问题,只要发送这个指令就可以获得数据反馈.

帮帮我吗,很着急啊
打死不掉牙 2008-10-15
  • 打赏
  • 举报
回复
请大家注意看题,我不能使用数组发指令,否则下位机是没有响应的.
这句话不知道你是怎么理解的,比如你发字符串"ABC",ABC对应的ASCII是&H41,&H42,&H43.发送的数据实质上和你发送数组byt一样(其中byt(0)=&H41,byt(1)=&H42,byt(2)=&H43)
MDIForm1.MSComm1.Output="ABC"和MDIForm1.MSComm1.Output=byt是一样的
enix 2008-10-15
  • 打赏
  • 举报
回复
请大家注意看题,我不能使用数组发指令,否则下位机是没有响应的.

所以只能是 mscomm1.output= XXXXXXX

我也弄不明白为什么使用数组发数据它会只响应一次.以后再怎么按都没有用.

Private Sub Command1_Click()
'MSComm1.PortOpen = True

Dim a1, a2, a3 As Integer
Dim st1, st2, st3, st_all As String

ReDim matrix(7)
matrix(0) = &H21 '!
matrix(1) = &H31 '1
matrix(2) = &H25 '%
matrix(6) = &H40 '@

a1 = Text1.Text \ 65536
If a1 < 15 Then
st1 = "0" & Hex(a1)
Else
st1 = Hex(a1)
End If
matrix(3) = "&H" & st1

a2 = (Text1.Text Mod 65536) \ 256
If a2 < 15 Then
st2 = "0" & Hex(a2)
Else
st2 = Hex(a2)
End If
matrix(4) = "&H" & st2

a3 = (Text1.Text Mod 65536) Mod 256
If a3 < 15 Then
st3 = "0" & Hex(a3)
Else
st3 = Hex(a3)
End If
matrix(5) = "&H" & st3

MDIForm1.MSComm1.OutBufferCount = 0 '清空发送缓冲区
'st_all = Chr(33) & Chr(49) & Chr(37) & Chr(CInt("&H" & st1)) & Chr(CInt("&H" & st2)) & Chr(CInt("&H" & st3)) & Chr(64)
'st_all = Chr(33) & Chr(49) & Chr(37) & Chr(1) & Chr(224) & Chr(244) & Chr(64)

MDIForm1.MSComm1.Output = matrix 'st_all
Label8.Caption = MDIForm1.MSComm1.Input

End Sub

这样就是不行.如果是 mscomm1.output="!S%" & chr(0f) & chr(12) & chr(23) & "@"
就无论按多少次都没问题.
但是如果 Chr(XX) 的XX大于 128就变成发送00出去.
问题就是这样,感觉大家帮忙,请继续帮助解答.谢谢.
现在还是人类 2008-10-15
  • 打赏
  • 举报
回复
如果你的XX是16进制,那么应该这样
dim cc(7) as bytes
cc(0)=Int("&H" & XX)
cc(1)=Int("&H" & XX)
cc(2)=Int("&H" & XX)
cc(3)=Int("&H" & XX)
cc(4)=Int("&H" & XX)
cc(5)=Int("&H" & XX)
cc(6)=Int("&H" & XX)
zdingyun 2008-10-15
  • 打赏
  • 举报
回复
[Quote=引用楼主 enix 的帖子:]
使用mscomm控件.
发送数据格式为 !S# & 十六进制 FF & 十六进制 FF & 十六进制 FF & @
中间有三个十六进制的数字,我的写法是
mscomm1.output = chr(XX) & chr(XX) & chr(XX) & chr(XX) & chr(XX) & chr(XX) & chr(XX)
然后出问题了,十六进制的数字如果超过128,就变成00了.
求助!谢谢大家的帮忙.

但是必须是mscomm1.output = chr(XX) & chr(XX) & chr(XX) & chr(XX) & chr(XX) & chr(XX) & chr(XX)格式的.
我试…
[/Quote]
使用数Byte数组及String字符混合发送:
Dim sj as String
sj = "!S#"
MsComm1.output = sj
Dim cc(2) as byte
cc(0)=&HFF
cc(1)=&HFF
cc(2)=&HFF
MsComm1.output=cc
sj = "@"
MsComm1.output = sj

或者全部使用Byte数组发送
Dim cc(6) as byte
cc(0)=Asc("!")
cc(1)=Asc("S")
cc(2)=Asc("#")
cc(3) = &HFF
cc(4) = &HFF
cc(5) = &HFF
cc(6) = Asc("@")
MsComm1.output = cc



1,451

社区成员

发帖
与我相关
我的任务
社区描述
VB 控件
社区管理员
  • 控件
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧