封裝

#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"windows.h"
#include"time.h"
#include"math.h"

#define BOXNUM 24  //櫃子個數

struct BoxState{
	int connect;
	int isOpen;
	int hasGoods;
};

//global variables
BoxState bs[BOXNUM+1];
BoxState newbs[BOXNUM+1];
int expiredSecs = 1;
float tep = 0.00;


//funcation declation
int initMb(HANDLE& mbCom);
int initAll(HANDLE& mbCom);
void setCom(HANDLE& hCom);
void ctMbPort(HANDLE& hCom,unsigned char *sendBuffer,unsigned char *exceptedBuffer,unsigned char *recvBuffer);
void sendMsg(HANDLE& hCom,unsigned char *sendBuffer);
int receive(HANDLE& hCom,unsigned char *recvBuffer);
int receiveMsg(HANDLE& hCom,unsigned char *recvBuffer);
int ifTemp(HANDLE& hCom);
void getAllStatus(HANDLE &hCom, BoxState newbs[BOXNUM]);
int ifBoxStatus(HANDLE &hCom,int &numChanged);
void readBoxStatus(HANDLE &hCom, unsigned char *result);


//local debug funcation 
void printRecv(char * s,unsigned char *b);


void printRecv(char * s,unsigned char *b){
	printf("%s received: ",s);
	for(int i=0;i<7;i++)
		printf("%02x ",b[i]);
	printf("\n");
}


void setCom(HANDLE& hCom)
{
	SetupComm(hCom,100,100); 

	COMMTIMEOUTS TimeOuts;
	
	TimeOuts.ReadIntervalTimeout=MAXDWORD;
	TimeOuts.ReadTotalTimeoutMultiplier=0;
	TimeOuts.ReadTotalTimeoutConstant=0;
	TimeOuts.WriteTotalTimeoutMultiplier=100;
	TimeOuts.WriteTotalTimeoutConstant=500;
	SetCommTimeouts(hCom,&TimeOuts); 
	DCB dcb;
	GetCommState(hCom,&dcb);
	dcb.BaudRate=9600; 
	dcb.ByteSize=8; 
	dcb.Parity=NOPARITY; 
	dcb.StopBits=ONE5STOPBITS; 
	SetCommState(hCom,&dcb);
	PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
}


void sendMsg(HANDLE& hCom,unsigned char lpOutBuffer[7]) 
{
	// TODO: Add your control notification handler code here
	OVERLAPPED m_osWrite;
	memset(&m_osWrite,0,sizeof(OVERLAPPED));
	m_osWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

	DWORD dwBytesWrite=7;
	COMSTAT ComStat;
	DWORD dwErrorFlags;
	BOOL bWriteStat;
	ClearCommError(hCom,&dwErrorFlags,&ComStat);
	bWriteStat=WriteFile(hCom,lpOutBuffer,
		dwBytesWrite,& dwBytesWrite,&m_osWrite);

	if(!bWriteStat)
	{
		if(GetLastError()==ERROR_IO_PENDING)
		{
			WaitForSingleObject(m_osWrite.hEvent,1000);
		}
	}

}

int receive(HANDLE& hCom,unsigned char str[100]) 
{
	// TODO: Add your control notification handler code here
	OVERLAPPED m_osRead;
	memset(&m_osRead,0,sizeof(OVERLAPPED));
	m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

	COMSTAT ComStat;
	DWORD dwErrorFlags;

	//memset(str,'\0',100);
	DWORD dwBytesRead=100;
	BOOL bReadStat;

	ClearCommError(hCom,&dwErrorFlags,&ComStat);
	dwBytesRead=min(dwBytesRead, (DWORD)ComStat.cbInQue);
	bReadStat=ReadFile(hCom,str,
		dwBytesRead,&dwBytesRead,&m_osRead);

	if(!bReadStat)
	{
		if(GetLastError()==ERROR_IO_PENDING)
			//GetLastError()函數返回ERROR_IO_PENDING,表明串口正在進行讀操作
		{
			WaitForSingleObject(m_osRead.hEvent,2000);
			//使用WaitForSingleObject函數等待,直到讀操作完成或延時已達到2秒鐘
			//當串口讀操作進行完畢後,m_osRead的hEvent事件會變爲有信號
		}
	}
	PurgeComm(hCom, PURGE_TXABORT|
		PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);

	return (strlen((const char *)str));
}

int receiveMsg(HANDLE& hCom,unsigned char *recvBuffer)
{
	memset(recvBuffer,'\0',100);
	clock_t start, finish;
	double duration;
	int len =0;
	start = clock();
	while(true)
	{
		len = receive(hCom,recvBuffer);
		if(len>0)
			break;
		finish = clock();
		duration = (double)(finish - start) / CLOCKS_PER_SEC;
		if(duration>expiredSecs)
			break;
	}
	return len;
}


void ctMbPort(HANDLE& hCom,unsigned char sendBuffer[7],unsigned char exceptedBuffer[7],unsigned char recvBuffer[100])
{
	for(int i=0;i<256;i++)
	{
		char comstr[8]="COM";
		char tmp[4];
		sprintf(tmp,"%d",i);
		strcat(comstr,tmp);
		
		hCom=CreateFileA((LPCSTR)comstr,
			GENERIC_READ|GENERIC_WRITE, 
			0, 
			NULL,
			OPEN_EXISTING, 
			FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
			NULL);
		if(hCom!=(HANDLE)-1)
		{
			printf("%s\n",comstr);
			setCom(hCom);	

			sendMsg(hCom,sendBuffer) ;
			
			clock_t start, finish;
			double duration;
			start = clock();
			while(true)
			{
				int len = receive(hCom,recvBuffer);
				if(len>0)
					break;
				finish = clock();
				duration = (double)(finish - start) / CLOCKS_PER_SEC;
				if(duration>expiredSecs)
					break;
			}
			
			//if(!strcmp((const char *)recvBuffer,(const char *)exceptedBuffer))
			if((recvBuffer[0]==exceptedBuffer[0])&&(recvBuffer[6]==exceptedBuffer[6]))
			{
				printf("create main board com port success\n");

				return ;
			}
			CloseHandle(hCom);
		}	
	}
	
}

int initMb(HANDLE& mbCom)
{
	unsigned char sendBuffer[7];
	unsigned char exceptedBuffer[7];
	unsigned char recvBuffer[100];
	memset(sendBuffer,'\0',7);
	memset(exceptedBuffer,'\0',7);
	memset(recvBuffer,'\0',100);

	sendBuffer[0]=0x68;
	sendBuffer[1]=0x00;
	sendBuffer[2]=0xff;
	sendBuffer[3]=0x01;   //lock_init
	sendBuffer[4]=0x00;
	sendBuffer[5]=0x00;
	sendBuffer[6]=0x16;

	exceptedBuffer[0]=0x68;
	exceptedBuffer[6]=0x16;

	recvBuffer[4]=0x00;
	recvBuffer[5]=0x01;

	ctMbPort(mbCom,sendBuffer,exceptedBuffer,recvBuffer);
	if(mbCom==((HANDLE)-1))
		return 0;
		printRecv("initMb",recvBuffer);
	unsigned char low=recvBuffer[4];
	unsigned char high = recvBuffer[5];
	if((low==0x00)&&(high==0x00))
		return 1;
	return 0;
}

int openBox(HANDLE& hCom,int no)
{
	//已經開始開櫃狀態,則不需重新開櫃
	if((no>=0)&&(no<=BOXNUM) && (bs[no].isOpen==1))
		return 1;
	unsigned char sendBuffer[7];
	unsigned char recvBuffer[100];

	sendBuffer[0]=0x68;
	sendBuffer[1]=0x00;
	sendBuffer[2]=0xff&no;
	//printf("%x",sendBuffer[2]);
	sendBuffer[3]=0x02;	//打開櫃子
	sendBuffer[4]=0x00;
	sendBuffer[5]=0x00;
	sendBuffer[6]=0x16;

	sendMsg(hCom,sendBuffer) ;

	int len = receiveMsg(hCom,recvBuffer);

	if(len==0)
		return 0;
	printRecv("readTemp",recvBuffer);
	unsigned char low=recvBuffer[4];
	unsigned char high = recvBuffer[5];
	if((low==0x00)&&(high==0x00))
		return 1;
	return 0;
}


unsigned short int readTemp(HANDLE& hCom )
{	//6800ff0601ee16
	unsigned char sendBuffer[7];
	unsigned char recvBuffer[100];

	sendBuffer[0]=0x68;
	sendBuffer[1]=0x00;
	sendBuffer[2]=0xff;
	sendBuffer[3]=0x06;//獲取溫度
	sendBuffer[4]=0xff;
	sendBuffer[5]=0xff;
	sendBuffer[6]=0x16;

	sendMsg(hCom,sendBuffer);

	int len = receiveMsg(hCom,recvBuffer);

	if(len==0)
		return 0;
	printRecv("readTemp",recvBuffer);
	unsigned char ch[]={recvBuffer[5],recvBuffer[4]};
	unsigned short int temp = 0;
	strncpy((char*)&temp,(const char *)ch,2);
	return temp;
}

int ifTemp(HANDLE& hCom)
{
	float newTep = readTemp(hCom);
	if(abs(newTep - tep)<0.01)
		return 0;
	return 1;
}


void getAllStatus(HANDLE &hCom, BoxState newbs[BOXNUM])
{
	//獲取所有的櫃子狀態
	for(int i=1;i<=BOXNUM;i++)
	{
		unsigned char sendBuffer[7];
		unsigned char recvBuffer[100];

		sendBuffer[0]=0x68;
		sendBuffer[1]=0x00;
		sendBuffer[2]=0xff&i;
		sendBuffer[3]=0x04; //是否開櫃
		sendBuffer[4]=0xff;
		sendBuffer[5]=0xff;
		sendBuffer[6]=0x16;

		//1.檢查是否開櫃。如果收到數據錯誤,則該櫃子連接狀態爲失敗
		sendMsg(hCom,sendBuffer);
		int len = receiveMsg(hCom,recvBuffer);
		if(len == 0)
		{
			newbs[i].connect=0;
			newbs[i].isOpen=0;
			newbs[i].hasGoods=0;
			continue;
		}
		unsigned char high = recvBuffer[5]; //得到高位數據
		if(high==0x00)
			newbs[i].isOpen=1;
		else if(high == 0x01)
			newbs[i].isOpen=0;
		else
		{
			newbs[i].connect=0;
			newbs[i].isOpen=0;
			newbs[i].hasGoods=0;
			continue;
		}

		//2.檢查是否有物品。
		sendBuffer[3]=0x05; //是否有物品

		sendMsg(hCom,sendBuffer);
		len = receiveMsg(hCom,recvBuffer);
		if(len == 0)
		{
			newbs[i].connect=0;
			newbs[i].isOpen=0;
			newbs[i].hasGoods=0;
			continue;
		}
		high = recvBuffer[5]; //得到高位數據
		if(high==0x00)
			newbs[i].hasGoods=0;
		else if(high == 0x01)
			newbs[i].hasGoods=1;
		else
		{
			newbs[i].connect=0;
			newbs[i].isOpen=0;
			newbs[i].hasGoods=0;
			continue;
		}

		//如果以上檢查都正常,則該櫃子連接正常
		newbs[i].connect = 1;
	}
}

int ifBoxStatus(HANDLE &hCom,int &numChanged)
{
	int sum = 0;
	numChanged = -1;
	getAllStatus(hCom,newbs);
	for(int i=0;i<=BOXNUM;i++)
	{
		if((newbs[i].connect==bs[i].connect)&&(newbs[i].isOpen==bs[i].isOpen)&&(bs[i].hasGoods==newbs[i].hasGoods))
			continue;
		else
		{
			sum+=1;
			numChanged = i;
		}
	}
	//更新所有櫃子狀態,bs永遠保存最近的上一次的櫃子狀態
	//if(sum>0)
	//{
	//	for(int i=0;i<=BOXNUM;i++)
	//	{
	//		bs[i].connect=newbs[i].connect;
	//		bs[i].isOpen = newbs[i].isOpen;
	//		bs[i].hasGoods = newbs[i].hasGoods;
	//	}
	//}
	return sum;
}

void readBoxStatus(HANDLE &hCom, unsigned char *result)
{
	
	int numChanged = -1;
	int total = ifBoxStatus(hCom,numChanged);
	if(0==total)
	{
		result[0]='\0';
	}
	else if(1==total)
	{
		result[0]=0xff00&numChanged;
		result[1]=0x00ff&numChanged;
		result[2]=0xff&newbs[numChanged].connect;
		result[3]=0xff&newbs[numChanged].isOpen;
		result[4]=0xff&newbs[numChanged].hasGoods;
		result[5]='\0';
	}
	else
	{
		int k=0;
		for(int i=0;i<=BOXNUM;i++)
		{
			result[k++]=0xff&newbs[i].connect;
			result[k++]=0xff&newbs[i].isOpen;
			result[k++]=0xff&newbs[i].hasGoods;
		}
		result[k]='\0';
	}
	//更新所有櫃子狀態,bs永遠保存最近的上一次的櫃子狀態
	if(total>0)
	{
		for(int i=0;i<=BOXNUM;i++)
		{
			bs[i].connect=newbs[i].connect;
			bs[i].isOpen = newbs[i].isOpen;
			bs[i].hasGoods = newbs[i].hasGoods;
		}
	}
}

int initAll(HANDLE& mbCom)
{
	int mbR= initMb(mbCom);
	if(mbR==0)
		return 0;
	
	//init temperature
	tep = readTemp(mbCom );
	//init all box STATUS
	getAllStatus(mbCom,bs); 

	return 1;
}


int main()
{
	HANDLE mbCom=NULL;
	int inRst = initAll(mbCom);
	printf("init:%d \n",inRst);

	printf("open box status:%d\n",openBox(mbCom,23));
	printf("read temp:%d\n" ,readTemp(mbCom ));

	printf("ifTemp:%d\n",ifTemp(mbCom));

	if(mbCom!=((HANDLE)-1))
		CloseHandle(mbCom);

}

發佈了97 篇原創文章 · 獲贊 33 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章