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

📄 slave645.c

📁 电力行业的DL645采集程序,嵌入式Linux环境
💻 C
字号:

/*********************************************************
版权所有:银骏科技
版本号	:1.00
文件名	:Slave645.c
创建日期:07/03
创建者:
功能说明:	读写国标子表程序头文件
*********************************************************/
#define ARM_SLAVE645_GLOBALS
#include "cfg_ISlave.h"
int fd;
int DL645_SendFrame(int fd , INT8U *addr, INT8U ctrlCode, INT8U *pbuf, INT16U bufsize);
int DL645_RecvFrame(int fd, INT8U *pbuf, INT16U bufsize, INT16U * psize);
void DL645_RxStateInit(void);


int  Init645Com(INT8U uart,int nSpeed,int nDataBits,char Parity,int nStopBit)
{
		fd = 	OpenCom(uart);
		if(fd > 0)
		{
				SetComOpt(fd,nSpeed,nDataBits,Parity,nStopBit);
				return  fd;
		}
		else
		{
			printf("Open Com Error\n");
			return E_COM_OTHER;
		}
}
/*****************************************************************************************
函数名称:      void DL645_RxStateInit(void)
功能说明:      645协议电表接收数据包状态初始化
输入参数:      
输出参数:      
其它说明:      
*****************************************************************************************/
void DL645_RxStateInit(void)
{ 
	gSlave645RxState.state = SLAVE645_RX_NULL;
	gSlave645RxState.offset = 0;
	gSlave645RxState.size = 1;
}
/*****************************************************************************************
函数名称:      INT8U Slave645ReadFrame(INT8U port, INT8U *pbuf, INT16U bufsize, INT16U * psize)
功能说明:      读645协议帧
输入参数:      
输出参数:      
其它说明:      
*****************************************************************************************/

int DL645_RecvFrame(int fd, INT8U *pbuf, INT16U bufsize, INT16U * psize)
{
	INT8U retvalue;
	INT16U size;

	*psize = 0;
	
	while(1)
	{
		retvalue = SlaveRecvFrame(fd, gSlave645RxData + gSlave645RxState.offset, gSlave645RxState.size, &size,SLAVE645_WAIT_OUT);
		if(retvalue == SUCCESS)
		{
			if(size > 0)
			{
				gSlave645RxState.offset += size;
				gSlave645RxState.size -= size;
				if(gSlave645RxState.size == 0)
				{
					switch(gSlave645RxState.state)
					{
						case SLAVE645_RX_NULL:
							if(gSlave645RxData[gSlave645RxState.offset - 1] == METER_FRAME_START_CH)
							{
								gSlave645RxState.state = SLAVE645_RX_HEADER;
								gSlave645RxState.size = METER_ADDR_LEN + 2;
							}
							else
							{
								DL645_RxStateInit();
							}

							break;
						case SLAVE645_RX_HEADER:
							if(gSlave645RxData[gSlave645RxState.offset-2] == METER_FRAME_START_CH)
							{
								gSlave645RxState.state = SLAVE645_RX_DATALEN;
								gSlave645RxState.size = 1;
							}
							else
							{
								DL645_RxStateInit();
							}
							break;
						case SLAVE645_RX_DATALEN:
							gSlave645RxState.state = SLAVE645_RX_DATA;
							gSlave645RxState.size = gSlave645RxData[gSlave645RxState.offset - 1];
							gSlave645RxState.size += 2;
							break;
						case SLAVE645_RX_DATA:
							if(gSlave645RxState.offset > bufsize)
							{INT8U
								DL645_RxStateInit();
								return E_ALLOT_MEMORY;
							}
							else
							{
								memcpy(pbuf, gSlave645RxData, gSlave645RxState.offset);
								*psize = gSlave645RxState.offset;
								DL645_RxStateInit();
								return SUCCESS;
							}
							
							break;
					}
				}
			}
			else
			{
				break;
			}
		}
		else
		{
			break;
		}
	}
	return retvalue;
}

/*****************************************************************************************
函数名称:      INT8U DL645_SendFrame(int fd, INT8U *addr, INT8U ctrlCode, INT8U *pbuf, INT16U bufsize)
功能说明:      发送645协议帧
输入参数:      
输出参数:      
其它说明:      
*****************************************************************************************/
int DL645_SendFrame(int fd , INT8U *addr, INT8U ctrlCode, INT8U *pbuf, INT16U bufsize)
{
	INT8U *ptr, i;
	INT16U size;
	INT8U sendbuf[METER_FRAME_SIZE];

	if(bufsize > METER_FRAME_DATA_SIZE)
	{
		return E_ALLOT_MEMORY;
	}
	size = 0;
	ptr = sendbuf;
	*(ptr++) = 0xfe;
	*(ptr++) = 0xfe;	
	*(ptr++) = METER_FRAME_START_CH;	
	size += 3;
	
	memcpy(ptr, addr, METER_ADDR_LEN);
	ptr += METER_ADDR_LEN;
	size += METER_ADDR_LEN;
	
	*(ptr++) = METER_FRAME_START_CH;
	*(ptr++) = ctrlCode;
	*(ptr++) = bufsize;
	size += 3;
	
	memcpy(ptr, pbuf, bufsize);
	for(i = 0; i < bufsize; i++)
		*(ptr++) += 0x33;
	size += bufsize;
	
	*(ptr++) = mCheckSumByte(sendbuf + 2, bufsize + 10);
	*ptr = METER_FRAME_END_CH;
	size += 2;
#if SLAVE_DEBUG_EN > 0	
	printf("645 send frame\n");
	mPrintfHex(sendbuf,size);
#endif
	return SlaveSendFrame(fd, sendbuf, size,SLAVE645_SEND_OUT);
}

/*****************************************************************************************
函数名称:      INT8U Slave645Data(INT16U mp, INT16U dataId, INT8U *pbuf, INT16U bufsize, INT8U *psize, MeterAddrType *pSlaveAddr)
功能说明:      读DL/T645协议子表数据
输入参数:      
输出参数:      
其它说明:      
*****************************************************************************************/

int Slave645ReadData(MpComProperty *mpProperty, INT16U dataId, INT8U *pbuf, INT16U bufsize, INT16U *psize)
{	
	INT16U framesize;
	INT16U size;
	MeterFrameType *pMeterFrame;
	MeterAddrType *addr;	
	INT8U buff[METER_FRAME_SIZE];
	INT8U retvalue; 
	long dtime;
	INT32U timeout;
	INT16U rddataid;
	time_t curTime;
	time_t startTime;
	
#if SLAVE_DEBUG_EN > 0	  
	printf("\n Slave645ReadData dataid =%02x\naddr \n",dataId);
#endif		

	memset(buff,0,METER_FRAME_SIZE);

	retvalue = DL645_SendFrame(fd, mpProperty->addr, METER_CTRL_READ_DATA, (INT8U *)&dataId, 2);
	if(retvalue != SUCCESS)
	{
		return retvalue;
	}
	
	DL645_RxStateInit();
	addr = (MeterAddrType *)mpProperty->addr;
	timeout = SLAVE645_WAIT_OUT*2;

	time(&startTime);
	time(&curTime);
	//difftime 返回精确到秒
	while((dtime = difftime(curTime,startTime)) <  timeout) 
	{
		time(&curTime);
		retvalue = DL645_RecvFrame(fd, buff, METER_FRAME_SIZE, &framesize);

#if SLAVE_DEBUG_EN > 0	  
		printf("\n Slave645ReadFrame retvalue=%d framesize=%d\n",retvalue,framesize);
		mPrintfHex(buff, framesize);
#endif		
		if(retvalue == SUCCESS)
		{	
			if(framesize > 0)
			{
				if(MeterFilterFrame(buff) == TRUE)
				{
#if SLAVE_DEBUG_EN > 0	  
						printf("MeterFilterFrame TRUE\n");
						mPrintfHex(buff,framesize);
#endif						
						if(pMeterFrame->ctrl_un.code.err == 0)
					 {
						printf("pMeterFrame->ctrl_un.code.err == 0)\n");
						pMeterFrame = (MeterFrameType *)buff;
						rddataid = pMeterFrame->data[1];
						rddataid <<= 8;
						rddataid += pMeterFrame->data[0];
					#if SLAVE_DEBUG_EN > 0	  
										printf("\n MeterFilterFrame OK\n");
					#endif						
						if(pMeterFrame->addr.m_ma == addr->m_ma && rddataid == dataId)
						{
	#if SLAVE_DEBUG_EN > 0	  
							printf("\n rddataid OK\n");
	#endif						
							size = pMeterFrame->datalen - 2;
							if(((dataId&0x000f)==0x000f) && (*(pMeterFrame->data+pMeterFrame->datalen-1)==0xaa))
							{
								size--;	
							}
							if(size > bufsize)
							{
								size = bufsize;
							}
							memcpy(pbuf, (INT8U *)(pMeterFrame->data + 2), size);
							*psize = size;
#if SLAVE_DEBUG_EN > 0	  
							printf("\n Slave645ReadData OK\n");
							mPrintfHex(pbuf, size);
#endif						
							return SUCCESS;
						}
					 }
					else
					{
#if SLAVE_DEBUG_EN > 0	  
							printf("\npMeterFrame->ctrl_un.code.err!=0\n");							
#endif	
						*psize = 0;
						return FAILED;
					}
				}
			}//if framesize > 0
		}//		if(retvalue == SUCCESS)
		else
		{
			return retvalue;
		}
		sleep(1);
	}//while

	return FAILED;
}

/*****************************************************************************************
函数名称:      INT8U Slave645RecvData(INT16U mp, INT16U dataId, INT8U *pbuf, INT16U bufsize, INT8U *pPassword, MeterAddrType *pSlaveAddr)
功能说明:      写DL/T645协议子表数据
输入参数:      
输出参数:      
其它说明:      
*****************************************************************************************/

int Slave645WriteData(MpComProperty *mpProperty, INT16U dataId, INT8U *pbuf, INT16U bufsize)
{
	INT16U framesize;
	MeterFrameType *pMeterFrame;
	MeterAddrType *addr;
	INT8U buff[METER_FRAME_SIZE];
	INT8U retvalue;
	INT32U timeout;
	long dtime;
	time_t curTime;
	time_t startTime;


	memcpy(buff, (INT8U *)&dataId, 2);
	memcpy(buff + 2, mpProperty->pass, METER_PASSWORD_LEN);
	memcpy(buff + 2 + METER_PASSWORD_LEN, pbuf, bufsize);

	retvalue = DL645_SendFrame(fd, mpProperty->addr, METER_CTRL_WRITE_DATA, buff, bufsize + METER_PASSWORD_LEN + 2);
	if(retvalue != SUCCESS)
	{
		return retvalue;
	}
	
	DL645_RxStateInit();

	timeout = SLAVE645_WAIT_OUT*10;
	addr = (MeterAddrType *)mpProperty->addr;


	//difftime 返回精确到秒
	while((dtime = difftime(curTime,startTime)) <  timeout) 
	{
		time(&curTime);
		retvalue = DL645_RecvFrame(fd, buff, METER_FRAME_SIZE, &framesize);
		if(retvalue == SUCCESS)
		{	
			if(framesize > 0)
			{
			
				if(MeterFilterFrame(buff) == TRUE)
				{
					pMeterFrame = (MeterFrameType *)buff;

					if(pMeterFrame->addr.m_ma == addr->m_ma)
					{
						if(pMeterFrame->ctrl_un.code.err == 0 && pMeterFrame->ctrl_un.code.function == METER_CTRL_WRITE_DATA)
						{						
							return SUCCESS;
						}
						else if(pMeterFrame->ctrl_un.code.err == 1)
						{
							return E_COM_RECV;
						}
						else
						{
							return E_COM_RECV;
						}
					}				
				}
			}
		}
		else
		{
			return E_COM_RECV;
		}
	}
	return FAILED;
}

⌨️ 快捷键说明

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