?? dlt645pri.c
字號:
/*------------------------------------------------------------------*/
/*模塊名稱:DL/T645.c */
/*模塊功能:DL/T 645-1997 多功能電能表通訊規約 */
/*編寫日期:2006年11月 */
/*編寫者: zhangxiaodan */
/*------------------------------------------------------------------*/
#include "includes.h"
#include "dlt645pri.h"
extern struct DBConfig *DBCfgs;
extern struct LinkInfo* ComLink[PORTNUM];
extern struct AppInfo* ComApp[PORTNUM];
extern struct SysPort* ComDb[PORTNUM];
/*------------------------------------------------------------------*/
/*函數名稱:DLT645_1997PriTask() */
/*函數功能:DL/T 645-1997 多功能電能表規約主站方任務 */
/*------------------------------------------------------------------*/
void DLT645_1997PriTask(struct SysPort *Info, struct PortAppInfo* PortCfg)
{
BOOL flag;
INT8U i, err;
INT16U events;
i = Info->PortID - 1;
//初始化
ComLink[i] = (void*) malloc (sizeof (struct LinkInfo));
ComApp[i] = (void*) malloc (sizeof (struct AppInfo));
if ((ComLink[i] == NULL) || (ComApp[i] == NULL))
return ;
else
{
memset (ComLink[i], 0, sizeof (struct LinkInfo));
memset (ComApp[i], 0, sizeof (struct AppInfo));
}
ComDb[i] = Info;
flag = DLT645InitPriLink(i+1, PortCfg);
if (!flag)
{
free (ComLink[i]);
ComDb[i] = NULL;
return ;
}
flag = DLT645InitPriApp(i+1, PortCfg);
if (!flag)
{
free (ComApp[i]);
ComDb[i] = NULL;
return ;
}
DLT645RecMISIData(Info->PortID,FALSE);
OSFlagPost(ComDb[i]->Event, FTXNEXT, OS_FLAG_SET, &err);
while (1)
{
events = OSFlagPend(Info->Event, TIME100MS+FTXNEXT,
OS_FLAG_WAIT_SET_ANY+OS_FLAG_CONSUME, 0, &err);
if (events & FTXNEXT) //繼續處理
{
PRI645SCHEDULE(Info->PortID);
}
//定時處理區(100MS)
if(events & TIME100MS)
{
if(ComApp[i]->AppDevs[ComApp[i]->CurDevNo].FactDelayTime)
{
ComApp[i]->AppDevs[ComApp[i]->CurDevNo].FactDelayTime--;
if(!ComApp[i]->AppDevs[ComApp[i]->CurDevNo].FactDelayTime)
{
if(ComApp[i]->AppDevs[ComApp[i]->CurDevNo].ComError > MAXCOMERROR)
{
if(ReadComYxStatus(i+1))
SetComYxStatus(i+1,FALSE); //寫通訊狀態 分
ComApp[i]->AppDevs[ComApp[i]->CurDevNo].ComError = 0;
ComApp[i]->AppDevs[ComApp[i]->CurDevNo].ReadDataFlag = 0;
OSFlagPost(ComDb[i]->Event, FTXNEXT, OS_FLAG_SET, &err);
}
else
{
ComApp[i]->AppDevs[ComApp[i]->CurDevNo].ComError++;
SendBakData(i+1);//發重復幀
}
}
}
ComApp[i]->AllDataCount++;
if(ComApp[i]->AllDataCount >= ComApp[i]->AllData)
{
SetAllDataFlag(i+1);//置全數據標志
ComApp[i]->AllDataCount = 0;
OSFlagPost(ComDb[i]->Event, FTXNEXT, OS_FLAG_SET, &err);
}
ComApp[i]->SetClockCount++;
if(ComApp[i]->SetClockCount >= ComApp[i]->SetClock)
{
SetClockFlag(i+1);//置對鐘標志
ComApp[i]->SetClockCount = 0;
OSFlagPost(ComDb[i]->Event, FTXNEXT, OS_FLAG_SET, &err);
}
ComApp[i]->DDCounter++;
if(ComApp[i]->DDCounter >= ComApp[i]->Counter)
{
SetKWHFlag(i+1);//置讀電度標志
ComApp[i]->DDCounter = 0;
OSFlagPost(ComDb[i]->Event, FTXNEXT, OS_FLAG_SET, &err);
}
DLT645RecMISIData(Info->PortID,TRUE);
}
}
}
BOOL DLT645InitPriLink(INT8U Port, struct PortAppInfo* PortCfg)
{
INT8U i;
struct PPri645Pad *pPad;
i = Port - 1;
pPad = (struct PPri645Pad*)(PortCfg->pPad);
ComLink[i]->Port = PortCfg->Port;
ComLink[i]->Attr = PortCfg->Attr;
ComLink[i]->RTSONDelay = PortCfg->RTSONDelay;
ComLink[i]->Medium = PortCfg->Medium;
ComLink[i]->Baudrate = PortCfg->Baudrate;
ComLink[i]->MeterCount = pPad->MeterCount;
ComLink[i]->DMeterAddr = (struct MeterAddr*)malloc(sizeof(struct MeterAddr)*ComLink[i]->MeterCount);
if(ComLink[i]->DMeterAddr == NULL)
return FALSE;
ComLink[i]->RxdHead = 0;
ComLink[i]->RxdTail = 0;
ComLink[i]->RxdLength = 0;
return TRUE;
}
BOOL DLT645InitPriApp(INT8U Port, struct PortAppInfo* PortCfg)
{
INT8U i, j, k;
INT16U xuhao;
struct PPri645Pad *pPad;
i = Port - 1;
pPad = (struct PPri645Pad*)(PortCfg->pPad);
if((pPad->CmdControl&BIT0) != FALSE) //對鐘使能
ComApp[i]->EnSetClock = TRUE;
if((pPad->CmdControl&BIT1) != FALSE) //定時召喚全數據
ComApp[i]->TimeAllData = TRUE;
if((pPad->CmdControl&BIT2) != FALSE) //定時召喚電度
ComApp[i]->TimeCounter = TRUE;
if((pPad->CmdControl&BIT3) != FALSE) //廣播對鐘
ComApp[i]->BroadCastClock = TRUE;
if(pPad->AllData < 1)
pPad->AllData = 1;
if(pPad->SetClock < 1440)
pPad->SetClock = 1440;
if(pPad->Counter < 1)
pPad->Counter = 1;
ComApp[i]->AllData = pPad->AllData*60*10;
ComApp[i]->SetClock = pPad->SetClock*60*10;
ComApp[i]->Counter = pPad->Counter*60*10;
ComApp[i]->AllDataCount = 0;
ComApp[i]->SetClockCount = 0;
ComApp[i]->DDCounter = 0;
ComApp[i]->DelayVal = pPad->DelayVal;
ComApp[i]->DevNum = pPad->MeterCount;
ComApp[i]->AppDevs = (struct PDevInfo*)malloc(sizeof(struct PDevInfo)*ComApp[i]->DevNum);
if(ComApp[i]->AppDevs == NULL)
return FALSE;
for(j = 0;j < ComApp[i]->DevNum; j++)
{
ComApp[i]->AppDevs[j].DevID = GetDevIDOfName(pPad->AddrList[j].UserName);
for(k = 0;k < 6;k++)
ComApp[i]->AppDevs[j].Addr[k] = pPad->AddrList[j].ADDR[k];
xuhao = GetActDevNoByDevID(i+1,ComApp[i]->AppDevs[j].DevID);
ComApp[i]->AppDevs[j].MAddr = ComDb[i]->DBCfgs[xuhao].MAddress;
ComApp[i]->AppDevs[j].ComError = 0;
ComApp[i]->AppDevs[j].FactDelayTime = 0;
ComApp[i]->AppDevs[j].DevData.AINum = ComDb[i]->DBCfgs[xuhao].YCNum;
ComApp[i]->AppDevs[j].DevData.BINum = ComDb[i]->DBCfgs[xuhao].YXNum;
ComApp[i]->AppDevs[j].DevData.CounterNum = ComDb[i]->DBCfgs[xuhao].DDNum;
if(ComApp[i]->TimeAllData)
ComApp[i]->AppDevs[j].ReadDataFlag |= ALLDATAFLAG;
if(ComApp[i]->TimeCounter)
{
ComApp[i]->AppDevs[j].ReadDataFlag |= KWHFLAG;
ComApp[i]->KWHStatus = PosiKWHDB;
}
if(ComApp[i]->EnSetClock)
ComApp[i]->AppDevs[j].ReadDataFlag |= CLOCKFLAG;
if(ComApp[i]->BroadCastClock)
ComApp[i]->AppDevs[j].ReadDataFlag |=BROADCAST;
}
return TRUE;
}
//設備調度函數
BOOL DevDispatch(INT8U Port)
{
INT8U i = 0,j = 0;
INT16U DevNo,OldDevNo;
INT32U zxd,zxd1;
i = Port - 1;
DevNo=ComApp[i]->CurDevNo;
OldDevNo = DevNo;
zxd = ComApp[i]->AppDevs[DevNo].ReadDataFlag;
zxd1 = (~(ALLDATAFLAG|KWHFLAG));
while((ComApp[i]->AppDevs[DevNo].ReadDataFlag & (ALLDATAFLAG|KWHFLAG))== 0)
{
DevNo=GetNextActDevNo(Port,DevNo);
j++;
ComApp[i]->KWHStatus = PosiKWHDB;
if(j>=ComApp[i]->DevNum)
return FALSE;
}
ComApp[i]->CurDevNo=DevNo;
return TRUE;
}
/*----------------------------------------------------------------------------------*/
/*函數名稱:GetDevIDByAddr(INT8U Port,INT8U *Addr) */
/*函數功能:通過電能表地址獲得設備的ID號 */
/*----------------------------------------------------------------------------------*/
INT16U GetDevIDByAddr(INT8U Port,INT8U *Addr)
{
INT8U i,j;
i = Port - 1;
for(j = 0;j < ComApp[i]->DevNum;j++)
{
if(!memcmp(ComApp[i]->AppDevs[j].Addr,Addr,6))
return (ComApp[i]->AppDevs[j].DevID);
}
return 0xffff;
}
/*----------------------------------------------------------------------------------*/
/*函數名稱:GetActDevNoByDevID(INT8U Port,INT16U DevID) */
/*函數功能:通過電能表ID號獲得設備的序號 */
/*----------------------------------------------------------------------------------*/
INT16U GetActDevNoByDevID(INT8U Port,INT16U DevID)
{
INT8U i,j;
i = Port - 1;
for(j = 0;j < ComDb[i]->DevNum;j++)
{
if(DevID == ComDb[i]->DBCfgs[j].DevID)
return j;
}
return 0xffff;
}
INT16U GetNextActDevNo(INT8U Port,INT16U DevNo)
{
INT8U i;
i = Port - 1;
return ((DevNo+1)%ComApp[i]->DevNum);
}
/*BCD轉換二進制*/
INT16U BcdToBin(INT16U BCD)
{
short i;
i= (BCD&0xf)+(((BCD>>4)&0xf)*10)+(((BCD>>8)&0xf)*100)+(((BCD>>12)&0x7)*1000);
if(BCD & 0x8000)
return((~i) + 1);
else
return(i);
}
INT32U BcdToBin8(unsigned char *BCD)
{
return(((*BCD)&0xf)+((*(BCD)>>4)*10)+((*(BCD+1)&0xf)*100)+((*(BCD+1)>>4)*1000)
+((*(BCD+2)&0xf)*10000)+((*(BCD+2)>>4)*100000)+((*(BCD+3)&0xf)*1000000)+((*(BCD+3)>>4)*10000000));
}
/*二進制轉換BCD*/
INT16U BinToBcd(INT16U i)
{
return(i%10+((i/10)<<4));
}
/*------------------------------------------------------------------*/
/*函數名稱:DLT645RecMISIData() */
/*函數功能:接收MISI數據 */
/*------------------------------------------------------------------*/
void DLT645RecMISIData(INT8U Port, BOOL Flag)
{
INT16U i, count;
i = Port - 1;
count = Readx((INT8U *)&ComLink[i]->RxdBuf[ComLink[i]->RxdTail], RXBUFLEN, Port);
if (count == 0)
return ;
lseek(Port, count);
if (Flag)
{
ComLink[i]->RxdTail += count;
DLT645SearchFrame(Port);
}
}
void DLT645SearchFrame(INT8U Port)
{
INT8U i, err, tmp, num;
i = Port - 1;
while (ComLink[i]->RxdHead < ComLink[i]->RxdTail)
{
if (ComLink[i]->RxdBuf[ComLink[i]->RxdHead] != STARTCODE68)
{
ComLink[i]->RxdHead++;
continue;
}
//找到后,清除無用的緩沖區報文
if (ComLink[i]->RxdTail > ComLink[i]->RxdHead)
{
memcpy (ComLink[i]->RxdBuf, &ComLink[i]->RxdBuf[ComLink[i]->RxdHead], ComLink[i]->RxdTail - ComLink[i]->RxdHead);
ComLink[i]->RxdTail -= ComLink[i]->RxdHead;
ComLink[i]->RxdHead = 0;
}
ComLink[i]->RxdLength = ComLink[i]->RxdTail - ComLink[i]->RxdHead;
if (ComLink[i]->RxdLength >= 10)
{
if (!DLT645HeadFun68(Port))
{
ComLink[i]->RxdHead++;
continue;
}
else
{
num = ComLink[i]->RxdBuf[ComLink[i]->RxdHead+9];
if (ComLink[i]->RxdLength >= (num + 12)) //報文收全
{
tmp = (INT8U)DLT6465CheckSum((void*)&ComLink[i]->RxdBuf[ComLink[i]->RxdHead], num+10);
if ((ComLink[i]->RxdBuf[num+10] == tmp)
&& (ComLink[i]->RxdBuf[num+11] == ENDCODE))
{
DLT645APP(Port);
if (ComLink[i]->RxdTail >= ComLink[i]->RxdHead)
{
ComLink[i]->RxdTail -= (num + 12);
ComLink[i]->RxdHead = 0;
OSFlagPost(ComDb[i]->Event, FTXNEXT, OS_FLAG_SET, &err);
}
}
else
{
ComLink[i]->RxdHead += (num+12);
if (ComLink[i]->RxdTail > ComLink[i]->RxdHead)
{
ComLink[i]->RxdLength = ComLink[i]->RxdTail - ComLink[i]->RxdHead;
memcpy (ComLink[i]->RxdBuf, &ComLink[i]->RxdBuf[ComLink[i]->RxdHead], ComLink[i]->RxdLength);
ComLink[i]->RxdHead = 0;
ComLink[i]->RxdTail = ComLink[i]->RxdLength;
}
}
}
else
break;
}
}
else
break;
}
}
/*------------------------------------------------------------------*/
/*函數名稱:DLT645HeadFun68() */
/*函數功能:檢測68幀頭正確性 */
/*------------------------------------------------------------------*/
BOOL DLT645HeadFun68(INT8U Port)
{
INT8U i;
i = Port - 1;
if (STARTCODE68 != ComLink[i]->RxdBuf[ComLink[i]->RxdHead])
return (FALSE);
if (STARTCODE68 != ComLink[i]->RxdBuf[ComLink[i]->RxdHead + 7])
return (FALSE);
return (TRUE);
}
INT8U DLT6465CheckSum(INT8U *Buf,INT8U Num)
{
INT8U sum = 0;
while(Num--)
{
sum +=*Buf++ & 0xff;
}
return sum;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -