有关问题未结,再发一蛋——MSCOMM控件 and CSerialport类,强淫们请进!

问题未结,再发一蛋——MSCOMM控件 and CSerialport类,强淫们请进!!
程序功能:向串口写指令数据。

已采用MSCOMM控件方式实现,代码见下面所附,其中函数SendGpsCmd();是我用来往串口写“指令数据”的函数。

其中定义了两种发送模式:
第一种模式ModeAnsi用来发送诸如“$PSRF100,0,57600,8,1,0*37”格式的指令数据;
第二种模式ModeHex用来发送诸如“A0A20007961E540006000A0118B0B3”格式的指令数据(谁能解释一下这种指令的格式规则?);

该函数工作正常。有一款软件叫“串口调试精灵”,就是这样实现的。它有一种“按十六进制发送”方式,就是上述第二种模式的方式。

//参数i我用来标示不同的串口
void   CGpsTestWizardDlg::SendGpsCmd(int   i,int   iMode,   CString   szSendStr)
{
int   len;
CByteArray   hexdata;

switch(iMode)
{
case   ModeAnsi:
pCom[i]-> SetOutput(COleVariant(szSendStr));
break;

case   ModeHex:
len=StringToHex(szSendStr,hexdata);
pCom[i]-> SetOutput(COleVariant(hexdata));
break;
}
}

int   CGpsTestWizardDlg::StringToHex(CString   str,   CByteArray   &senddata
{
int   hexdata,   lowhexdata;
int   hexdatalen=0;
int   len=str.GetLength();

senddata.SetSize(len/2);

for(int   i=0;i <len;)
{
char   lstr,   hstr=str[i];
if(hstr== '   ')//空格时
{
i++;
continue;
}
i++;

if(i> =len)//转换完毕
break;

lstr=str[i];//lstr为str[i]后一个字符
hexdata=ConvertHexChar(hstr);
lowhexdata=ConvertHexChar(lstr);
if((hexdata==16)||(lowhexdata==16))
break;
else  
hexdata=hexdata*16+lowhexdata;
i++;
senddata[hexdatalen]=(char)hexdata;
hexdatalen++;
}

senddata.SetSize(hexdatalen);
return   hexdatalen;
}

//这是一个将 "字符 "转换为相应的十六进制值的函数
//功能:若是在0-F之间的字符,则转换为相应的十六进制字符,否则返回-1
char   CGpsTestWizardDlg::ConvertHexChar(char   ch)  
{
if((ch> = '0 ')&&(ch <= '9 '))//0的ascii码是48,即0x30
return   ch-0x30;
else   if((ch> = 'A ')&&(ch <= 'F '))//A--   65
return   ch- 'A '+10;
else   if((ch> = 'a ')&&(ch <= 'f '))//a   --97
return   ch- 'a '+10;
else   return   (-1);
}


程序目标:要在新创建的线程中操作和使用mscomm控件,而在主程序中读取mscomm控件从串口中出来的数据。却发现MSCOMM无法与多线程联合使用(ps:或者是我未得其法?),所以考虑使用网络上的CSerialport类来实现。

CSerialport类往串口写数据的函数是:CSerialPort::WriteToPort(char*   string);

熟悉CSerailport类的达人注意了,问题在此:
我用该函数发送“$PSRF100,0,57600,8,1,0*37”是正常的。
可是用来发送“A0A20007961E540006000A0118B0B3”则不对,跟预期不一致。也就是说怎么使用WriteToPort(char*   string)完成上述第二种模式的数据发送?是要对该函数作什么改写,还是要对“十六进制字符串”作什么处理?

内容比较多,希望表述清楚了,先感谢大家帮忙!急待

------解决方案--------------------
楼主,MSCOMM空间控件可以在多线程中使用,我以前用过,同时工作十几个串口两两工作为一个线程。


用文件形式做串口通讯,楼主要注意都是以字节char 形势发送的,变成别的形势需要楼主自己处理。

------解决方案--------------------
A0A20007961E540006000A0118B0B3
这样的数据需要使用无符号字符数组来发送,你需要转换为unsigned char型
------解决方案--------------------
CSerailport处理发送NULL(0x00)字符会有问题,因为WriteToPort是按char*发送的,0x00被自动截断了,解决方法,增加一个函数,如:
// Write a BYTE[] to the port
//
void CSerialPort::WriteToPort(BYTE bWriteBuffer[],int nWriteBufferSize)
{
assert(m_hComm != 0);

//int nSize = sizeof(bWriteBuffer)/sizeof(BYTE);
memcpy(m_szWriteBuffer, bWriteBuffer, nWriteBufferSize);
m_nWriteBufferSize = nWriteBufferSize;

// set event for write
SetEvent(m_hWriteEvent);
}
------解决方案--------------------