📄 slave645.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 + -