MFC同步串口问题!求大神解答,我实在解决不了了!

r_mc123 2018-10-18 07:19:03
主要问题:1.不能持续收发,只能收发一次。
2.点击按钮第二次的时候会报错。
3.您别告诉我加一个发送按钮。我的上级不让!刚毕业新人谢谢各位大佬!请您帮改改代码!分数全部奉上!

环境: vs2008,多字节。

报错如下:如图

代码:.h


#pragma once
#include <Windows.h>
class CSerial
{
public:
CSerial();
virtual ~CSerial();
BOOL Open(int nPort,int nBaud);
void Close();
BOOL writeToComm(BYTE data[], DWORD dwLength);
CString ReadData();
HANDLE hCom;
protected:
BOOL m_bOpened;
};


.cpp

#include "CSerial.h"
#include "stdafx.h"

CSerial::CSerial()
{
hCom=NULL;
m_bOpened=FALSE;
}

CSerial::~CSerial()
{
Close();
}

BOOL CSerial::Open(int nPort,int nBaud)
{
if (m_bOpened)
{
return TRUE;
}

char szPort[15];
DCB dcb={0};

wsprintf(szPort,"COM%d",nPort);
hCom=CreateFile(szPort,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);

if (hCom==INVALID_HANDLE_VALUE)
{
AfxMessageBox("打开失败");
return FALSE;
}

SetupComm(hCom, 6000, 6000);
dcb.DCBlength=sizeof(DCB);
GetCommState(hCom,&dcb);
dcb.BaudRate=nBaud;
dcb.ByteSize=8;
dcb.Parity=NOPARITY;
BYTE byStopBits=1;
if (byStopBits==1)
dcb.StopBits=ONESTOPBIT;
else if (byStopBits==2)
dcb.StopBits=TWOSTOPBITS;
else
dcb.StopBits=ONE5STOPBITS;

dcb.fDsrSensitivity=FALSE;
dcb.fDtrControl=DTR_CONTROL_ENABLE;
dcb.fOutxDsrFlow=FALSE;

COMMTIMEOUTS TimeOuts;
TimeOuts.ReadIntervalTimeout=MAXDWORD;
TimeOuts.ReadTotalTimeoutMultiplier=0;
TimeOuts.ReadTotalTimeoutConstant=0;
TimeOuts.WriteTotalTimeoutMultiplier=100;
TimeOuts.WriteTotalTimeoutConstant=500;
SetCommTimeouts(hCom,&TimeOuts);

if (!SetCommState(hCom,&dcb))
{
AfxMessageBox("串口设置失败");
return FALSE;
}

PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);


m_bOpened=TRUE;
return m_bOpened;
}


void CSerial::Close()
{

SetCommMask(hCom, 0);
EscapeCommFunction(hCom, CLRDTR);
PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
CloseHandle(hCom);
hCom = NULL;
}


BOOL CSerial::writeToComm(BYTE data[], DWORD dwLength)
{
COMSTAT ComStat;
DWORD dwErrorFlags;
DWORD dxlen = 0;
BOOL bWriteStat;
ClearCommError(hCom, &dwErrorFlags, &ComStat);
bWriteStat=WriteFile(hCom,data,dwLength,&dwLength,NULL);
if(!bWriteStat)
{
AfxMessageBox("写串口失败!");
}

return TRUE;
}

CString CSerial::ReadData()
{

DWORD n;
SetCommMask(hCom, EV_RXCHAR);

if (WaitCommEvent(hCom, &n, NULL))
{
BYTE val[128];
memset(val, 0, 128);
CString str;
DWORD wCount = 128;
BOOL bReadStat;
bReadStat=ReadFile(hCom, val, 128, &wCount, NULL);
str.Format("%s", val);
if(!bReadStat)
{
AfxMessageBox("读串口失败!");
}

PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
return str;
}

}


...全文
425 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
r_mc123 2018-10-20
  • 打赏
  • 举报
回复
各位大神不知道为什么我第二次点击按钮后WaitCommEvent(hCom, &n, NULL);这个函数不触发了请帮我想先办法!!!
r_mc123 2018-10-20
  • 打赏
  • 举报
回复
引用 9 楼 qq_39850605 的回复:
你这个错误是典型的访问空指针或者访问已经被析构的对象导致的。建议你从点第二下按钮开始调试,一步步跟进,看看在哪崩溃的。这种错误调试应该很好找,但是从代码上却很难看出来。
确实第二次点击WaitCommEvent(hCom, &n, NULL);这个函数不触发了不知道为什么求解!!自己百度了很长时间了
赵4老师 2018-10-19
  • 打赏
  • 举报
回复
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止
r_mc123 2018-10-19
  • 打赏
  • 举报
回复
所有的东西都给大佬们贴上了,帮忙修改修改吧吧谢谢了
r_mc123 2018-10-19
  • 打赏
  • 举报
回复
r_mc123 2018-10-19
  • 打赏
  • 举报
回复
zgl7903 2018-10-19
  • 打赏
  • 举报
回复
To get extended error information, call GetLastError.
r_mc123 2018-10-19
  • 打赏
  • 举报
回复

void CChuanKouTxDlg::OnBnClickedButton1()
{
	//serial.Close();
	serial.Open(4,19200);
	ReceiveData();
}

void CChuanKouTxDlg::DcSendDate(void)
{
	CString strsave[2];
	CString str;
	GetDlgItem(IDC_EDIT3)->GetWindowText(str);
	
	for (int i=0; i<2; i++)
	{
		AfxExtractSubString(strsave[i],str,i,' ');
	}

	int s = 0;  
	sscanf(strTempsave[0], "%x", &s); 
	BYTE ss = (BYTE)s;

	BYTE pBuf[7];
	WORD wCRC;
	pBuf[0] = ss;
	pBuf[1] = 0x03;
	pBuf[2] = 0x02;

	s = 0;  
	sscanf(strsave[0], "%x", &s); 
	ss = (BYTE)s;
	pBuf[3] = ss;

	s = 0;  
	sscanf(strsave[1], "%x", &s); 
	ss = (BYTE)s;
	pBuf[4] = ss;

	wCRC = Modbus_CRC16(pBuf,5);
	pBuf[5] = LOBYTE(wCRC);
	pBuf[6] = HIBYTE(wCRC);
	serial.writeToComm(pBuf,7);
}


void CChuanKouTxDlg::AcSendDate(void)
{
	CString strsave[6];
	CString str;
	GetDlgItem(IDC_E1)->GetWindowText(str);
	for (int i=0; i<6; i++)
	{
		AfxExtractSubString(strsave[i],str,i,' ');
	}

	int s = 0;  
	sscanf(strTempsave[0], "%x", &s); 
	BYTE ss = (BYTE)s;

	BYTE pBuf[11];
	WORD wCRC;

	pBuf[0] = ss;
	pBuf[1] = 0x03;
	pBuf[2] = 0x06;
	
	s = 0;  
	sscanf(strsave[0], "%x", &s); 
	ss = (BYTE)s;
	pBuf[3] = ss;

	s = 0;  
	sscanf(strsave[1], "%x", &s); 
	ss = (BYTE)s;
	pBuf[4] = ss;
	
	wCRC = Modbus_CRC16(pBuf,5);
	
	s = 0;  
	sscanf(strsave[2], "%x", &s); 
	ss = (BYTE)s;
	pBuf[5] = ss;

	s = 0;  
	sscanf(strsave[3], "%x", &s); 
	ss = (BYTE)s;
	pBuf[6] = ss;

	s = 0;  
	sscanf(strsave[4], "%x", &s); 
	ss = (BYTE)s;
	pBuf[7] = ss;

	s = 0;  
	sscanf(strsave[5], "%x", &s); 
	ss = (BYTE)s;
	pBuf[8] = ss;

	pBuf[9] = LOBYTE(wCRC);
	pBuf[10] = HIBYTE(wCRC);
	serial.writeToComm(pBuf,11);
}

void CChuanKouTxDlg::ReceiveData(void)
{
	CString val = serial.ReadData();
	UpdateData(TRUE); 
	m_edit1.SetWindowText(val);
	UpdateData(FALSE);
	for (int i=0; i<8; i++)
	{
		AfxExtractSubString(strTempsave[i],val,i,' ');
	}

	if(strTempsave[5] == "0x03")
	{
		if(AcCrc() == FALSE)
		{
			AfxMessageBox("交流电CRC效验失败!");
			serial.Close();
		}
		else
		{
			m_coB.AddString(strTempsave[0]);
			m_coB.SetCurSel(0);
			AcSendDate();
		}
	} 
	else
	{

		if(DcCrc() == FALSE)
		{
			AfxMessageBox("直流CRC效验失败!");
			serial.Close();
		}
		else
		{
			m_co.AddString(strTempsave[0]);
			m_co.SetCurSel(0);
			DcSendDate();
		}
	}
}

BOOL CChuanKouTxDlg::DcCrc(void)
{

	int num = 0;
	sscanf(strTempsave[0], "%x", &num);
	BYTE bt = (BYTE)num;

	BYTE pBuf[8];
	WORD wCRC;
	pBuf[0] = bt;
	pBuf[1] = 0x03;
	pBuf[2] = 0x00;
	pBuf[3] = 0x10;
	pBuf[4] = 0x00;
	pBuf[5] = 0x01;
	wCRC = Modbus_CRC16(pBuf,6);
	pBuf[6] = LOBYTE(wCRC);
	pBuf[7] = HIBYTE(wCRC);
	
	num = 0;
	sscanf(strTempsave[6], "%x", &num);
	BYTE c = (BYTE)num;

	num = 0;
	sscanf(strTempsave[7], "%x", &num);
	BYTE v = (BYTE)num;

	if (pBuf[6] == c && pBuf[7] == v)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

BOOL CChuanKouTxDlg::AcCrc(void)
{
	int num = 0;
	sscanf(strTempsave[0], "%x", &num);
	BYTE bt = (BYTE)num;

	BYTE pBuf[8];
	WORD wCRC;
	pBuf[0] = bt;
	pBuf[1] = 0x03;
	pBuf[2] = 0x00;
	pBuf[3] = 0x10;
	pBuf[4] = 0x00;
	pBuf[5] = 0x03;
	wCRC = Modbus_CRC16(pBuf,6);
	pBuf[6] = LOBYTE(wCRC);
	pBuf[7] = HIBYTE(wCRC);

	num = 0;
	sscanf(strTempsave[6], "%x", &num);
	BYTE c = (BYTE)num;

	num = 0;
	sscanf(strTempsave[7], "%x", &num);
	BYTE v = (BYTE)num;

	if (pBuf[6] == c && pBuf[7] == v)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

WORD CChuanKouTxDlg::Modbus_CRC16(BYTE *Buff_addr,WORD len)
{    
	//用于电流表的CRC计算
	//低字节CRC值表
	BYTE  auchCRCLo[] = 
	{
		0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
		0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
		0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
		0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
		0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
		0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
		0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
		0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
		0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
		0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
		0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
		0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
		0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
		0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
		0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
		0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
		0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
		0x40
	};  
	// 高字节CRC值表
	BYTE auchCRCHi[] = 
	{
		0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
		0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
		0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
		0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
		0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
		0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
		0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
		0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
		0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
		0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
		0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
		0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
		0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
		0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
		0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
		0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
		0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
		0x40
	};
	// 函数返回值是无符号短整型CRC值
	// 待进行CRC校验计算的报文
	// 待校验的报文长度

	BYTE uchCRCHi = 0xFF;             // CRC高字节的初始化
	BYTE uchCRCLo = 0xFF;             // CRC低字节的初始化
	WORD uIndex;                          
	while (len--)								
	{
		uIndex = uchCRCLo ^ *Buff_addr++;    
		uchCRCLo = uchCRCHi ^ auchCRCHi[uIndex];
		uchCRCHi = auchCRCLo[uIndex];
	}
	return(uchCRCHi <<8 | uchCRCLo);
}
r_mc123 2018-10-19
  • 打赏
  • 举报
回复
引用 1 楼 qq_39850605 的回复:
找半天,没找到你说的错误呢
这可如何是好啊
@风轻云淡_ 2018-10-19
  • 打赏
  • 举报
回复
你这个错误是典型的访问空指针或者访问已经被析构的对象导致的。建议你从点第二下按钮开始调试,一步步跟进,看看在哪崩溃的。这种错误调试应该很好找,但是从代码上却很难看出来。
@风轻云淡_ 2018-10-18
  • 打赏
  • 举报
回复
找半天,没找到你说的错误呢

24,855

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧