123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918 |
- #include "IEC101.h"
- #include "usart.h"
- #include "timer.h"
- uint8_t flgDIR, flgPRM, flgFCB = 0, flgFCV, flgACD;
- uint8_t LINK_ADDRESS = 0x01; //定义链路地址
- uint8_t ProtocolRxBuffer[64] = {0}; //存储主站发过来的命令
- uint8_t TxBuffer[64] = {0};
- uint8_t TxAppBuffer[64] = {0};
- uint8_t RxControlField = 0; //接收到数据中的控制域
- uint8_t RxDIR, RxPRM, RxFCB, RxFCV, RxFunctionCode;
- uint8_t LastFCB;
- uint8_t TxDIR, TxPRM, TxFCB, TxFCV, TxFunctionCode;
- TimeStructure NowTimeStruct;
- uint16_t LastType;
- uint8_t Info[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //开关量数量 0/1/2 跌落 3跌落状态 4温度状态 5 欠压 6/7/8/9 漏保
- uint8_t InfoTemp[8]; //温度
- uint8_t DataFromGPRSBuffer[128];
- uint8_t moduleMaskEn; // 模块故障MASK
- /*
- ****************************************************************************************************
- * 功能描述:初始化链路层参数
- * 输入参数:
- * 返回参数:
- * 说 明:
- ****************************************************************************************************
- */
- void LinkInit(void) {
- RxDIR = M2S_DIR; //固定值,从站接收到主站的数据时DIR为0,
- RxPRM = 0; //非固定值
- TxPRM = 0; //非固定值
- RxFCB = 0;
- RxFCV = 0;
- TxDIR = S2M_DIR; //固定值从站发出数据时DIR为1
- }
- //此函数用于CheckSum函数之后,即已经判断为有效帧后再校验地址是否正确
- //返回SUCCESS地址正确,返回ERROR地址不正确
- uint8_t CheckLinkAddress(uint8_t* pBuffer) {
- uint16_t LinkAddress = 0;
- if (pBuffer[0] == 0x10) {
- LinkAddress = (uint16_t)pBuffer[2];
- }
- else if (pBuffer[0] == 0x68) {
- LinkAddress = (uint16_t)pBuffer[5];
- }
- else {
- return ERROR; //链路地址不正确
- }
- if (LinkAddress == LINK_ADDRESS) {
- return SUCCESS; //链路地址正确
- }
- else {
- return ERROR; //链路地址不正确
- }
- }
- /*
- ****************************************************************************************************
- * 功能描述:
- * 输入参数:
- * 返回参数:校验和的值
- * 说 明:
- ****************************************************************************************************
- */
- uint8_t GetCheckSum(uint8_t* pBuffer) {
- uint8_t i;
- uint8_t TempSum = 0;
- uint8_t DataLength = 0;
- if (pBuffer[0] == 0x10)
- TempSum = pBuffer[1] + pBuffer[2];
- else if (pBuffer[0] == 0x68) {
- DataLength = pBuffer[1]; //获取可变帧数据长度
- for (i = 0; i < DataLength; i++)
- TempSum += pBuffer[i + 4];
- }
- else
- TempSum = 0;
- return TempSum;
- //////////////////////////////////////////////////////////////////////////
- }
- /*
- ****************************************************************************************************
- * 功能描述:
- * 输入参数:
- * 返回参数:
- * 说 明:
- ****************************************************************************************************
- */
- uint8_t CheckError(uint8_t* pBuffer) {
- uint8_t Length1, Length2;
- if ((pBuffer[0] == 0x68) && (pBuffer[3] == 0x68)) {
- //可变帧长
- Length1 = pBuffer[1];
- Length2 = pBuffer[2];
- if (Length1 != Length2)
- return 0; //两个长度字节不相等,返回错误
- else
- //校验和相等且最后一个字节为0x16
- if ((GetCheckSum(pBuffer) == pBuffer[4 + Length1]) && (pBuffer[5 + Length1] == 0x16)) {
- RxControlField = pBuffer[4]; //帧校验成功后取得控制域数据
- return VARIABLE_DATA;
- }
- else
- return 0;
- }
- /* 固定帧长第一字节和最后字节校验 */
- else if ((pBuffer[0] == 0x10) && (pBuffer[5] == 0x16)) {
- //检验和是否相等
- if (GetCheckSum(pBuffer) == pBuffer[3]) {
- RxControlField = pBuffer[1]; //取得控制域数据
- return STABLE_DATA;
- }
- else
- return 0;
- }
- else
- //无效帧,丢弃
- return 0;
- }
- /*
- ****************************************************************************************************
- * 功能描述:
- * 输入参数:
- * 返回参数:
- * 说 明:
- ****************************************************************************************************
- */
- uint8_t Protocol101_RxLink(void) {
- RxDIR = (RxControlField >> 7) & 0x01; //取得DIR位
- RxPRM = (RxControlField >> 6) & 0x01; //取得PRM位
- RxFCB = (RxControlField >> 5) & 0x01; //取得FCB位
- RxFCV = (RxControlField >> 4) & 0x01; //取得FCV位
- RxFunctionCode = RxControlField & 0x0F; //取得功能码
- if ((RxDIR == M2S_DIR) && (RxPRM == 1))
- return SUCCESS; //接收标志位判断
- else {
- // newFrame = 1;
- LastFCB = RxFCB;
- return ERROR;
- }
- }
- /*
- ****************************************************************************************************
- * 功能描述:
- * 输入参数:
- * 返回参数:
- * 说 明:
- ****************************************************************************************************
- */
- uint8_t SetTxControlField(uint8_t PRM, uint8_t FCB, uint8_t FCV, uint8_t FuncCode) {
- uint8_t Temp = 0;
- Temp |= ((S2M_DIR & 0x01) << 7);
- Temp |= ((PRM & 0x01) << 6);
- Temp |= ((FCB & 0x01) << 5);
- Temp |= ((FCV & 0x01) << 4);
- Temp |= (FuncCode & 0x0F);
- return Temp;
- }
- void SendStableData(uint8_t PRM, uint8_t FCB, uint8_t FCV, uint8_t FuncCode) {
- uint8_t TxCrtlField = 0;
- uint8_t CheckSum = 0;
- uint8_t FrameData[6] = {0x00};
- TxCrtlField = SetTxControlField(PRM, FCB, FCV, FuncCode);
- FrameData[0] = 0x10;
- FrameData[1] = TxCrtlField;
- FrameData[2] = LINK_ADDRESS;
- CheckSum = FrameData[1] + FrameData[2];
- FrameData[3] = CheckSum;
- FrameData[4] = 0x16;
- SendData(FrameData, 5); //串口发送
- }
- #if 0
- void SendVariableData( uint8_t PRM, uint8_t FCB, uint8_t FCV, uint8_t FuncCode, uint8_t* pBuffer )
- {
- ASDU_DataStructure ASDU_DataStruct;
- ASDU_DataStruct.TypeID = 100;
- ASDU_DataStruct.Qualifier = 1;
- ASDU_DataStruct.Reason = 7;
- ASDU_DataStruct.ASDU_Address = LINK_ADDRESS;
- ASDU_DataStruct.InfoAddress1 = 0x0000;
- ASDU_DataStruct.InfoData1 = 0X14;
- ASDU_Init( ASDU_DataStruct, TxAppBuffer );
- }
- #endif
- #if 0
- /*
- ****************************************************************************************************
- * 功能描述:
- * 输入参数:TxAppLength:应用层数据不为0,指的是ASDU的长度,发送的是可变帧长数据
- * pTxBuffer:链路层数据缓存,最后通过物理通道发送出去
- * pTxAppBuffer:应用层数据缓冲区,会在应用层将数据转移到pTxBuffer中
- * 返回参数:无
- * 说 明:
- ****************************************************************************************************
- */
- void Protocol101_TxLink( uint8_t TxAppLength, uint8_t* pTxBuffer, uint8_t* pTxAppBuffer )
- {
- uint8_t i;
- uint8_t TempSum = 0;
- uint8_t TxCounter = 0;
- //如果应用层数据不为0,则表示发送的是可变帧长数据
- if ( TxAppLength != 0 ) {
- pTxBuffer[0] = 0x68;
- pTxBuffer[1] = TxAppLength + 3;
- pTxBuffer[2] = TxAppLength + 3;
- pTxBuffer[3] = 0x68;
- pTxBuffer[4] = SetTxControlField();
- TempSum += pTxBuffer[4];
- pTxBuffer[5] = LINK_ADDRESS & 0xff;
- TempSum += pTxBuffer[5];
- pTxBuffer[6] = ( LINK_ADDRESS >> 8 ) & 0xff;
- TempSum += pTxBuffer[6];
- TxCounter = 7;
- for ( i = 0; i <= TxAppLength - 1; i++ ) {
- pTxBuffer[TxCounter] = pTxAppBuffer[i];
- TempSum += pTxBuffer[TxCounter++];
- }
- TempSum &= 0xff;
- pTxBuffer[TxCounter++] = TempSum;
- pTxBuffer[TxCounter++] = 0x16;
- } else {
- pTxBuffer[0] = 0x10;
- pTxBuffer[1] = GetTxControlField();
- pTxBuffer[2] = LINK_ADDRESS & 0xff;
- pTxBuffer[3] = ( LINK_ADDRESS >> 8 ) & 0xff;
- //计算校验和
- for ( i = 1; i < 4; i++ )
- TempSum += pTxBuffer[i];
- pTxBuffer[4] = TempSum;
- pTxBuffer[5] = 0x16;
- TxCounter = 6;
- }
- SendData( pTxBuffer, TxCounter ); //串口发送
- }
- #endif
- uint8_t ASDU_Init(ASDU_DataStructure* ASDU_Struct, uint8_t NumOfInfo, uint8_t* pBuffer) {
- uint8_t i = 0;
- uint8_t ASDU_Length = 0;
- uint8_t ASDU_AddressLow = 0;
- uint8_t ASDU_AddressHigh = 0;
- ASDU_AddressLow = LINK_ADDRESS;
- ASDU_AddressHigh = (LINK_ADDRESS >> 8);
- pBuffer[0] = ASDU_Struct->TypeID;
- pBuffer[1] = ASDU_Struct->Qualifier;
- pBuffer[2] = ASDU_Struct->Reason & 0xff;
- pBuffer[3] = ASDU_Struct->Reason >> 8;
- pBuffer[4] = ASDU_Struct->ASDU_Address & 0xff;
- pBuffer[5] = ASDU_Struct->ASDU_Address >> 8;
- pBuffer[6] = ASDU_Struct->InfoAddress & 0xFF;
- pBuffer[7] = ASDU_Struct->InfoAddress >> 8;
- pBuffer[8] = ASDU_Struct->InfoAddress >> 16;
- ASDU_Length = 9;
- while (NumOfInfo--) {
- pBuffer[i + 9] = ASDU_Struct->InfoData[i];
- ASDU_Length += 1;
- i++;
- }
- return ASDU_Length;
- }
- #if 0
- /*
- ****************************************************************************************************
- * 功能描述:
- * 输入参数:
- *
- *
- *
- * 返回参数:
- * 说 明:
- ****************************************************************************************************
- */
- void Protocol101_TxApp( uint8_t TypeID, uint8_t Qual, uint8_t SendReason, uint8_t Func, uint8_t TxAppLength )
- {
- TxFunctionCode = Func & 0x0F;
- if ( TxAppLength != 0 ) {
- TxAppBuffer[0] = TypeID; //类型标识
- TxAppBuffer[1] = Qual; //信息体数量
- TxAppBuffer[2] = ( SendReason & 0xff );
- TxAppBuffer[3] = LINK_ADDRESS & 0xFF; //公共地址低位
- TxAppBuffer[4] = ( LINK_ADDRESS >> 8 ) & 0xFF; //公共地址高位
- }
- Protocol101_TxLink( TxAppLength, TxBuffer, TxAppBuffer );
- }
- #endif
- uint8_t ResponseLinkStatus(void) {
- uint8_t Temp = 11;
- // txAppLength = 0;
- // i = linkState;
- Temp &= 0x0F;
- switch (Temp) {
- case 11:
- TxFCB = 0;
- SendStableData(0, 0, 0, 11);
- // Protocol101_TxApp(0,0,0,0x0b,0); /* 0x0b 链路状态响应 */
- break;
- case 14:
- // Protocol101_TxApp(0,0,0,0x0e,0); /* 0x0e 链路服务未工作 */
- break;
- default:
- // Protocol101_TxApp(0,0,0,0x0f,0); /* 0x0f 链路服务未完成 */
- break;
- }
- // linkState = 0;
- return 1;
- }
- //主站复位远方链路
- uint8_t ResponseResetRemoteLink(void) {
- SendStableData(0, 0, 0, 0);
- return SUCCESS;
- }
- // 发送1级数据, 掉用函数,查看当前所有的信息
- void Data1Frame(){
-
- }
- // 发送2级数据, 掉用函数,查看当前所有的信息
- void Data2Frame(){
-
- }
- // 激活结束帧
- void overFrame(){
- uint8_t data[32];
- data[0] = data[3] = 0x68;
- data[1] = data[2] = 0x0C;
- data[4] = 0x08;
- data[5] = LINK_ADDRESS;
- data[6] = LastType >> 8;
- data[7] = 0x01;
- data[8] = 0x0A;
- data[9] = 0x00;
- data[10] = data[11] = 0xFF;
- data[12] = data[13] = data[14] = 0x00;
- if(LastType >> 8 == 0x64)
- data[15] = 0x14;// 结束全局召唤
- else if(LastType >> 8 == 0x65)
- data[15] = 0x05;// 结束召唤电度
- uint8_t crc = 0;
- for(uint8_t i = 0; i < 12; i++){
- crc += data[i + 4];
- }
- data[16] = crc;
- data[17] = 0x16;
- SendData(data, 18); //串口发送
- }
- //确认帧
- uint8_t ConfirmFrame(void) {
- uint8_t TxCtrlField = 0;
- uint8_t CheckSum = 0;
- uint8_t FrameData[6] = {0x00};
- TxCtrlField |= ((M2S_DIR & 0x01) << 7);
- TxCtrlField |= ((0 & 0x01) << 6);
- TxCtrlField |= ((1 & 0x01) << 5);
- TxCtrlField |= ((0 & 0x01) << 4);
- TxCtrlField |= (0 & 0x0F);
- FrameData[0] = 0x10;
- FrameData[1] = TxCtrlField;
- FrameData[2] = LINK_ADDRESS;
- CheckSum = FrameData[1] + FrameData[2];
- FrameData[3] = CheckSum;
- FrameData[4] = 0x16;
- SendData(FrameData, 5); //串口发送
- }
- //确认总召唤
- uint8_t ResponseCallAll(void) {
- uint8_t i = 0;
- uint8_t TxCtrlField = 0;
- uint8_t TempCallAllBuf[64] = {0x00};
- uint8_t TempASDU_Buf[32] = {0x00};
- uint8_t ASDU_Length = 0; // ASDU的长度,并非可变帧长中的L值
- // uint8_t SendLength = 0; //可变帧长总长度,最后通过串口发送
- uint8_t CheckSum = 0;
- ASDU_DataStructure ASDU_DataStruct;
- //获取控制域的值
- TxCtrlField |= ((M2S_DIR & 0x01) << 7);
- TxCtrlField |= ((0 & 0x01) << 6);
- TxCtrlField |= ((1 & 0x01) << 5);
- TxCtrlField |= ((0 & 0x01) << 4);
- TxCtrlField |= (8 & 0x0F);
- ASDU_DataStruct.TypeID = 0x64;
- ASDU_DataStruct.Qualifier = 0x01;
- ASDU_DataStruct.Reason = 0x0007;
- ASDU_DataStruct.ASDU_Address = 0xffff;
- ASDU_DataStruct.InfoAddress = 0x000000;
- ASDU_DataStruct.InfoData[0] = 0x14;
- ASDU_Length = ASDU_Init(&ASDU_DataStruct, 1,
- TempASDU_Buf); //填充ASDU数据并返回ASDU的长度(此值并非L)
- TempCallAllBuf[0] = 0x68;
- TempCallAllBuf[1] = ASDU_Length + 2;
- TempCallAllBuf[2] = ASDU_Length + 2;
- TempCallAllBuf[3] = 0x68;
- TempCallAllBuf[4] = TxCtrlField;
- TempCallAllBuf[5] = LINK_ADDRESS;
- for (i = 0; i < ASDU_Length; i++)
- TempCallAllBuf[i + 6] = TempASDU_Buf[i];
- for (i = 0; i < (ASDU_Length + 2); i++)
- CheckSum += TempCallAllBuf[i + 4]; //计算校验和
- TempCallAllBuf[ASDU_Length + 6] = CheckSum;
- TempCallAllBuf[ASDU_Length + 7] = 0x16;
- SendData(TempCallAllBuf, (ASDU_Length + 8));
- return 1;
- }
- void UpdateDataForCallAll(void) {
- uint8_t i = 0;
- uint8_t TxCtrlField = 0;
- uint8_t TempCallAllBuf[64] = {0x00};
- uint8_t TempASDU_Buf[32] = {0x00};
- uint8_t ASDU_Length = 0; // ASDU的长度,并非可变帧长中的L值
- // uint8_t SendLength = 0; //可变帧长总长度,最后通过串口发送
- uint8_t CheckSum = 0;
- ASDU_DataStructure ASDU_DataStruct;
- //获取控制域的值
- TxCtrlField = SetTxControlField(0, 0, 0, 0x00);
- ASDU_DataStruct.TypeID = 0x1; //无时标的单点信息
- ASDU_DataStruct.Qualifier = 0x8a; //单地址,6个数据
- ASDU_DataStruct.Reason = 0x14; //响应总召唤
- ASDU_DataStruct.ASDU_Address = LINK_ADDRESS;
- ASDU_DataStruct.InfoAddress = 0x0001;
- if (moduleMaskEn == 0) { //非屏蔽状态及时发送状态
- ASDU_DataStruct.InfoData[0] = Info[0];
- ASDU_DataStruct.InfoData[1] = Info[1];
- ASDU_DataStruct.InfoData[2] = Info[2];
- ASDU_DataStruct.InfoData[3] = Info[3];
- ASDU_DataStruct.InfoData[4] = Info[4];
- ASDU_DataStruct.InfoData[5] = Info[5];
- ASDU_DataStruct.InfoData[6] = Info[6]; //漏保1
- ASDU_DataStruct.InfoData[7] = Info[7]; //漏保2
- ASDU_DataStruct.InfoData[8] = Info[8]; //漏保3
- ASDU_DataStruct.InfoData[9] = Info[9]; //漏保4
- }
- else {
- ASDU_DataStruct.InfoData[0] = 0; //屏蔽状态都按正常处理
- ASDU_DataStruct.InfoData[1] = 0; //屏蔽状态都按正常处理
- ASDU_DataStruct.InfoData[2] = 0; //屏蔽状态都按正常处理
- ASDU_DataStruct.InfoData[3] = 0; //屏蔽状态都按正常处理
- ASDU_DataStruct.InfoData[4] = 0; //屏蔽状态都按正常处理
- ASDU_DataStruct.InfoData[5] = 0; //屏蔽状态都按正常处理
- ASDU_DataStruct.InfoData[6] = 0; //漏保1
- ASDU_DataStruct.InfoData[7] = 0; //漏保2
- ASDU_DataStruct.InfoData[8] = 0; //漏保3
- ASDU_DataStruct.InfoData[9] = 0; //漏保4
- }
- TxCtrlField = SetTxControlField(0, 0, 0, 0x00);
- ASDU_Length = ASDU_Init(&ASDU_DataStruct, 10,
- TempASDU_Buf); //填充ASDU数据并返回ASDU的长度(此值并非L)
- TempCallAllBuf[0] = 0x68;
- TempCallAllBuf[1] = ASDU_Length + 3;
- TempCallAllBuf[2] = ASDU_Length + 3;
- TempCallAllBuf[3] = 0x68;
- TempCallAllBuf[4] = TxCtrlField;
- TempCallAllBuf[5] = LINK_ADDRESS & 0xFF;
- TempCallAllBuf[6] = LINK_ADDRESS >> 8;
- for (i = 0; i < ASDU_Length; i++)
- TempCallAllBuf[i + 7] = TempASDU_Buf[i];
- for (i = 0; i < (ASDU_Length + 3); i++)
- CheckSum += TempCallAllBuf[i + 4]; //计算校验和
- TempCallAllBuf[ASDU_Length + 7] = CheckSum;
- TempCallAllBuf[ASDU_Length + 8] = 0x16;
- SendData(TempCallAllBuf, (ASDU_Length + 9));
- }
- ///遥测1:温度
- void UpdateTempForCallAll(void) {
- uint8_t i = 0;
- uint8_t TempCallAllBuf[64] = {0x00};
- uint8_t TxCtrlField = 0;
- ASDU_DataStructure ASDU_DataStruct;
- uint8_t TempASDU_Buf[32] = {0x00};
- uint8_t ASDU_Length = 0; // ASDU的长度,并非可变帧长中的L值
- uint8_t CheckSum = 0;
- //获取控制域的值
- TxCtrlField = SetTxControlField(0, 0, 0, 0x00);
- ASDU_DataStruct.TypeID = 0x15; //类型标示,不带品质因数的遥测量
- ASDU_DataStruct.Qualifier = 0x83; //品质因数,单地址3个数据
- ASDU_DataStruct.Reason = 0x14; //响应总召
- ASDU_DataStruct.ASDU_Address = LINK_ADDRESS;
- ASDU_DataStruct.InfoAddress = 0x0001;
- if (moduleMaskEn == 0) { //非屏蔽状态及时发送状态
- ASDU_DataStruct.InfoData[0] = InfoTemp[0];
- ASDU_DataStruct.InfoData[1] = InfoTemp[1];
- ASDU_DataStruct.InfoData[2] = InfoTemp[2];
- }
- else {
- ASDU_DataStruct.InfoData[0] = 20; //屏蔽状态都按正常处理
- ASDU_DataStruct.InfoData[1] = 20; //屏蔽状态都按正常处理
- ASDU_DataStruct.InfoData[2] = 20; //屏蔽状态都按正常处理
- }
- TxCtrlField = SetTxControlField(0, 0, 0, 0x00);
- ASDU_Length = ASDU_Init(&ASDU_DataStruct, 3,
- TempASDU_Buf); //填充ASDU数据并返回ASDU的长度(此值并非L)
- TempCallAllBuf[0] = 0x68;
- TempCallAllBuf[1] = ASDU_Length + 3;
- TempCallAllBuf[2] = ASDU_Length + 3;
- TempCallAllBuf[3] = 0x68;
- TempCallAllBuf[4] = TxCtrlField;
- TempCallAllBuf[5] = LINK_ADDRESS & 0xFF;
- TempCallAllBuf[6] = LINK_ADDRESS >> 8;
- for (i = 0; i < ASDU_Length; i++)
- TempCallAllBuf[i + 7] = TempASDU_Buf[i];
- for (i = 0; i < (ASDU_Length + 3); i++)
- CheckSum += TempCallAllBuf[i + 4]; //计算校验和
- TempCallAllBuf[ASDU_Length + 7] = CheckSum;
- TempCallAllBuf[ASDU_Length + 8] = 0x16;
- SendData(TempCallAllBuf, (ASDU_Length + 9));
- }
- void EndOfCallAll(void) {
- uint8_t i = 0;
- uint8_t TxCtrlField = 0;
- uint8_t TempCallAllBuf[64] = {0x00};
- uint8_t TempASDU_Buf[32] = {0x00};
- uint8_t ASDU_Length = 0; // ASDU的长度,并非可变帧长中的L值
- // uint8_t SendLength = 0; //可变帧长总长度,最后通过串口发送
- uint8_t CheckSum = 0;
- ASDU_DataStructure ASDU_DataStruct;
- //获取控制域的值
- TxCtrlField = SetTxControlField(0, 0, 0, 0x00);
- ASDU_DataStruct.TypeID = 0x64;
- ASDU_DataStruct.Qualifier = 0x01;
- ASDU_DataStruct.Reason = 0x0A;
- ASDU_DataStruct.ASDU_Address = LINK_ADDRESS;
- ASDU_DataStruct.InfoAddress = 0x0000;
- ASDU_DataStruct.InfoData[0] = 0x14;
- ASDU_Length = ASDU_Init(&ASDU_DataStruct, 1,
- TempASDU_Buf); //填充ASDU数据并返回ASDU的长度(此值并非L)
- TempCallAllBuf[0] = 0x68;
- TempCallAllBuf[1] = ASDU_Length + 3;
- TempCallAllBuf[2] = ASDU_Length + 3;
- TempCallAllBuf[3] = 0x68;
- TempCallAllBuf[4] = TxCtrlField;
- TempCallAllBuf[5] = LINK_ADDRESS & 0xFF;
- TempCallAllBuf[6] = LINK_ADDRESS >> 8;
- for (i = 0; i < ASDU_Length; i++)
- TempCallAllBuf[i + 7] = TempASDU_Buf[i];
- for (i = 0; i < (ASDU_Length + 3); i++)
- CheckSum += TempCallAllBuf[i + 4]; //计算校验和
- TempCallAllBuf[ASDU_Length + 7] = CheckSum;
- TempCallAllBuf[ASDU_Length + 8] = 0x16;
- SendData(TempCallAllBuf, (ASDU_Length + 9));
- }
- void GetClockFromServer(TimeStructure* TimeStruct, uint8_t* pBuffer) {
- uint16_t Temp = 0;
- Temp = pBuffer[15] << 8;
- Temp += pBuffer[14];
- TimeStruct->MilliSec = (Temp % 1000);
- TimeStruct->Sec = (uint8_t)(Temp / 1000);
- TimeStruct->Min = pBuffer[16];
- TimeStruct->Hour = pBuffer[17];
- TimeStruct->Day = pBuffer[18];
- TimeStruct->Month = pBuffer[19];
- TimeStruct->Year = pBuffer[20];
- }
- // InfoAdress -- 上单元编号:1~6
- // Info -- 上单元状态:0-正常;1-跌落
- //*Time -- 时间结构体
- void ChangeUpdate(uint16_t InfoAdress, uint8_t Info, TimeStructure* Time) {
- uint8_t i;
- uint8_t CheckSum = 0;
- uint8_t InfoArray[32] = {0x00};
- // static uint8_t PreInfo = 0;
- // static uint16_t PreInfoAdress = 0;
- // if ((PreInfoAdress != InfoAdress) || (PreInfo != Info))
- //{
- InfoArray[0] = 0x68;
- InfoArray[1] = 0x12;
- InfoArray[2] = 0x12;
- InfoArray[3] = 0x68;
- InfoArray[4] = SetTxControlField(1, 0, 0, 3);
- InfoArray[5] = LINK_ADDRESS & 0xFF;
- InfoArray[6] = LINK_ADDRESS >> 8;
- InfoArray[7] = 0x1E; // 0x1E==30,带CP56Time2a时标的单点信息
- InfoArray[8] = 0x01;
- InfoArray[9] = 0x03; //传送原因:突发
- InfoArray[10] = LINK_ADDRESS & 0xFF;
- InfoArray[11] = LINK_ADDRESS >> 8;
- InfoArray[12] = InfoAdress & 0xFF;
- InfoArray[13] = InfoAdress >> 8;
- InfoArray[14] = Info;
- InfoArray[15] = (uint8_t)((Time->Sec * 1000) + Time->MilliSec);
- InfoArray[16] = ((Time->Sec * 1000) + Time->MilliSec) >> 8;
- InfoArray[17] = Time->Min;
- InfoArray[18] = Time->Hour;
- InfoArray[19] = Time->Day;
- InfoArray[20] = Time->Month;
- InfoArray[21] = Time->Year;
- for (i = 0; i < 0x12; i++)
- CheckSum += InfoArray[i + 4];
- InfoArray[22] = CheckSum;
- InfoArray[23] = 0x16;
- // PreInfoAdress = InfoAdress;
- // PreInfo = Info;
- SendData(InfoArray, 24);
- // }
- }
- void TempChangeUpdate(uint16_t InfoAdress, uint8_t Info, TimeStructure* Time) {
- uint8_t i;
- uint8_t CheckSum = 0;
- uint8_t InfoArray[32] = {0x00};
- static uint8_t PreInfo = 0;
- static uint16_t PreInfoAdress = 0;
- if ((PreInfoAdress != InfoAdress) || (PreInfo != Info)) {
- InfoArray[0] = 0x68;
- InfoArray[1] = 0x12;
- InfoArray[2] = 0x12;
- InfoArray[3] = 0x68;
- InfoArray[4] = SetTxControlField(1, 0, 0, 3);
- InfoArray[5] = LINK_ADDRESS & 0xFF;
- InfoArray[6] = LINK_ADDRESS >> 8;
- InfoArray[7] = 0x23; // 0x23==35,带CP56Time2a时标的测量标量值
- InfoArray[8] = 0x01;
- InfoArray[9] = 0x03; //传送原因:突发
- InfoArray[10] = LINK_ADDRESS & 0xFF;
- InfoArray[11] = LINK_ADDRESS >> 8;
- InfoArray[12] = InfoAdress & 0xFF;
- InfoArray[13] = InfoAdress >> 8;
- InfoArray[14] = Info;
- InfoArray[15] = (uint8_t)((Time->Sec * 1000) + Time->MilliSec);
- InfoArray[16] = ((Time->Sec * 1000) + Time->MilliSec) >> 8;
- InfoArray[17] = Time->Min;
- InfoArray[18] = Time->Hour;
- InfoArray[19] = Time->Day;
- InfoArray[20] = Time->Month;
- InfoArray[21] = Time->Year;
- for (i = 0; i < 0x12; i++)
- CheckSum += InfoArray[i + 4];
- InfoArray[22] = CheckSum;
- InfoArray[23] = 0x16;
- PreInfoAdress = InfoAdress;
- PreInfo = Info;
- SendData(InfoArray, 24);
- }
- }
- void ResponseTimeSynchronous(void) {
- uint8_t i = 0;
- uint8_t CheckSum = 0;
- uint16_t Temp = 0;
- uint8_t Time[32] = {0x00};
- Temp = NowTimeStruct.Sec * 1000 + NowTimeStruct.MilliSec;
- Time[0] = 0x68;
- Time[1] = 0x11;
- Time[2] = 0x11;
- Time[3] = 0x68;
- Time[4] = SetTxControlField(0, 0, 0, 0);
- Time[5] = LINK_ADDRESS & 0xFF;
- Time[6] = LINK_ADDRESS >> 8;
- Time[7] = 0x67;
- Time[8] = 0x01;
- Time[9] = 0x07; //激活确认
- Time[10] = LINK_ADDRESS & 0xFF;
- Time[11] = LINK_ADDRESS >> 8;
- Time[12] = 0x00;
- Time[13] = 0x00;
- Time[14] = Temp & 0xFF;
- Time[15] = Temp >> 8;
- Time[16] = NowTimeStruct.Min;
- Time[17] = NowTimeStruct.Hour;
- Time[18] = NowTimeStruct.Day;
- Time[19] = NowTimeStruct.Month;
- Time[20] = NowTimeStruct.Year;
- for (i = 0; i < 17; i++)
- CheckSum += Time[i + 4];
- Time[21] = CheckSum;
- Time[22] = 0x16;
- SendData(Time, 23);
- }
- /*
- 更改这个结构,以实现通过GPRS发送一个数据时
- */
- uint8_t DataProcess(void) {
- uint8_t TempRxFunctionCode = 0;
- if (CheckLinkAddress(rx_232_Buffer) == SUCCESS) {
- if (CheckError(rx_232_Buffer) == SUCCESS) {
- //数据校验通过,可以开始处理数据
- if (Protocol101_RxLink() == SUCCESS) {
- TempRxFunctionCode = RxFunctionCode;
- switch (TempRxFunctionCode) {
- case 0: //主站复位远方链路
- ResponseResetRemoteLink();
- break;
- case 1: //主站复位用户进程
- break;
- case 2: //发送\确认链路测试功能
-
- break;
- case 3: //发送\确认用户数据
- if ((rx_232_Buffer[7] == 0x64) && ((rx_232_Buffer[14] == 0x14) || (rx_232_Buffer[15] == 0x14))) {
- ResponseCallAll();
- // SysDelay(1000);
- UpdateDataForCallAll();
- UpdateTempForCallAll(); // SysDelay(1000);
- EndOfCallAll();
- }
- if (rx_232_Buffer[7] == 0x67) {
- // //获取时间
- // GetClockFromServer(&NowTimeStruct, ProtocolRxBuffer);
- // //将时间写入时钟芯片
- // Time_Data[0] = NowTimeStruct.Year;
- // Time_Data[1] = NowTimeStruct.Month;
- // Time_Data[2] = NowTimeStruct.Day;
- // Time_Data[3] = NowTimeStruct.Hour;
- // Time_Data[4] = NowTimeStruct.Min;
- // Time_Data[5] = NowTimeStruct.Sec;
- // //回复确认帧
- // ResponseTimeSynchronous();
- }
- break;
- case 4: //发送\无回答用户数据
- break;
- case 9: //主站请求链路状态
- ResponseLinkStatus();
- break;
- case 10://请求1级用户数据
- break;
- case 11://请求2级用户数据
- break;
- }
-
-
-
-
- return SUCCESS;
- }
- }
- }
- return ERROR;
- }
- //判断属于哪条命令
- uint8_t IEC_Protocol(uint8_t* pBuffer) {
- uint8_t pCheckErrorResult;
- pCheckErrorResult = CheckError(pBuffer);
- if (pCheckErrorResult == STABLE_DATA) {
- if (CheckLinkAddress(pBuffer) == 1) {
- if (pBuffer[1] == 0x49) {
- ResponseLinkStatus();
- }
- else if (pBuffer[1] == 0x40) {
- ResponseResetRemoteLink();
- }
- //固定帧
- return STABLE_DATA;
- }
- }
- else if (pCheckErrorResult == VARIABLE_DATA) {
- if (CheckLinkAddress(pBuffer) == 1) {
- if ((pBuffer[7] == 0x64) && (pBuffer[14] == 0x14)) //总召命令
- {
- ResponseCallAll();
- }
- //可变帧长
- return VARIABLE_DATA;
- }
- }
- else {
- return INVALID_DATA;
- }
- return INVALID_DATA;
- }
- //////////////////////////////////////////
- // //
- // 测试功能函数 //
- // //
- //////////////////////////////////////////
- static void test(void const* arg) {
- while (1)
- {
- while(recv_232_done == 0) delay_ms(100);// 轮询到232串口接收到数据
- recv_232_done = 0;
- // 先判断是固定帧还是可变帧,并储存控制域->RxControlField
- if(CheckError(rx_232_Buffer) == STABLE_DATA){// 固定帧
- if (CheckLinkAddress(rx_232_Buffer) == SUCCESS) {
- if (Protocol101_RxLink() == SUCCESS) { // 取得功能码RxFunctionCode
- if (rx_232_Buffer[1] == 0x49)// 请求链路
- ResponseLinkStatus();
- else if (rx_232_Buffer[1] == 0x40)// 复位链路
- ResponseResetRemoteLink();
-
- // 请求1级数据 FCB位每次取反,这里没做FCB的取反判断
- else if (rx_232_Buffer[1] == 0x7A || rx_232_Buffer[1] == 0x5A)
- {
- if(LastType == 0x6406)// 回应总召唤
- {
- ResponseCallAll();
- LastType = 0x6407;
- }
- else if(LastType == 0x6407)// 回应已有的1级数据
- {
- uint8_t have_data = 0;//后续调用函数,查看当前所有的数据
- if(have_data) Data1Frame();//判断是否还有数据
- else overFrame();
- }
-
- if(LastType == 0x6506)// 回应电度召唤
- {
- ResponseCallAll();
- LastType = 0x6507;
- }
- else if(LastType == 0x6507)// 回应已有的1级数据
- {
- uint8_t have_data = 0;//后续调用函数,查看当前所有的数据
- if(have_data) Data2Frame();//判断是否还有数据
- else overFrame();
- }
- }
- else if (rx_232_Buffer[1] == 0x7B || rx_232_Buffer[1] == 0x5B)// 请求2级数据 FCB位每次取反
- {
- uint8_t noneData = 0xE5;
- SendData(&noneData,1);
- }
- }//Protocol101_RxLink
- }//CheckLinkAddress
- }//CheckError
- else if(CheckError(rx_232_Buffer) == VARIABLE_DATA)// 可变帧
- {
- if (CheckLinkAddress(rx_232_Buffer) == SUCCESS) {
- if (Protocol101_RxLink() == SUCCESS) { // 取得功能码RxFunctionCode
- if ((rx_232_Buffer[6] == 0x64) && rx_232_Buffer[8] == 0x06 && (rx_232_Buffer[15] == 0x14)) //总召命令激活
- {
- LastType = 0x6406;
- ConfirmFrame();
- }
- if ((rx_232_Buffer[6] == 0x65) && rx_232_Buffer[8] == 0x06 && (rx_232_Buffer[15] == 0x05)) //总召命令激活
- {
- LastType = 0x6506;
- ConfirmFrame();
- }
- }//Protocol101_RxLink
- }//CheckLinkAddress
-
- }//CheckError
- } //while
- } //test
- void creatTest(void)
- {
- osThreadDef(IEC, test, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 4);
- osThreadCreate (osThread(IEC), NULL);
- }
|