电力抄表 DLT645-1997-2007解析源代码

645规约的全称应该是“中华人民共和国电力行业标准DL/T 645——1997多功能电能表通信规约”。在经过多年的现场时间基础上,为了适应市场需求的发展,全国电工仪器仪表标委会于2000年10月组建《自动抄表系统》国家标准起草工作组,并开始起草《自动抄表系统》国家标准。初步确定采用国际电工委员会的IEC62056标准作为我国载波集抄系统通信规约的标准。就是在IEC62056中,考虑到载波信道通信的复杂性与特殊性,还是采用了最大程度的开放性。

645规约还规定了两字节的数据标识,还有一字节的密码权限、三字节的传输密码!对于居民照明用户,只有一个电能量标志,数据保密性要求也与动力用户大相径庭!这里的数据比特浪费几乎到了无以复加的地步……

/******************************************************************************* * Function Name : DLT645_2007Receive * Description : Receive a DLT645-2007 frame form serial port. * Input : serial port * Output : None * Return : 0 waiting * : other OK *******************************************************************************/ unsigned int DLTReceive(unsigned char port) { static unsigned int DLT_RxPos[4] = {0,0,0,0}; // 接收位置 unsigned char i, sum; unsigned int len; if(UARTReceive(port, (&DLT_RxBuf[port][0] + DLT_RxPos[port]), 1)) // 从串口缓冲区读出数据 { DLT_RxPos[port] ++; } while((DLT_RxPos[port] > 10) && (DLT_RxBuf[port][0] != 0x68 || DLT_RxBuf[port][7] != 0x68)) { // 找帧头 for(i = 1;i < DLT_RxPos[port];i ++) // 将缓冲区中的数据往前移 { DLT_RxBuf[port][i - 1] = DLT_RxBuf[port][i]; } DLT_RxPos[port] --; } if((DLT_RxPos[port] < 10) || DLT_RxBuf[port][0] != 0x68 || DLT_RxBuf[port][7] != 0x68 ) { // 没有找到帧头,直接返回 return 0; } len = DLT_RxBuf[port][9] + 12; if(len > 212) // 长度不合法,重新找帧头 (645-2007数据域长度<=200,再加上帧头帧尾12B,共212B) { for(i = 1;i < DLT_RxPos[port];i ++) { DLT_RxBuf[port][i - 1] = DLT_RxBuf[port][i]; } DLT_RxPos[port] --; return 0; } if(DLT_RxPos[port] < len) // 长度不够,继续等待 { return 0; } if(DLT_RxBuf[port][len - 1] != 0x16) // 找到帧头,长度足够,结束符合法么 { for(i = 1;i < DLT_RxPos[port];i ++) { DLT_RxBuf[port][i - 1] = DLT_RxBuf[port][i]; } DLT_RxPos[port] --; return 0; } sum = 0; // 结束符合法,计算校验和 for(i = 0;i < len - 2;i++) { sum += DLT_RxBuf[port][i]; } if(sum != DLT_RxBuf[port][len - 2]) // 校验和不合法,将缓冲区中的数据往前移 { for(i = 1;i < DLT_RxPos[port];i ++) { DLT_RxBuf[port][i - 1] = DLT_RxBuf[port][i]; } DLT_RxPos[port] --; return 0; } else { for(i = 0; i < len; i++) { DLT_TxBuf[port][i] = DLT_RxBuf[port][i]; } DLT_RxPos[port] = 0; #ifdef __LED_PROCESS__ if(port == M485) { USTimerSet(dwRxTimer, 500000); dwRxFlag = 1; } else { USTimerSet(upRxTimer, 500000); upRxFlag = 1; } #endif return len; } }

你可能感兴趣的:(电力抄表 DLT645-1997-2007解析源代码)