程序思路:
用一个数组p_LCD一直去读取串口的数据!用一个数据校验函数Check_DataFrame_JF去p_LCD中读取数据放到ReceiveBuf并且把ReceiveBuf读取的数据从p_LCD清除
    const  int JF_MAX_FRAME_LEN=MAX_BUF_LEN-100;
static unsigned char p_LCD[MAX_BUF_LEN];
static int  Len; {   unsigned char ch=0;
    int  HaveData;
    HaveData=0;
    unsigned char ch1;
    for(;;) {                rs232.Read_From_Port();
                HaveData=rs232.GetOneByteFromCycleBuf(ch1);//rs232de 端口读数据函数
ch=ch1; if(HaveData==0) break;
if(HaveData!=0) {
p_LCD[Len++]=ch;//读取缓存数据
if(Len>JF_MAX_FRAME_LEN ) Len=0;
}
    } }
int Return_Data_Len;
int InputDataLen=0;
InputDataLen=Len;
        Return_Data_Len=Check_DataFrame_JF(p_LCD, ReceiveBuf, InputDataLen );//数据校验函数
        if(Return_Data_Len>0) {
;
//ProcessReceiveData(Return_Data_Len,ReceiveBuf);
}
Len=InputDataLen;
return Return_Data_Len;
Check_DataFrame_JF函数代码://Check_DataFrame_JF循环的从p_LCD中读取处理数据
功能是找出符合条件的数据并存储到ReceiveBuf中释放该数据占用的p_LCD空间..
int Check_DataFrame_JF(unsigned char * InputBuf, unsigned char * OutputBuf, int &InputBufLen,int model)
{
static unsigned char TempBuf[MAX_BUF_LEN];
        int OneFrameDataLen=-1;
if(model==1){//////////主程序用的CDT校验
bool crc_flag=true;
int i,Start_Pos=-1,End_Pos=-1;
for(i=0;i<InputBufLen;i++){//////////读取接收缓冲区
if((i+6)<InputBufLen && (InputBufLen-i-6>=0)){
if(InputBuf[i]==0xeb && InputBuf[i+1]==0x90 && InputBuf[i+2]==0xeb &&
InputBuf[i+3]==0x90 && InputBuf[i+4]==0xeb && InputBuf[i+5]==0x90 &&
InputBuf[i+6]==0x71 && InputBuf[i+7]==0xf4)Start_Pos=i;
}///////if 
if(Start_Pos>=0){
int real_len=-1;
if((i+8)<InputBufLen && (InputBufLen-i-8)>=0)real_len=(InputBuf[8]+1)*6;
unsigned char Crc_result=0;
for(int k=0;k<real_len;k+=6){
Crc_result=crc_array[InputBuf[i+6+k]^0x00];
Crc_result=crc_array[Crc_result]^InputBuf[i+7+k];
Crc_result=crc_array[Crc_result]^InputBuf[i+8+k];
Crc_result=crc_array[Crc_result]^InputBuf[i+9+k];
Crc_result=crc_array[Crc_result]^InputBuf[i+10+k];
Crc_result=crc_array[Crc_result]^0xff;
if(Crc_result==InputBuf[i+11+k]){
crc_flag=crc_flag&true;
}
else{
crc_flag=crc_flag&false;
// goto AA;
}
}///for k
if(crc_flag) {
                                End_Pos=i+6+real_len;
                                memcpy(OutputBuf, &InputBuf[Start_Pos], End_Pos - Start_Pos + 1 );
                                OneFrameDataLen= End_Pos - Start_Pos + 1; // remove head ,crc, tail 4 byte
                                static int count;
                                count++;
                                unsigned char *p=InputBuf;
                               }
                     else {
                                 End_Pos=i+6+real_len;
                                   OneFrameDataLen=0;
                                        }
 
}//////////if(Star_Pos>=0)
if(End_Pos>0) {  // remove one frame data
                                       memcpy(TempBuf     , &InputBuf[End_Pos+1]  ,  InputBufLen-End_Pos -1 );
                                       memcpy(&InputBuf[0], TempBuf               ,  InputBufLen-End_Pos -1 );
                                        InputBufLen=InputBufLen-End_Pos-1;
                                        break;
                                }
}//for i
}//if 1 
return OneFrameDataLen;
}
问题如下:我是通过定时器工作的,开始时一切正常当p_LCD[Len++]被取空或者p_LCD[Len++]=被填满重新开始时会报两个内存不能写错误!
错误一:"0x00412acf"指令引用的"0x004bb000"内存不能"written",
错误二:"0x7c938fea"指令引用的"0x00000010"内存不能"written",
在线等待请各位大侠帮帮忙!!

解决方案 »

  1.   

    补充MAX_BUF_LEN=1024*5
    给rs232.GetOneByteFromCycleBuf分配的内存为:1024*10
    我的内存大小为:512+128;
      

  2.   

    经你一类好用,我一直用这个!
    // Serial.h#ifndef __SERIAL_H__
    #define __SERIAL_H__#define FC_DTRDSR       0x01
    #define FC_RTSCTS       0x02
    #define FC_XONXOFF      0x04
    #define ASCII_BEL       0x07
    #define ASCII_BS        0x08
    #define ASCII_LF        0x0A
    #define ASCII_CR        0x0D
    #define ASCII_XON       0x11
    #define ASCII_XOFF      0x13class CSerial
    {public:
    CSerial();
    ~CSerial(); BOOL Open( int nPort = 2, int nBaud = 9600 );
    BOOL Close( void ); int ReadData( void *, int );
    int SendData( const char *, int );
    int ReadDataWaiting( void ); BOOL IsOpened( void ){ return( m_bOpened ); } BOOL AsciiToHex(CString szAscii,unsigned char &HexResult);
    BOOL WriteCommByte( unsigned char );
    protected:
    // BOOL WriteCommByte( unsigned char ); HANDLE m_hIDComDev;
    OVERLAPPED m_OverlappedRead, m_OverlappedWrite;
    BOOL m_bOpened;};#endif// Serial.cpp#include "stdafx.h"
    #include "Serial.h"CSerial::CSerial()
    { memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
      memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
    m_hIDComDev = NULL;
    m_bOpened = FALSE;
    }CSerial::~CSerial()
    { Close();}BOOL CSerial::Open( int nPort, int nBaud )
    { if( m_bOpened ) return( TRUE ); char szPort[15];
    char szComParams[50];
    DCB dcb; wsprintf( szPort, "COM%d", nPort );
    m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
    if( m_hIDComDev == NULL ) return( FALSE ); memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
      memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) ); COMMTIMEOUTS CommTimeOuts;
    CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
    CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
    CommTimeOuts.ReadTotalTimeoutConstant = 0;
    CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
    CommTimeOuts.WriteTotalTimeoutConstant = 5000;
    SetCommTimeouts( m_hIDComDev, &CommTimeOuts ); wsprintf( szComParams, "COM%d:%d,n,8,1", nPort, nBaud ); m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
    m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); dcb.DCBlength = sizeof( DCB );
    GetCommState( m_hIDComDev, &dcb );
    dcb.BaudRate = nBaud;
    dcb.ByteSize = 8;
    unsigned char ucSet;
    ucSet = (unsigned char) ( ( FC_RTSCTS & FC_DTRDSR ) != 0 );
    ucSet = (unsigned char) ( ( FC_RTSCTS & FC_RTSCTS ) != 0 );
    ucSet = (unsigned char) ( ( FC_RTSCTS & FC_XONXOFF ) != 0 );
    if( !SetCommState( m_hIDComDev, &dcb ) ||
    !SetupComm( m_hIDComDev, 10000, 10000 ) ||
    m_OverlappedRead.hEvent == NULL ||
    m_OverlappedWrite.hEvent == NULL ){
    DWORD dwError = GetLastError();
    if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
    if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
    CloseHandle( m_hIDComDev );
    return( FALSE );
    } m_bOpened = TRUE; return( m_bOpened );}BOOL CSerial::Close( void )
    { if( !m_bOpened || m_hIDComDev == NULL ) return( TRUE ); if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
    if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
    CloseHandle( m_hIDComDev );
    m_bOpened = FALSE;
    m_hIDComDev = NULL; return( TRUE );}BOOL CSerial::WriteCommByte( unsigned char ucByte )
    {
    BOOL bWriteStat;
    DWORD dwBytesWritten; bWriteStat = WriteFile( m_hIDComDev, (LPSTR) &ucByte, 1, &dwBytesWritten, &m_OverlappedWrite );
    if( !bWriteStat && ( GetLastError() == ERROR_IO_PENDING ) )
    {
    if( WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 ) )
    dwBytesWritten = 0;
    else
    {
    GetOverlappedResult( m_hIDComDev, &m_OverlappedWrite, &dwBytesWritten, FALSE );
    m_OverlappedWrite.Offset += dwBytesWritten;
    }
    } return( TRUE );}int CSerial::SendData( const char *buffer, int size )
    { if( !m_bOpened || m_hIDComDev == NULL ) return( 0 ); DWORD dwBytesWritten = 0;
    int i;
    for( i=0; i<size; i++ )
    {
    WriteCommByte( buffer[i] );
    dwBytesWritten++;
    } return( (int) dwBytesWritten );}
    int CSerial::ReadDataWaiting( void )
    { if( !m_bOpened || m_hIDComDev == NULL ) return( 0 ); DWORD dwErrorFlags;
    COMSTAT ComStat; ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat ); return( (int) ComStat.cbInQue );}int CSerial::ReadData( void *buffer, int limit )
    { if( !m_bOpened || m_hIDComDev == NULL ) return( 0 ); BOOL bReadStatus;
    DWORD dwBytesRead, dwErrorFlags;
    COMSTAT ComStat; ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
    if( !ComStat.cbInQue ) return( 0 ); dwBytesRead = (DWORD) ComStat.cbInQue;
    if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit; bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
    if( !bReadStatus ){
    if( GetLastError() == ERROR_IO_PENDING ){
    WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
    return( (int) dwBytesRead );
    }
    return( 0 );
    } return( (int) dwBytesRead );}
    /*************************************************
    //功能:将小写两位字符转16制数转成功返回TRUE //
    //并将结果存于HexResult中,转换失败返回FALSE //
    *************************************************/
    BOOL CSerial::AsciiToHex(CString szAscii,unsigned char &HexResult)
    {
    // unsigned char HexResult=0; for(int i=0;i<szAscii.GetLength();i++)
    {
    if(2>szAscii.GetLength())
    {//是一个字符时按以下处理
    switch(szAscii.GetAt(i))
    {
    case 'a':
    {
    HexResult=10;
    break;
    }
    case 'b':
    {
    HexResult=11;
    break;
    }
    case 'c':
    {
    HexResult=12;
    break;
    }
    case 'd':
    {
    HexResult=13;
    break;
    }
    case 'e':
    {
    HexResult=14;
    break;
    }
    case 'f':
    {
    HexResult=15;
    break;
    }
    default:
    {
    if('0'<=szAscii.GetAt(i)&&szAscii.GetAt(i)<='9')
    {
    HexResult=(szAscii.GetAt(i)-0x30);
    }
    else
    {
    AfxMessageBox("当前数不是十六进制数!",IDOK|MB_ICONWARNING);
    return FALSE;
    break;
    }
    }//end of default
    }//end of switch
    }//end of if 
    else//是按两个字符时处理
    {
    switch(szAscii.GetAt(i))
    {
    case 'a':
    {
    if(0==i)
    HexResult=10*16;
    else if(1==i)
    HexResult =HexResult + 10;
    break;
    }
    case 'b':
    {
    if(0==i)
    HexResult=11*16;
    else if(1==i)
    HexResult =HexResult + 11;
    break;
    }
    case 'c':
    {
    if(0==i)
    HexResult=12*16;
    else if(1==i)
    HexResult =HexResult + 12;
    break;
    }
    case 'd':
    {
    if(0==i)
    HexResult=13*16;
    else if(1==i)
    HexResult =HexResult + 13;
    break;
    }
    case 'e':
    {
    if(0==i)
    HexResult=14*16;
    else if(1==i)
    HexResult =HexResult + 14;
    break;
    }
    case 'f':
    {
    if(0==i)
    HexResult=15*16;
    else if(1==i)
    HexResult =HexResult + 15;
    break;
    }
    default:
    {
    if('0'<=szAscii.GetAt(i)&&szAscii.GetAt(i)<='9')
    {
    if(0==i)
    {
    HexResult=(szAscii.GetAt(i)-0x30)*16;
    }
    else if(1==i)
    {
    HexResult =(HexResult + (szAscii.GetAt(i)-0x30) );
    }
    }
    else
    {
    AfxMessageBox("当前数不是十六进制数!",IDOK|MB_ICONWARNING);
    return FALSE;
    break;
    }
    }//end of default
    }//end of switch
    }//end of else
    }//end of for
    return TRUE;
    }
      

  3.   

    debug下断点看具体运行情况。
      

  4.   

    程序太大真是其中的一小部分
    而且是通讯模块而且是通讯模块起来太复杂了吧?我用TRACE看了一下的问题是:Unhandle exception in my.exe : 0x0000005 : Access Violation
      

  5.   

    To: myzcp123
    谢谢!!有空用你提供的试试不过现在时间紧还是想用老的通讯类!
      

  6.   

    Unhandle exception 时看一下调用堆栈.