BOOL CGrayCommDlg::ReadComm(int data_length,BYTE *data)//读程序,读17个字节
{
OVERLAPPED os;//异步信息(重叠操作)结构体对象,
DWORD dwMask/*事件标记*/, dwTrans, dwErrorFlags;
COMSTAT ComStat;
memset(&os, 0, sizeof(OVERLAPPED));
os.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL); //设置非0表示可以重叠操作
int ifreceived=1,/*返回标记,1收到,0未收到*/
MaxWaitTimes=8000,//间*/
nChar=0;//用于标记接收到的字符个数
BYTE m_buf[MAXBLOCK/4];
while(data_length-nChar>0)
{
ClearCommError(m_hCom,&dwErrorFlags,&ComStat);//检索串口,得到ComStat
if(ComStat.cbInQue)//如果读来的字节数大于0
{
unsigned int nCharNeed=data_length-nChar;//还有nCharNeed个字节没收到
unsigned int nReadLength=min(nCharNeed, ComStat.cbInQue);
 WORD length=nReadLength;
                            ReadFile(m_hCom,m_buf,length,&length,&m_os);
            for (unsigned int iread=0;iread<nReadLength;iread++)
{
data[nChar]=m_buf[iread]; 
nChar++;
}
}
dwMask=0;

if(!WaitCommEvent(m_hCom, &dwMask, &os)) // 等待串口SetCommMask事件发生,完成返0
{
            MaxWaitTimes--;
if(GetLastError()==ERROR_IO_PENDING) 
GetOverlappedResult(m_hCom, &os, &dwTrans, 0);//未结束无限等待重叠操作结果
}
if(MaxWaitTimes<0){nChar=data_length; ifreceived=0;}
}
CloseHandle(os.hEvent);
return ifreceived;
}
DWORD CGrayCommDlg::WriteComm(BYTE *buf, DWORD dwLength)//写程序,向下位机写8个字节
{
OVERLAPPED  m_osWrite; // 用于重叠读/写
memset(&m_osWrite, 0, sizeof(OVERLAPPED));
if((m_osWrite.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL))==NULL)return FALSE;// 为重叠写创建事件对象,手工重置,初始化为无信号的
DWORD length=dwLength;
COMSTAT ComStat;
DWORD dwErrorFlags;
ClearCommError(m_hCom,&dwErrorFlags,&ComStat);
if(!WriteFile(m_hCom,buf,length,&length,&m_osWrite))
{
if(GetLastError()==ERROR_IO_PENDING)
{GetOverlappedResult(m_hCom,&m_osWrite,&length,TRUE);}// 等待
else length=0;
}
return length;
}BYTE data[40][17];//全局变量 用来保存接受到的数据BOOL CGrayCommDlg::Receive(unsigned char number)//
{
BYTE com_str[8];
        com_str[0]=number;
com_str[1]=3;
com_str[2]=1;
com_str[3]=0;
com_str[4]=0;
com_str[5]=6;
WORD crc=CRC16_1((BYTE*)com_str, 6);
com_str[6]=(crc%256);//设置CRC字节
com_str[7]=(crc>>8);
WriteComm(com_str, 8);//发送读数据的命令,8个字节
BYTE re_data[17];//建立一个保存接收来的数据的临时数组
if(ReadComm(17,re_data))//如果接收数据成功就把数据读入到data的数组中,接受到17个字节
{ for(i=0;i<17;i++){data[number][i]=re_data[i]}
}void CGrayCommDlg::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default
if (1==nIDEvent)
{
for(int i=1;i<31;i++)
Receive(i);
} }
CDialog::OnTimer(nIDEvent);
}
定时2秒读取30个设备,波特率是38400,为什么运行几秒钟后,回弹出0x00000000 该内存无法引用

解决方案 »

  1.   

    调试,看看call stack窗口最后出现错误的位置,看看内存有没有访问出错了
      

  2.   

    初始化的问题!!建议看这篇文章http://dev.yesky.com/401/2308901.shtml!!
      

  3.   

    实在找不到问题 没有发现数组越界。不过今天发现在ClearCommErro(m_hCom,&dwErrorFlags,&ComStat);后面加上10毫秒左右的延时就没出这个错误了。但还是不明白什么
      

  4.   

    初始化没看到有问题啊。BOOL CGrayCommDlg::OpenConnection()
    {
    if(m_bConnected) return FALSE;//如果已经连接返回
    m_hCom=CreateFile("COM7", GENERIC_READ | GENERIC_WRITE, 0, NULL,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 
    NULL); // 创建具有重叠方式的串口文件句柄
    if(m_hCom==INVALID_HANDLE_VALUE) return FALSE;//如果句柄无效则返回
    SetupComm(m_hCom,MAXBLOCK,MAXBLOCK);//设置串口接收、发送缓冲区大小
    SetCommMask(m_hCom, EV_RXCHAR);//把串口事件标记设置为输入缓冲区接受到一个字符
    COMMTIMEOUTS TimeOuts;//串口等待超时设置
    /* 设置写超时以指定WriteComm成员函数中的GetOverlappedResult函数的等待时间*/
    TimeOuts.WriteTotalTimeoutMultiplier=50;
    TimeOuts.WriteTotalTimeoutConstant=1000;
    TimeOuts.ReadIntervalTimeout=0;
    TimeOuts.ReadTotalTimeoutConstant=0;
    SetCommTimeouts(m_hCom, &TimeOuts);
    if(ConfigConnection()) 
    {
    m_bConnected=TRUE;//对串口控制参数进行设置,如果成功
    PurgeComm(m_hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
    }
    else {CloseHandle(m_hCom); return FALSE;}//如果对串口参数进行用户设置失败,关闭串口
    return TRUE; //连接串口成功
    }
    //
    BOOL CGrayCommDlg::ConfigConnection()//配置串口控制参数
    {
    DCB dcb;
    if(!GetCommState(m_hCom, &dcb)) return FALSE;//把串口原设置读来,不成功返回
    dcb.fBinary=TRUE;
    dcb.BaudRate =38400; // 数据传输速率
    dcb.ByteSize = 8; // 每字节位数
    dcb.fParity = TRUE;
    dcb.Parity=NOPARITY;
    dcb.StopBits=ONESTOPBIT;
    return SetCommState(m_hCom, &dcb);//把dcb设置到串口上
    }
      

  5.   

    Debug下call stack,看函数调用堆栈
      

  6.   

    if(GetLastError()==ERROR_IO_PENDING)  
    GetOverlappedResult(m_hCom, &os, &dwTrans, 0);//未结束无限等待重叠操作结果把最后一个参数设置为 TRUE,直到读取到数据。
    或者超时失败后,不要忘记使用 CancelIo。
      

  7.   

    就是越界了,别想了,楼主到你的接收函数里面提取一下每次接收到的字节数,写到一个文本文件里面看看就明白。如果你发送的是17个字节,每次收到的可能是是1、4、6、8、9、32、22等等个字节,然后这些字节进入你的处理程序就出现越界。前几天我也是这个错误,你的还个给你提示,我的根本提示都没有直接退出程序。
    建议收发两端最好自己定义某种协议。例如,发送 FF EE DD BB为开始一次收发,发送AA 00 66 77作为结束。这样可以保证收的时候明确的知道哪里是开始,哪里是终止。不然收的多了 少了都有可能出现你现在的问题。
      

  8.   

    你读到空指针了,孩纸~用DEBUG模式可以追踪到错误行的~
      

  9.   

    问题已经解决 是这个函数用错了 if(!WaitCommEvent(m_hCom, &dwMask, &os)) 注释掉后一切OK ,非常感觉大家的帮忙,特别是 Tinary3v0和Saleayas