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

📄 fbycom.cpp

📁 FBYCOM.dll的源程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
'COPYRIGHT: Foshan Analytical Instrument Factory, All rights reserved.
'This document, which contains confidential material is private and is
'the 'property and copyright of Foshan Analytical Instrument Factory.
'It is not to 'be used other purposes, copied, distributed or transmitted
'in any form or by 'any means without the prior written consent of the company.
'Infringement of 'copyright is a serious civil and criminal offence which can
'result in heavy 'fines and payment of substantial damages.
'================================================================
'1.模块定义
'  模块名称:Serial.cpp
'  模块ID:FBYCom
'  文件名称:Serial.cpp
'  程序员:李文杰
'  日期:2003/11/01
'2.注释
'  项目:FGA4100通讯控制系统
'  操作系统:Windows 98 or Windows 2000
'  软件环境:Vc++ 6.0
'3.修改履历:
*/
// FBYCom.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "FBYCom.h"
#include "Serial.h"
#include "FBY_Com.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define ERROR_CODE					    0xff //无效命令
#define GET_STATUS						0x01 //取状态
#define GET_TEST_DATA					0x02 //取测量值
#define GET_SAFE_DATA					0x03 //取稳态值
#define GET_SPEEDUP_DATA				0x04 //取加速值
#define REVISE							0x05 //请求线性修正
#define CHANGE_TO_TEST_PAGE				0x06 //请求转换到测量屏
#define CHANGE_TO_SAFE_PAGE				0x07 //请求转换到稳态屏
#define CHANGE_TO_SPEEDUP_PAGE			0x08 //请求转换到加速屏
#define BEGIN_STOP_SAFE_TEST			0x09 //请求开始或停止稳态测量
#define SPEEDUP_TOUCH_OFF				0x0b //请求进行一次加速触发(手动方式)
#define CLEAR_SPEEDUP_DATA				0x0c //请求清除加速数据
#define CHANGE_SPEEDUP_MODE				0x0d //请求切换加速方式(手动方式与自动方式间切换)
#define GET_LAST_MAIN_SPEEDUP_DATA		0x0e //请求取最后一次加速主要数据
#define GET_LAST_SPEEDUP_LINE			0x0f //请求取最近一次加速曲线数据



//
//	Note!
//
//		If this DLL is dynamically linked against the MFC
//		DLLs, any functions exported from this DLL which
//		call into MFC must have the AFX_MANAGE_STATE macro
//		added at the very beginning of the function.
//
//		For example:
//
//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
//		{
//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
//			// normal function body here
//		}
//
//		It is very important that this macro appear in each
//		function, prior to any calls into MFC.  This means that
//		it must appear as the first statement within the 
//		function, even before any object variable declarations
//		as their constructors may generate calls into the MFC
//		DLL.
//
//		Please see MFC Technical Notes 33 and 58 for additional
//		details.
//

/////////////////////////////////////////////////////////////////////////////
// CFBYComApp

BEGIN_MESSAGE_MAP(CFBYComApp, CWinApp)
	//{{AFX_MSG_MAP(CFBYComApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFBYComApp construction

CFBYComApp::CFBYComApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}



/////////////////////////////////////////////////////////////////////////////
// The one and only CFBYComApp object

CFBYComApp theApp;

unsigned char SendData[4]; //发送命令缓存
unsigned char ReadData[1007];//接收数据缓存  能够适应最大的数据块

unsigned char SingleMachineCode[3] = { 'f','t','y' }; //单机通讯时加的字节
int ReadNum; //读取的字节数

int fby_ComID;    //端口
int fby_Baud;	   //波特率
int fby_IsOpened;	//串口是否打开
int fby_Address;   //仪器地址
int SingleMachine = 0; //单机多机位  默认为多机通讯

CSerial Serial;
int CalDelayTime(long delaytime);//延时函数
void ClearComData();//清串口函数


BOOL Send()//发送数据函数 在 Read(int read_num) 中被调用//发送的数据保存在全局变量内
{
	int ReceiveNum = 0;

	for(int ll = 0;ll < 5 ;ll++ )
	{
		ClearComData();

		if( SingleMachine == 0 )//多机模式下通讯时
		{
			//
			Serial.Open(fby_ComID,fby_Baud,3); //先把校验位设为,也就是3,发送地址
			Serial.SendData((char *)(&SendData[0]),1);
			
			//
			Serial.Open(fby_ComID,fby_Baud,4); //在把校验位改为space,也就是4,发送命令
			Serial.SendData((char *)(&SendData[1]),3);
		}
		else  //单机模式下通讯
		{
			Serial.Open(fby_ComID,fby_Baud,0);//无奇偶校验
			Serial.SendData((char *)(&SingleMachineCode[0]),3);
			Serial.SendData((char *)(&SendData[0]),4);
		}
		

		CalDelayTime( -1 );
		CalDelayTime( 1 );
		for(;;)
		{
			::Sleep(50);
			ReceiveNum = Serial.ReadDataWaiting();
			if( ReceiveNum > 0 )
			{
				return TRUE;
			}
			if( CalDelayTime( 800 ) > 0 ) 
				break;//应答超时
		}
	}
	if( ll == 5 )
		return FALSE;
	return TRUE;
}

BOOL Read(int read_num)//读取数据函数
{
	int return_num; //具体读取的时候的字节数
	int ReceiveNum; //现在已经在缓存内的数据个数
	int MyDelaytime; //延时时间
	int OldReadNum; //前一次取得的数据字节数 
	int SameDataTimes = 0;//取到同样数据的次数
	BOOL bReadData = FALSE;

	if( !Send() )
		return FALSE;

	::Sleep(150);

	if( read_num == 1007 )//曲线数据使用5000ms延时
	{
		MyDelaytime = 5000 ;
		::Sleep(1200);
	}
	else if( read_num == 37 )//加速数据使用1000ms延时
		MyDelaytime = 1200 ;
	else
		MyDelaytime = 1000 ;//其他使用500ms延时

	CalDelayTime(-1);//计时器复位
	CalDelayTime( MyDelaytime );//开始记时

	for(;;)
	{
		ReceiveNum = Serial.ReadDataWaiting();
		if( ReceiveNum > 0 && ReceiveNum < read_num )//如果是有数据  但是数据还没有达到预期的数量
		{
			//在没有超时的情况下 判断取得的数据是否在增长 ,
			//如果连续2次发现取得的数据都没有增长,则认为数据接收完成
			if( SameDataTimes == 0 )//如果是第一次进入这个判断  则将当前的缓存内的数据字节数记录下来
			{
				OldReadNum = ReceiveNum;
				SameDataTimes ++ ;
			}
			else if( SameDataTimes != 10 )//如果同样字节数没有超过3次
			{
				//当前的字节数和上一次的字节数是否相等
				//如果相等  则将相等次数添加1
				//如果不相等  则将当前的字节数作为前一次数据字节数进行保存
				if( ReceiveNum == OldReadNum )
					SameDataTimes++;
				else
				{
					OldReadNum = ReceiveNum;				
					SameDataTimes = 1;
				}
				continue;
			}
			else if( SameDataTimes == 10 )//如果发现有连续3次读取的缓存内的数据没有变化  
										 //则认为数据已经接收完毕  退出循环
				break;

			if( CalDelayTime( MyDelaytime ) > 0 ) 
				break;//应答超时
		}
		else if( ReceiveNum > 0 && ReceiveNum == read_num )//当前缓存内的数据和目标数据长度相等  退出循环
			break;
	}
	
	return_num = Serial.ReadData((char *)&ReadData,read_num);

	//以下是数据校验
	if( return_num > 0 )//如果读到数据			
	{
		unsigned char temp = 0;
		for( int ss = 1;ss <= return_num - 2 ;ss++ )
			temp += ReadData[ss];

		if( 256 - temp == ReadData[ return_num - 1 ]) 
		{
			ReadNum = return_num;
			return TRUE;
		}
		else
		{
			return_num = 0;
			memset(ReadData,0,1007);
		}
	}
	return FALSE;
}


void ClearComData()//清串口函数
{
	int ReceiveNum=0;
	unsigned char ReturnData;
	
	Serial.ReadDataWaiting(&ReceiveNum);
	
	for(int ii=0;ii<ReceiveNum;ii++)
	{
		Serial.ReadData(&ReturnData,1);
	}
}

int CalDelayTime(long delaytime)//延时函数
{
	static LONGLONG BeginTime;
	static BOOL StartFlag;
	
	LARGE_INTEGER litmp; 
	LONGLONG CulTime; 
	
	double dfFreq; 
	
	long AlreadyDelayTime=0;
	
	if(delaytime<0)
	{
		StartFlag=FALSE;
		return FBY_SUCCESS;	
	}
	else//定时器复位
	{
		if(!StartFlag)//开始记时
		{
			// 获得初始值 
			QueryPerformanceCounter(&litmp); 
			BeginTime = litmp.QuadPart; 
			StartFlag=TRUE;
			return FBY_FAIL;
		}
		else
		{
			// 获得处理器时钟频率 
			QueryPerformanceFrequency(&litmp); 
			dfFreq = (double)litmp.QuadPart; 
			
			// 获得终止值 
			QueryPerformanceCounter(&litmp); 
			CulTime = litmp.QuadPart; 
			
			//计算从开始记时到现在已经过去的时间
			
			AlreadyDelayTime =(long)((double)((CulTime*1.0-BeginTime*1.0)/ (dfFreq*1.0))*1000); //单位为ms
			
			if(AlreadyDelayTime>delaytime)//延时已到
			{
				return AlreadyDelayTime;
			}
			else
			{
				return FBY_FAIL;
			}
		}
	}
}

/*
打开端口
*/
int _stdcall FBY_Open(int iComID/*端口号*/,int iBaud/*波特率*/,int iAddress/*仪器地址*/ )
{
	if(iComID<=0 || iBaud<=0 ) return ERR_REF_ERR; //参数错误
	fby_ComID=iComID;
	fby_Baud=iBaud;
	fby_Address = iAddress;

⌨️ 快捷键说明

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