程序思路:
用一个数组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",
在线等待请各位大侠帮帮忙!!
用一个数组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",
在线等待请各位大侠帮帮忙!!
解决方案 »
- Vsiual C++ 2008 express edition 是不是不能建MFC工程
- editor box 输入的行数,列数随意 怎样存入一个二维数组之中
- 创建非模式对话框碰到的一个莫名其妙的错误
- 救命?????n简单!!!
- SetBkColor和SetBkMode,Brush什么关系?
- 关于子类化窗口
- WindowsNT下如何通过修改注册表来修改系统的IP地址.
- C++中指针的深度拷贝问题?
- 我想vc中使用ShellExecute,如何引用shellapi.pas,是要下载吗
- MD5算法.......
- error C3861: “GdipCreateBitmapFromGdiDib”: 即使使用参数相关的查找,也未找到标识符,这个问题怎么解决?
- 100分求助, CDialogBar中的按钮能实现多语言吗?
给rs232.GetOneByteFromCycleBuf分配的内存为:1024*10
我的内存大小为:512+128;
// 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;
}
而且是通讯模块而且是通讯模块起来太复杂了吧?我用TRACE看了一下的问题是:Unhandle exception in my.exe : 0x0000005 : Access Violation
谢谢!!有空用你提供的试试不过现在时间紧还是想用老的通讯类!