void SendToCom(USHORT WrAddr,INT WrData)
{
BYTE send_pkt[10] = {0xEB,0x91,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4E};
send_pkt[2] = (UCHAR)WrAddr >> 8;
send_pkt[3] = (UCHAR)WrAddr;
send_pkt[4] = (UCHAR)(WrData >> 24);
send_pkt[5] = (UCHAR)(WrData >> 16);
send_pkt[6] = (UCHAR)(WrData >> 8);
send_pkt[7] = (UCHAR)(WrData);
send_pkt[8] = 0xEB+0x91+ send_pkt[2]+send_pkt[3]+send_pkt[4]+send_pkt[5]+send_pkt[6]+send_pkt[7];

UCHAR * comm_recvbuf = new UCHAR[20];

memcpy(&comm_recvbuf[0],&send_pkt,sizeof(send_pkt));
::PostMessage(AfxGetMainWnd()->m_hWnd, WM_SEND_SERIAL_DATA,  (WPARAM)comm_recvbuf,sizeof(send_pkt));
Sleep(150);
}void CComMonitorDlg::OnToComm(WPARAM p_packet_buf, LPARAM len)
{
char *pbuf=(char*)p_packet_buf;
if(!m_bSerialPortOpened) 
return; //检查串口是否打开
m_SerialPort.WriteToPort(pbuf,len);//发送数据
delete []pbuf;
}
void CComMonitorDlg::OnToComm(WPARAM p_packet_buf, LPARAM len)
{
UCHAR *pbuf=(UCHAR*)p_packet_buf;
UCHAR get_data[MAX_PACKET_LEN];
memset(get_data,0,sizeof(get_data));
memcpy(&get_data[0],pbuf,len);//201007
delete []pbuf;

CByteArray array; 
array.RemoveAll(); 
array.SetSize(len); 

for(int i=0;i<len;i++) 
{
array.SetAt(i, get_data[i]); 
}
m_MsComm.SetOutput(COleVariant(array)); // 发送数据
}
上面是我写的一部分代码:
        SendToCom是一个全局函数,程序运行过程中会调用这个函数,按照帧结构组成数据帧,然后发送消息给OnToComm;
        OnToComm是串口发送函数,第一个调用CSerialPort类中的WriteToPort,第二个调用Mscomm控件的发送函数;
        程序的对端是一个FPGA程序(用来接收我的串口指令);
现在的问题是:
        使用Mscomm控件发送则FPGA程序会收到指令,并可以解析,但是使用CSerialPort类却没有反应。
        我使用虚拟串口时,CSerialPort发送数据,对端的串口调试助手是可以收到的,而且格式都正确。
另外我现在使用mscomm控件写串口程序时,在《len=safearray_inp.GetOneDimSize();//得到有效数据长度》这里就总出错,然后程序就崩溃了,不能用,语法应该没问题,相同的程序拿到其他的机器上,有的机器和我的一样会出错,有的就可运行。请教各位大侠帮我看看哪里有问题呀?

解决方案 »

  1.   

    1.
        CSerialPort发送数据对方无响应,而MSCOMM却可以,那你就看看CSerialPort是否有发送时间超时,如果有,你看这个时间是否太短了导致发送失败.
        另外,你单步执行,看CSerialPort发送的数据是什么,是不是转换错了,这样就把转换错的数据发出去了:char *pbuf=(char*)p_packet_buf;,是不是应该改成UCHAR *pbuf=(UCHAR*)p_packet_buf;
    2. 
        mscomm出错的提示是什么,是否这个变量实际无效,你可以先执行工程清除,然后再重新完全编绎一次.同时,你可以把safearray_inp这个变量定义在接收函数开始处或定义成全局变量.同样可以单步执行,在这个语句的前一句你先看看这个变量的有关信息,是否已有数据,是否这个变量有效.
        另外,也可能和操作系统有关,这个控件我没在WIN7上用过,不知道行不行
      

  2.   

    Mscomm控件,这个有问题,建议不要用。
      

  3.   

    1 用物理的串口接收试试看,是不是波特率、校验位、停止位等设置不一样2 mscomm 接收那一段是怎么写的?
      

  4.   


    void CComMonitorDlg::OnCommMscomm() 
    {
    COleSafeArray safearray_inp;
    COleVariant coleVariant; LONG len=0,k=0;
    BYTE rxData[32760]; //设置BYTE数组 An 8-bit integerthat is not signed.
    if(m_MsComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
     { ////////以下你可以根据自己的通信协议加入处理代码
    coleVariant.Attach(m_MsComm.GetInput()); //解决程序运行时内存不断增加的bug
    safearray_inp = coleVariant;  len=safearray_inp.GetOneDimSize();//得到有效数据长度
     for(k=0;k<len;k++)
     {
     safearray_inp.GetElement(&k,rxData+k);//转换为BYTE型数组
     }
              }
    }多谢上面的三位能抽空帮我分析问题,多谢。
    上面是MSCOMM接收的代码,好像和其他的差不多,而且到某些机器上还能使用,在出错的计算机上面,会弹出一个错误提示:Unhandled exception in CommMonitor.exe(MFC042D.DLL) 0x00000005 Access violation.
    一般碰到这样的错误我就快吐血了,不知道从什么地方查。一楼提出来的char *pbuf=(char*)p_packet_buf;,是不是应该改成UCHAR *pbuf=(UCHAR*)p_packet_buf;
    原来是UCHAR *pbuf=(UCHAR*)p_packet_buf;后来让我改成char *pbuf=(char*)p_packet_buf;因为我看到WriteToPort定义:WriteToPort(char* string, int len);所以才改的。不过好像差别不是很大关于CSerialPort的问题,在虚拟串口上调试,看着都是正确的,发送和接收数据相同,应该不是波特率设置的问题;
    物理串口上我还没有验证,等有时间再验证一下,不过感觉应该和虚拟串口差不多(我以前的串口程序都是在虚拟串口上调试的)
    我现在还没弄明白,CSerialPort发送的时候是怎么发的,是一个一个字节发,还是一下子都发出去,这个类是这两天刚弄到的,还不太明白工作原理是什么样的