⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plusecomm-cpp

📁 RS485通讯,用于PC机与C51单片机通讯,进行运动控制
💻
📖 第 1 页 / 共 2 页
字号:

#include "Stdafx.h"
#include "common.h"
#include "plusecomm.h"

extern	char			CurPath[256], InitFileName[256];
extern	char			IniFile[];

PLUSE_MOTOR_DEF			PlusePortParam;
int						PluseReadConfigFlag = 0;

void PluseMotorReadConfig( void )
{
	int			i, j;

	char		szbuf[128], entry[256], section[256];
	MODE_DEF	mode;

	if ( PluseReadConfigFlag )
		return;

	if ( !PluseReadConfigFlag )
	{
		memset( (char*)&PlusePortParam, 0, sizeof(PLUSE_MOTOR_DEF) );	
		PluseReadConfigFlag = 1;
	}

	GetCurrentDirectory( 200, CurPath );
	sprintf( InitFileName, "%s\\%s", CurPath, IniFile );

	GetPrivateProfileString( "PLUSE端口设置", "起始设备号", "", szbuf, 20, InitFileName );
	StringCut( (char*)szbuf );
	if ( strlen(szbuf) == 0 )
	{
		MessageBox ( NULL, "PLUSE变频起始设备号未设置,缺省为 0x01 !!!", "提示信息...", MB_OK | MB_ICONQUESTION );
		strcpy( szbuf, "1" );
	}
	PlusePortParam.StartDevNo = atoi( szbuf );

	GetPrivateProfileString( "PLUSE端口设置", "设备数量", "", szbuf, 20, InitFileName );
	StringCut( (char*)szbuf );
	if ( strlen(szbuf) == 0 )
	{
		MessageBox ( NULL, "PLUSE变频设备数量未设置,缺省为 0x01 !!!", "提示信息...", MB_OK | MB_ICONQUESTION );
		strcpy( szbuf, "1" );
	}
	PlusePortParam.DevNum = atoi( szbuf );

	GetPrivateProfileString( "PLUSE端口设置", "通讯模式", "", szbuf, 20, InitFileName );
    StringCut( szbuf );
	if ( strlen(szbuf) == 0 )
	{
		MessageBox ( NULL, "PLUSE通讯方式未设置,缺省为 9600,n,8,1 !!!", "提示信息...", MB_OK | MB_ICONQUESTION );
		strcpy( szbuf, "9600,n,8,1" );
	}
	GetCommMode( &mode, szbuf );
	PlusePortParam.Mode.Baud = mode.Baud;
	PlusePortParam.Mode.CommBit = mode.CommBit;
	PlusePortParam.Mode.Parity = mode.Parity;
	PlusePortParam.Mode.Stop = mode.Stop;
	
	PlusePortParam.SendTimeConst = 1000000/PlusePortParam.Mode.Baud/MAIN_TIMER_CONST + 2;

	GetPrivateProfileString( "PLUSE端口设置", "通讯端口", "", szbuf, 20, InitFileName );
	StringCut( (char*)szbuf );
	if ( strlen(szbuf) == 0 )
	{
		MessageBox ( NULL, "PLUSE计算机串口号未设置,缺省为 'COM2' !!!", "提示信息...", MB_OK | MB_ICONQUESTION );
		strcpy( szbuf, "2" );
	}
	PlusePortParam.CommNo = atoi( szbuf );

	for( i = 0; i < PlusePortParam.DevNum; i++ )
	{
		sprintf( entry, "PLUSE设备%d", i + 1 );
		for( j = 0; j < MAX_PLUSE_MOTOR_NUM; j++ )
		{
			sprintf( section, "方向求反%d", j + 1 );
			PlusePortParam.Motor[i][j].DirCpl = GetPrivateProfileInt( entry, section, 0, InitFileName );

			sprintf( section, "双向使能%d", j + 1 );
			PlusePortParam.Motor[i][j].DdirEnable = GetPrivateProfileInt( entry, section, 0, InitFileName );

			sprintf( section, "最低频率%d", j + 1 );	
			PlusePortParam.Motor[i][j].LowestRate = GetPrivateProfileInt( entry, section, 0, InitFileName );
		}
	}
}

//***************************************************************
//*						  初始化 PC 串口端口					*	
//***************************************************************
void PluseMotorInitCommPort( void )
{
	char			szbuf[256];
	COMMTIMEOUTS	timeouts;
	DCB				dcb;
	
	PluseMotorReadConfig( );

	if ( PlusePortParam.InitOk )
		return;

	sprintf( szbuf, "COM%d", PlusePortParam.CommNo );
				
	PlusePortParam.CommId = CreateFile( 
							(char*)szbuf, 
							GENERIC_READ | GENERIC_WRITE, 
							0, 
							NULL,
							OPEN_EXISTING, 
							FILE_FLAG_OVERLAPPED, 
							NULL );

	if ( PlusePortParam.CommId == (HANDLE)(0xffffffff) )
		return;
	
	PlusePortParam.Overlapped.Offset = 0;
	PlusePortParam.Overlapped.OffsetHigh = 0;
	PlusePortParam.Overlapped.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
				
	if ( GetCommState( PlusePortParam.CommId, &dcb ) == FALSE )		
		return;
				
	dcb.BaudRate = PlusePortParam.Mode.Baud;
	dcb.ByteSize = PlusePortParam.Mode.CommBit;
	dcb.StopBits = PlusePortParam.Mode.Stop;
	dcb.Parity = PlusePortParam.Mode.Parity;
	
	if ( SetCommState( PlusePortParam.CommId, &dcb ) == FALSE )
		return;
				
	if ( SetupComm( PlusePortParam.CommId, MAX_BUF_SIZE, MAX_BUF_SIZE ) == FALSE )
		return;
				
	timeouts.ReadIntervalTimeout = -1;
	timeouts.ReadTotalTimeoutConstant = 0;
	timeouts.ReadTotalTimeoutMultiplier = 0;
	timeouts.WriteTotalTimeoutConstant = 0;
	timeouts.WriteTotalTimeoutMultiplier = 0;
	SetCommTimeouts( PlusePortParam.CommId, &timeouts );
	
	PlusePortParam.InitOk = TRUE;
}

int PluseMotorReadCommPort( char *buf, int len )
{
    DWORD		rdlen;
	int			retval;

	PluseMotorInitCommPort( );

	if ( PlusePortParam.InitOk == FALSE )
		return 0;

	retval = ReadFile( PlusePortParam.CommId, 
						buf, 
						len, 
						&rdlen, 
						&PlusePortParam.Overlapped 
						);

	if ( retval == TRUE )
		return rdlen;

	return 0;
}

int PluseMotorWriteCommPort( char *buf, int len )
{
    DWORD		wrlen;
	
	PluseMotorInitCommPort( );

	if ( PlusePortParam.InitOk == 0 )
		return 0;

	WriteFile( PlusePortParam.CommId, 
				buf, 
				len, 
				&wrlen, 
				&PlusePortParam.Overlapped );
	
	return wrlen;
}

void PluseMotorDataProcess( void )
{
	int		i, idx;
	u_char	devidx, motoridx, cmd;

	PlusePortParam.SendCmdFlag = 0;
	PlusePortParam.SendTimeCnt = 0;

	devidx = PluseMotorCalCheckSum( PlusePortParam.RecvBuf.MsgData, PlusePortParam.RecvBuf.MsgCnt - 3 );
	motoridx = (HexCharToInt( PlusePortParam.RecvBuf.MsgData[PlusePortParam.RecvBuf.MsgCnt-3] ) << 4)
			+ HexCharToInt( PlusePortParam.RecvBuf.MsgData[PlusePortParam.RecvBuf.MsgCnt-2] );

	if ( devidx != motoridx )
		return;

	devidx = (HexCharToInt( PlusePortParam.RecvBuf.MsgData[1] ) << 4) + HexCharToInt( PlusePortParam.RecvBuf.MsgData[2] ) - 1;
	motoridx = HexCharToInt( PlusePortParam.RecvBuf.MsgData[3] )  - 1;

	cmd = (HexCharToInt( PlusePortParam.RecvBuf.MsgData[5] ) << 4) + HexCharToInt( PlusePortParam.RecvBuf.MsgData[6] );

	switch( PlusePortParam.RecvBuf.MsgData[4] )
	{
		case 'R':
		case 'r':
			switch( cmd )
			{
				case PLUSE_READ_MOTOR_STATUS:
					if ( PlusePortParam.RecvBuf.MsgData[0] == ACK_CHAR )
					{
						PlusePortParam.Motor[devidx][motoridx].CurCtrl = 
							(HexCharToInt( PlusePortParam.RecvBuf.MsgData[7] ) << 4)
							| HexCharToInt( PlusePortParam.RecvBuf.MsgData[8] );

						PlusePortParam.Motor[devidx][motoridx].CurPos = 
							(HexCharToInt( PlusePortParam.RecvBuf.MsgData[9] ) << 28)
							| (HexCharToInt( PlusePortParam.RecvBuf.MsgData[10] ) << 24)
							| (HexCharToInt( PlusePortParam.RecvBuf.MsgData[11] ) << 20)
							| (HexCharToInt( PlusePortParam.RecvBuf.MsgData[12] ) << 16)
							| (HexCharToInt( PlusePortParam.RecvBuf.MsgData[13] ) << 12)
							| (HexCharToInt( PlusePortParam.RecvBuf.MsgData[14] ) << 8)
							| (HexCharToInt( PlusePortParam.RecvBuf.MsgData[15] ) << 4)
							| HexCharToInt( PlusePortParam.RecvBuf.MsgData[16] );

						if ( HexCharToInt( PlusePortParam.RecvBuf.MsgData[9] ) > 7 )
							PlusePortParam.Motor[devidx][motoridx].CurPos |= 0xff000000;
					}
					else
					{
						PlusePortParam.LastCmdAckFlag = NO_ACK_CHAR;
					}
					break;

				case PLUSE_READ_ALL_MOTOR_STATUS:
					if ( PlusePortParam.RecvBuf.MsgData[0] == ACK_CHAR )
					{
						PlusePortParam.LastCmdAckFlag = ACK_CHAR;

						idx = 7;
						for( i = 0; i < MAX_PLUSE_MOTOR_NUM; i++, idx += 10 )
						{
							PlusePortParam.Motor[devidx][i].CurCtrl = 
								(HexCharToInt( PlusePortParam.RecvBuf.MsgData[idx] ) << 4)
								| HexCharToInt( PlusePortParam.RecvBuf.MsgData[idx+1] );

							PlusePortParam.Motor[devidx][i].CurPos = 
								(HexCharToInt( PlusePortParam.RecvBuf.MsgData[idx+2] ) << 28)
								| (HexCharToInt( PlusePortParam.RecvBuf.MsgData[idx+3] ) << 24)
								| (HexCharToInt( PlusePortParam.RecvBuf.MsgData[idx+4] ) << 20)
								| (HexCharToInt( PlusePortParam.RecvBuf.MsgData[idx+5] ) << 16)
								| (HexCharToInt( PlusePortParam.RecvBuf.MsgData[idx+6] ) << 12)
								| (HexCharToInt( PlusePortParam.RecvBuf.MsgData[idx+7] ) << 8)
								| (HexCharToInt( PlusePortParam.RecvBuf.MsgData[idx+8] ) << 4)
								| HexCharToInt( PlusePortParam.RecvBuf.MsgData[idx+9] );
						}
					}
					else
					{
						PlusePortParam.LastCmdAckFlag = NO_ACK_CHAR;
					}
					break;
			}
			break;

		case 'W':
		case 'w':
			if ( PlusePortParam.RecvBuf.MsgData[0] == ACK_CHAR )
			{
				PlusePortParam.LastCmdAckFlag = ACK_CHAR;
			}
			else
			{
				PlusePortParam.LastCmdAckFlag = NO_ACK_CHAR;
			}
			break;
	}
}

//***************************************************************
//*    				 读 PC 机端口 LGBus 数据					*
//***************************************************************
void PluseMotorReadCommData( void )
{
    int  		len, plen;
    u_char		c, buf[2048];

	len = PluseMotorReadCommPort( (char*)buf, 2000 );
	if ( len <= 0 )
		return;

	for ( plen = 0; plen < len; plen++ )
    {
		c = buf[plen];

		switch( PlusePortParam.RevStatus )
		{
			case 0:        //Search sync Char
				PlusePortParam.RecvBuf.MsgData[0] = c;
				
				if ( (c == ACK_CHAR) || (c == NO_ACK_CHAR) )
				{
					PlusePortParam.RevStatus = 1;
					PlusePortParam.RecvBuf.MsgCnt = 1;
				}
				else
				{
					PlusePortParam.RevStatus = 0;
					PlusePortParam.RecvBuf.MsgCnt = 0;
				}
				break;

			case 1:     //  receive real msg body
				PlusePortParam.RecvBuf.MsgData[PlusePortParam.RecvBuf.MsgCnt] = c;
				PlusePortParam.RecvBuf.MsgCnt++;

				if ( c == END_CHAR )
				{
					PluseMotorDataProcess( );

					PlusePortParam.SendCmdFlag = 0;
					PlusePortParam.RevStatus = 0;
					break;
				}

				if ( (c == ACK_CHAR) || (c == NO_ACK_CHAR) )
				{
					PlusePortParam.RevStatus = 0;
					break;
				}
				break;

			default:
				PlusePortParam.RevStatus = 0;
				break;
        }
    }
}

u_char PluseMotorCalCheckSum( u_char *buf, int len )
{
	int		i;
	u_char	sum;

	sum = 0;
	for ( i = 0; i < len; i++ )
	{
		sum += buf[i];
	}

	return sum;
}

void PluseMotorMakeReadStatus( int devidx, int motoridx, int cmd )
{
	int		sum, idx;
	char	szbuf[256];

	if ( (devidx >= PlusePortParam.DevNum) || (motoridx < 0) || (motoridx >= MAX_PLUSE_MOTOR_NUM) )
		return;

	idx = 0;

	szbuf[idx++] = START_CHAR;
		
	// 板地址
	szbuf[idx++] = DecToHexChar( ((PlusePortParam.StartDevNo + devidx) >> 4) & 0x0f );
	szbuf[idx++] = DecToHexChar( (PlusePortParam.StartDevNo + devidx) & 0x0f );
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -