最近有编写一个Modbus模拟通讯设备,这里记下编写过程中遇到的问题,聊作学习笔记。
编写程序中有用到的两个类:
CAniGIF m_ctrlAniGifFan1;
CSerialPort m_Port;
过程中重写了Cserialport类的writetoport函数
void CSerialPort::WriteToPort(char* string,int n)
{
assert(m_hComm != 0);
memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
// memset(m_szWriteBuffer, 0, n);
// strncpy(m_szWriteBuffer, string, n);
memcpy(m_szWriteBuffer, string, n);
m_nWriteSize=n;
// set event for write
SetEvent(m_hWriteEvent);
}
通过定时5ms来判定接收完一条modbus指令:
LONG Dialog1::OnCommunication(WPARAM ch, LPARAM port)
{
if (m_bTimer==TRUE)//有了m_bTimer,一条modbus指令中只会一次定时5ms
{//m_bTimer要初始化为true
SetTimer(1,5,NULL);//5毫秒
m_bTimer=FALSE;
}
CString str;
str.Format("%02x ",ch);
m_strPortRXData+=str;
return 0;
}
void Dialog1::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if (nIDEvent==1)
{
char data[512];
BYTE rxdata[512];
CString str,strTemp;
unsigned short c1,c2;
int len=Str2Hex(m_strPortRXData,data);
for (LONG k=0;k<len;k++)
{
rxdata[k]=data[k];
}
c1=CRC16(rxdata,len-2);
c2=rxdata[len-1]|(rxdata[len-2]<<8);
if (c1=c2)
{
if (rxdata[0]==0x01)
{
switch(rxdata[1])
{
case 0x10:
{
switch(rxdata[8])
{
case 0x05:
{
//alloff
Even(FALSE);
Odd(FALSE);
}break;
case 0x06:
{
Even(FALSE);