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

📄 serialcomm.cpp

📁 VC++ 串口通信的dll. MsgQue 和SerialBase中重要的数据结构和通信函数,其可以完全复用. SerialComm是具体的应用, 大家实际应用中要做相应的修改. 代码注释详细,书写规
💻 CPP
字号:
// SerialComm.cpp : Defines the entry point for the DLL application.
//
//History
//*Data          *Name      *comments.
//2008-Feb-03    Rock Li    Initialization

#include "stdafx.h"
#include "SerialComm.h"
#include "SerialBase.h"


//Added the command by Rock Li
// New Key word. It should be well-arranged in the future.
#define  CMD_DOWN_SEND_UNACK_DATA_TO_TN 0xD0   //  SendUnackDataToTN

#define  CMD_DOWN_SEND_ACK_DATA_TO_TN   0xD1   //  SendAckDataToTN
#define  CMD_ACK_SEND_ACK_DATA_TO_TN    0xD2   //  SendAckDataToTN


#define  CMD_DOWN_DOWNLOAD_UID		0xEF   //DownloadUID
#define  CMD_DOWN_RUN_NET_BUILD		0xEE   //RunNetBuild

#define  MAX_UID 8   //DownloadUID

//End of adding by Rock Li

#define  UNIQUE_NODE_ID_LEN    6
#define  MAX_ROUTE_NODE_NUM    8     //最多路由中继数
#define  MAX_CONF_NODE_NUM	   6     //记录相邻的已配置节点数

#define __LITTLE_ENDIAN_BITFIELD 1

#pragma pack(1)
typedef struct  
{
	unsigned char comand;  //CMD_DOWN_0 EF
	unsigned char trans_length;
	unsigned char reserved;               //sometimes it is used for check sum
}UartHead;  //head of Uart
#pragma pack()

typedef struct  
{
	UartHead head;
	unsigned char UID[MAX_UID][6];
}UartDownloadUID;  //上位机对下层传的UID download命令格式。

typedef unsigned char Byte;
typedef unsigned char uint8;
typedef unsigned char Bits;

typedef struct
{
    uint8    subnetID;
#if defined(__LITTLE_ENDIAN_BITFIELD)
	Bits     node      : 7;
    Bits               : 1;
#elif defined(__BIG_ENDIAN_BITFIELD)
    Bits              : 1;
	Bits     node      : 7;
#else
	////#error  "ENDIAN_BITFIELD not specified"
#endif
} SubnetNodeAddr;   //记录一个节点的逻辑地址

typedef  struct 
{
#if defined(__LITTLE_ENDIAN_BITFIELD)
	Bits   routeNodeNum 	 :4;				//保存路由节点的个数
	Bits   pollFailTimes     :2;                //状态查询失败的次数
    Bits   unused            :2;
#elif defined(__BIG_ENDIAN_BITFIELD)
    Bits   unused            :2;
	Bits   pollFailTimes     :2;                //状态查询失败的次数
	Bits   routeNodeNum 	 :4;				//保存路由节点的个数
#else
		////#error	"ENDIAN_BITFIELD not specified"
#endif
    SubnetNodeAddr   routeNode[MAX_ROUTE_NODE_NUM];     //路由节点的逻辑地址
    Byte   statusWord;
}DownlinkPath;  //CC到终端的下行路径

typedef struct
{
  SubnetNodeAddr   subnetNodeAddr;     //分配给终端的逻辑地址
  #if defined(__LITTLE_ENDIAN_BITFIELD)   
   Bits     valueofQ        :4;  //通信质量
   Bits     level           :4;  //该节点到CC的路由级数
 #elif defined(__BIG_ENDIAN_BITFIELD)  
   Bits     level           :4;  //该节点到CC的路由级数
   Bits     valueofQ        :4;  //通信质量
 #else
   #error  "ENDIAN_BITFIELD not specified"
 #endif  
   uint8   generalQ;             //记录广义的Q值,该值只记录,不保存,在掉电后再上电初始化的时候,重新由Q和路由级数计算
}ConfiguredNode;

typedef struct
{
   ConfiguredNode     configuredList[MAX_CONF_NODE_NUM];     //已配置邻居节点列表
   unsigned char               confNodeCnt;           //已配置邻居节点列表中节点的个数
//   UnConfiguredNode   unconfiguredList[MAX_UNCONF_NODE_NUM]; //未配置邻居节点列表
//   unsigned char               unconfNodeCnt;       //未配置邻居节点列表中节点的个数
}NeighborNode;

typedef struct
{
#if defined(__LITTLE_ENDIAN_BITFIELD)
	Bits   ifConfigued       :1;                //是否被配置
	Bits   bValid            :1;                //表示该节点的信息是否有效
	Bits   currPath          :1;                //0:表示主路径;1:表示辅路径
	Bits   needConfig        :1;                // 1:表示需要配置,0:不需要配置
	Bits   pathNum           :2;                //表示路径条数 
	
	Bits   unused            :2;
#elif defined(__BIG_ENDIAN_BITFIELD)
	Bits   unused			 :2;

	Bits   pathNum			 :2;				//表示路径条数 
	Bits   needConfig        :1;                // 1:表示需要配置,0:不需要配置
	Bits   currPath          :1;                //0:表示主路径;1:表示辅路径
	Bits   bValid            :1;                //表示该节点的信息是否有效
	Bits   ifConfigued       :1;                //是否被配置
#else
			////#error	"ENDIAN_BITFIELD not specified"
#endif
	DownlinkPath      priPath;                                //主路径
	DownlinkPath      secPath;                                //辅路径
	Byte              uniqueNodeId[UNIQUE_NODE_ID_LEN];       //终端节点地址
	SubnetNodeAddr    subnetNodeAddr;                         //分配给终端的逻辑地址
	NeighborNode      neiborList;                             //相邻节点信息
	uint8             Qvalue;                                 //记录Q值
	SubnetNodeAddr	  priUplinkNode;						   //上行的主节点
	SubnetNodeAddr	  secUplinkNode;						   //上行的第二个节点
	uint8             CCQvalue;
}NodeInfo;                                      //一条路由通道信息

#define  MAX_TERMINAL_NUM	   36	 //最多终端数
#define  MAX_ROUTE_NODE_NUM    8     //最多路由中继数
#define  MAX_CONF_NODE_NUM	   6     //记录相邻的已配置节点数
#define  MAX_UNCONF_NODE_NUM   4     //记录相邻的未配置节点数
#define  UNIQUE_NODE_ID_LEN    6

#define  cmd_1 0xFF  // 组网期间的信息上传
#define  cmd_2 0xFE  // 组网完成后的信息上传
#define  cmd_3 0xFD  // 收到数据包的信息
#define  cmd_4 0xFC  // UID下载是否成功的CC回执给上位机的信息
#define  cmd_5 0xFB	 // (手动组网模式)集中器返回握手信息,表示可以接收命令
#define  cmd_6 0xFA	 //(手动组网模式)集中器APP返回下载UID校验正确的信息


#define  CMD_DOWN_0 0xEF   //Load UID ,命令
#define  CMD_DOWN_1 0xEE   //组网命令
#define  CMD_DOWN_2 0xEC   //开灯关灯命令
#define  CMD_DOWN_3	0xEA   //(自动组网模式中)自动轮询和按键轮询的命令,,CC图标的右键菜单下达

#define  CMD_DOWN_4 0xE9   //设置轮询方式
#define  CMD_DOWN_5 0xE8   //增加一个节点,输入的都是uid
#define  CMD_DOWN_6 0xE7   //删除一个节点,根据节点的uid删除一个节点

#define  CMD_DOWN_7 0xE6   //查询一个或多个节点,输入的都是uid
#define  CMD_DOWN_8 0xE5   //配置一个或多个节点,输入的都是uid
#define  CMD_DOWN_9 0xE4   //(手动组网模式中)上位机下达命令前的握手命令,察看集中器是否忙

#define  CMD_DOWN_10 0xE3  //手动自动都用的设置组网参数
#define  CMD_DOWN_11 0xE2  //指定路由信息的命令

#define  CMD_DOWN_15 0xDE  //手动组网,利用某点查结点间的Q值,节点到节点的Q值查询

#define  PC_REV_CMD_LEN 0x4E


//Added by Rock 2008-Feb-01

#define MAX_NUM_TN 100;

typedef struct  
{
	unsigned char   uniqueNodeId[UNIQUE_NODE_ID_LEN];
}UID;

typedef struct tag_TN_Info
{
	unsigned char nodecnt;		//225
    UID uid;					//UID information
	SubnetNodeAddr la;			//Logic Address
}TN_Info;

static TN_Info   m_tnInfo[100]; 

static unsigned char m_AckCmd[] = {
										cmd_1,
										cmd_2,
										cmd_3,
										cmd_4,
										cmd_5,
										cmd_6,
										CMD_ACK_SEND_ACK_DATA_TO_TN
										}; //the name should be adjusted


BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}



SERIALCOMM_API bool DownloadUID(unsigned char *p_TermUID, int NumOfNodes)
{
//CMD_DOWN_DOWNLOAD_UID
//To make the check sum
	if(NumOfNodes>MAX_UID)
	{
		return false;
	}

	UartDownloadUID package;
	memset((void*)&package,0,sizeof(package));

	unsigned char checkSum = 0;
	for(int i=0; i < NumOfNodes * 6; i++)
	{
		checkSum += p_TermUID[i];
	}

	package.head.comand = CMD_DOWN_DOWNLOAD_UID;
	package.head.trans_length = NumOfNodes * 6 + 3;
	package.head.reserved = checkSum;

	memcpy(package.UID,p_TermUID,NumOfNodes*6);

//	bool WriteComm(unsigned char* lpBuffer, const DWORD dwBytesToWrite)
	if(!WriteComm((unsigned char*)&package, package.head.trans_length))
	{
		return false;
	}

	pMsgQue ackMsg = NULL;

	bool bRet = GetAckMessage(&ackMsg);

	if(bRet)
	{
		if(ackMsg != NULL)
		{
			UartHead* headMsg = (UartHead*)ackMsg;
			if(headMsg->comand == cmd_4)  //this command should be adjusted.
			{
				if(headMsg->reserved == 0x01)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else
			{
				//it is impossible; program error
				return false;
			}
		}
	}
	else
	{
		return false;
	}

	return true;
}

SERIALCOMM_API bool DllInit(HANDLE hProExit, char szComName[])
{
//bool Init(HANDLE hProExit, unsigned char uploadCmd[],char szComName[])

	return Init(hProExit, m_AckCmd,szComName);

//	return true;
}

SERIALCOMM_API bool DllCleanUp()
{
	return CleanUp();
}

SERIALCOMM_API bool RunNetBuild(void)
{
//CMD_DOWN_DOWNLOAD_UID
//To make the check sum

	UartHead rxDataHead;
	memset((void*)&rxDataHead, 0, sizeof(rxDataHead));

	rxDataHead.comand = CMD_DOWN_RUN_NET_BUILD;
	rxDataHead.trans_length = 0x3;
	rxDataHead.reserved = 0x00;

	if(!WriteComm((unsigned char*)&rxDataHead,rxDataHead.trans_length))
	{
		return false;
	}

/*
	pMsgQue ackMsg = NULL;

	bool bRet = GetAckMessage(&ackMsg);

	if(bRet)
	{
		if(ackMsg != NULL)
		{
			UartHead* headMsg = (UartHead*)ackMsg;
			if(headMsg->comand == cmd_4)  //this command should be adjusted.
			{
				if(headMsg->reserved == 0x01)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else
			{
				//it is impossible; program error
				return false;
			}
		}
	}
	else
	{
		return false;
	}
*/
	return true;
}

//Purpose: To sends unacknowledged data to a TN. 
//Arguments description:
//p_TermUID --> An pointer to UID of one terminal Node
//p_InDataBuf -->An pointer to the Data to be sent
//inDataLen -->the length of the data
//return value: true for success and false for failure  
//comments: inDataLen should be less than 200. Or it will return false.

SERIALCOMM_API bool SendUnAckDataToTN ( unsigned char *p_TermUID,
										unsigned char *p_InDataBuf,
										unsigned char  inDataLen)
{
#pragma pack(1)
	struct tag_UserData
	{
		UartHead head;
		unsigned char data[256];
	} txUserData;
#pragma pack()

	if(inDataLen >200)
	{
		return false;
	}

	memset((void*)&txUserData, 0, sizeof(txUserData));

	txUserData.head.comand = CMD_DOWN_SEND_UNACK_DATA_TO_TN;
	txUserData.head.trans_length = 0x3 + 6 + inDataLen;
	txUserData.head.reserved = 0x00;

	memcpy(&txUserData.data, p_TermUID ,6);

	memcpy( (char*)&txUserData.data + 6, (void*)p_InDataBuf ,inDataLen);

//we should use sizeof function to check the length of data, To ensure that align =1
	if(!WriteComm((unsigned char*)&txUserData,txUserData.head.trans_length))
	{
		return false;
	}

	return true;
}

//Purpose: To sends unacknowledged data to a TN. 
//Arguments description:
//p_TermUID --> An pointer to UID of one terminal Node
//p_InDataBuf -->An pointer to the Data to be sent
//inDataLen -->the length of the data
//return value: true for success and false for failure  
//comments: inDataLen should be less than 200. Or it will return false.

SERIALCOMM_API bool SendAckDataToTN ( unsigned char    *p_TermUID,
										unsigned char  *p_InDataBuf,
										unsigned char  inDataLen,
										unsigned char  *p_RespData,
										unsigned char  *p_RespDataLen)
{
#pragma pack(1)
	struct tag_UserData
	{
		UartHead head;
		unsigned char data[256];
	} txUserData;
#pragma pack()

	if(inDataLen >200)
	{
		return false;
	}

	memset((void*)&txUserData, 0, sizeof(txUserData));

	txUserData.head.comand = CMD_DOWN_SEND_ACK_DATA_TO_TN;
	txUserData.head.trans_length = 0x3 + 6 + inDataLen;
	txUserData.head.reserved = 0x00;

	memcpy(&txUserData.data, p_TermUID ,6);
	memcpy( (char*)&txUserData.data + 6, p_InDataBuf ,inDataLen);

//we should use sizeof function to check the length of data, To ensure that align =1

	if(!WriteComm((unsigned char*)&txUserData,txUserData.head.trans_length))
	{
		return false;
	}

	pMsgQue ackMsg = NULL;

	bool bRet = GetAckMessage(&ackMsg);

	if(bRet)
	{
		if(ackMsg != NULL)
		{
			UartHead* headMsg = (UartHead*)ackMsg;
			if(headMsg->comand == CMD_ACK_SEND_ACK_DATA_TO_TN)  //this command should be adjusted.
			{
				if(headMsg->reserved == 0x01)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else
			{
				//it is impossible; program error
				return false;
			}
		}
	}
	else
	{
		return false;
	}

	return true;

}

⌨️ 快捷键说明

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