- "解析下行数据"FC:
python
#pos := 2;
/////////////////////////解析区域变量的参数////////////////////
#tmp_areaVar.Area := PEEK(area := #buff_area_var.Area, dbNumber := #buff_area_var.DBNum, byteOffset := #pos); //帧区域
#pos := #pos + 2;
#tmp_areaVar.DBNum := DWORD_TO_DINT(IN := PEEK_DWORD(area := #buff_area_var.Area, dbNumber := #buff_area_var.DBNum, byteOffset := #pos)); //帧DB号
#pos := #pos + 4;
#tmp_areaVar.Offset := DWORD_TO_DINT(PEEK_DWORD(area := #buff_area_var.Area, dbNumber := #buff_area_var.DBNum, byteOffset := #pos)); //帧字节偏移
#pos := #pos + 4;
#tmp_areaVar.byteCount := DWORD_TO_DINT(PEEK_DWORD(area := #buff_area_var.Area, dbNumber := #buff_area_var.DBNum, byteOffset := #pos)); //帧字节长度
#pos := #pos + 4;
#tmp_areaVar.bit := DWORD_TO_DINT(PEEK_DWORD(area := #buff_area_var.Area, dbNumber := #buff_area_var.DBNum, byteOffset := #pos)); //帧位(bit)
#pos := #pos + 4; //pos目前位于数据区之前
////////////////////////////解析数据内容//////////////////////////
//如果是bool
IF #tmp_areaVar.bit <> 16#FFFFFFFF THEN
POKE_BOOL(area := #tmp_areaVar.Area, ////写一个bool位
dbNumber := #tmp_areaVar.DBNum,
byteOffset := #tmp_areaVar.Offset,
bitOffset := DINT_TO_INT(IN := #tmp_areaVar.bit),
value := PEEK_BOOL(area := #buff_area_var.Area, dbNumber := #buff_area_var.DBNum, byteOffset := #pos, bitOffset := #tmp_areaVar.bit));
/////////////////////////////////如果不是bool//////////////////////////////
ELSE //写块数据
POKE_BLK(area_src := #buff_area_var.Area,
dbNumber_src := #buff_area_var.DBNum,
byteOffset_src := #pos,
area_dest := #tmp_areaVar.Area,
dbNumber_dest := #tmp_areaVar.DBNum,
byteOffset_dest := #tmp_areaVar.Offset,
count := #tmp_areaVar.byteCount);
END_IF;
"处理下行数据"FC:
python
/////////////// 追加数据到buff区的尾部 ///////////
//缓冲区溢出检查
IF #pos_tail + #this_len > 2000 THEN //缓冲区最大长度
#pos_tail := 0; // 溢出则清空, 防止越界写
RETURN;
END_IF;
//把最新数据内容加到缓冲区的最后
POKE_BLK(area_src := #data_areaVar.Area,
dbNumber_src := #data_areaVar.DBNum,
byteOffset_src := 0,
area_dest := #buf_areaVar.Area,
dbNumber_dest := #buf_areaVar.DBNum,
byteOffset_dest := #pos_tail,
count := #this_len);
#pos_tail := #pos_tail + #this_len;
#pos_head := 0;
/////////// 循环处理数据直至最后一行/////////
WHILE #pos_tail > 0 DO
//IF #pos_tail < 4 THEN
//RETURN;
//END_IF;
//#pos_tail := 0;
//RETURN;
//"b_tmp" := PEEK(area := #buf_areaVar.Area, dbNumber := #buf_areaVar.DBNum, byteOffset := #pos_head);
///////////// 搜索帧头////////////
#pos_head := 0;
WHILE #pos_head + 1 < #pos_tail DO
IF (PEEK(area := #buf_areaVar.Area, dbNumber := #buf_areaVar.DBNum, byteOffset := #pos_head) = #frameHeader1) AND
(PEEK(area := #buf_areaVar.Area, dbNumber := #buf_areaVar.DBNum, byteOffset := #pos_head + 1) = #frameHeader2) THEN
#tmp_status := 1; //找到了帧头,可能的最后一个是#pos_tail-2
//"char_TMP" := 'a';
EXIT; // 找到帧头立即退出
ELSE
//"char_TMP" := 'b';
#pos_head := #pos_head + 1; //没找到,可能的最后一个是#pos_tail-1
END_IF;
END_WHILE;
/////////没找到帧头, 丢弃前面的垃圾///////////////////
IF #pos_head = #pos_tail - 1 THEN //如果找到了帧头,可能的最后一个是#pos_tail-2,所以走到了这里一定是没找到
//如果最后一行是帧头,保留,等待下一帧凑齐第二个帧头
IF PEEK(area := #buf_areaVar.Area, dbNumber := #buf_areaVar.DBNum, byteOffset := #pos_head) = #frameHeader1 THEN
// POKE_BLK(area_src := #buf_areaVar.Area,
// dbNumber_src := #buf_areaVar.DBNum,
// byteOffset_src := #pos_head,
// area_dest := #buf_areaVar.Area,
// dbNumber_dest := #buf_areaVar.DBNum,
// byteOffset_dest := 0,
//count := 1);
#pos_tail := 1;
//RETURN;
ELSE
#pos_tail := 0; //丢弃所有数据
END_IF;
RETURN;
END_IF;
// 查找到的帧头不在首位: 移到buf[0], 丢弃前面的无效数据
IF #pos_head > 0 THEN
POKE_BLK(area_src := #buf_areaVar.Area,
dbNumber_src := #buf_areaVar.DBNum,
byteOffset_src := #pos_head,
area_dest := #buf_areaVar.Area,
dbNumber_dest := #buf_areaVar.DBNum,
byteOffset_dest := 0,
count := #pos_tail - #pos_head);
#pos_tail := #pos_tail - #pos_head;
#pos_head := 0;
END_IF;
///////////// 心跳帧////////////
IF #pos_tail >= #pos_head + 3 AND PEEK(area := #buf_areaVar.Area, dbNumber := #buf_areaVar.DBNum, byteOffset := #pos_head + 2) = #frameTail1 AND
PEEK(area := #buf_areaVar.Area, dbNumber := #buf_areaVar.DBNum, byteOffset := #pos_head + 3) = #frameTail2 THEN
POKE_BLK(area_src := #buf_areaVar.Area,
dbNumber_src := #buf_areaVar.DBNum,
byteOffset_src := #pos_head + 4,
area_dest := #buf_areaVar.Area,
dbNumber_dest := #buf_areaVar.DBNum,
byteOffset_dest := 0,
count := #pos_tail - 4);
#pos_tail := #pos_tail - 4;
#pos_head := 0;
CONTINUE;
END_IF;
IF #pos_tail < #pos_head + 16 THEN // 半包, 等待补齐,当超过16个字节就可以读出本帧携带的数据长度
RETURN;
END_IF;
//"int_tmp" := BYTE_TO_INT(PEEK(area := #buf_areaVar.Area, dbNumber := #buf_areaVar.DBNum,
// byteOffset := #pos_head + 2));
"byte_tmp" := PEEK(area := #buf_areaVar.Area, dbNumber := #buf_areaVar.DBNum,
byteOffset := #pos_head+2);
//////////////// 本帧携带的有效数据长度/////////////////////////
IF (BYTE_TO_INT(PEEK(area := #buf_areaVar.Area, dbNumber := #buf_areaVar.DBNum,
byteOffset := #pos_head + 2)) >= 129) AND
(BYTE_TO_INT(PEEK(area := #buf_areaVar.Area, dbNumber := #buf_areaVar.DBNum,
byteOffset := #pos_head + 2)) <= 132) THEN //监测Array参数是否16#81--16#84
#byte_count := DWORD_TO_DINT(PEEK_DWORD(area := #buf_areaVar.Area, dbNumber := #buf_areaVar.DBNum,
byteOffset := #pos_head + 12));
//"int_tmp" := #byte_count;
//#byte_count := DWORD_TO_DINT(PEEK_DWORD(area := #buf_areaVar.Area, dbNumber := #buf_areaVar.DBNum,
//byteOffset := #pos_head + 10));
// "char_TMP" := 'c';
ELSE
POKE_BLK(area_src := #buf_areaVar.Area,
dbNumber_src := #buf_areaVar.DBNum,
byteOffset_src := 2,
area_dest := #buf_areaVar.Area,
dbNumber_dest := #buf_areaVar.DBNum,
byteOffset_dest := 0,
count := #pos_tail - 2); //废帧,把帧头去掉后重新检测
#pos_tail := #pos_tail - 2;
CONTINUE;
END_IF;
// 帧总长=24+N
IF #pos_tail < 24 + #byte_count THEN
RETURN; // 数据不齐, 等待补齐
END_IF;
//////////////////////////// CRC计算 [修复6: 范围到23+N, 含CRC前一字节] //////////////////////////
#wCRC := 16#FFFF;
FOR #i := 0 TO #pos_head + 21 + #byte_count DO // 对除了最后2位之外的所有字节做CEC
#bTemp := PEEK(area := #buf_areaVar.Area,
byteOffset := #i,
dbNumber := #buf_areaVar.DBNum);
#wTemp := #wCRC XOR BYTE_TO_WORD(IN := #bTemp);
#wTemp := #wTemp AND 16#00FF;
#nIndex := WORD_TO_INT(IN := #wTemp);
#wCRC := SHR(IN := #wCRC, N := 8) XOR #DB_CRC_TABLE[#nIndex];
END_FOR;
///////////// CRC校验 [失败则丢弃帧头以及area] ////////////
IF #wCRC <> PEEK_WORD(area := #buf_areaVar.Area,
byteOffset := #pos_head + 22 + #byte_count,
dbNumber := #buf_areaVar.DBNum) THEN
POKE_BLK(area_src := #buf_areaVar.Area,
dbNumber_src := #buf_areaVar.DBNum,
byteOffset_src := 4,
area_dest := #buf_areaVar.Area,
dbNumber_dest := #buf_areaVar.DBNum,
byteOffset_dest := 0,
count := #pos_tail - 4);
#pos_tail := #pos_tail - 4;
CONTINUE;
END_IF;
#done := TRUE;
//////////////////////////// 解析数据内容 //////////////////////////
"_build_AreaVal"(Area := #buf_areaVar.Area,
DBNum := #buf_areaVar.DBNum,
Offset := 0,
byteCount := 0,
destAreaVar := #tmp_areavar);
"解析下行数据"(#tmp_areavar);
//////////////////////////// 移除已处理的帧//////////////////////////
#pos_head := 24 + #byte_count;
IF #pos_head < #pos_tail THEN
POKE_BLK(area_src := #buf_areaVar.Area,
dbNumber_src := #buf_areaVar.DBNum,
byteOffset_src := #pos_head,
area_dest := #buf_areaVar.Area,
dbNumber_dest := #buf_areaVar.DBNum,
byteOffset_dest := 0,
count := #pos_tail - #pos_head);
END_IF;
#pos_tail := #pos_tail - #pos_head;
#pos_head := 0;
END_WHILE;
// 查找帧尾
//FOR #i:=#pos_head TO #pos_tail-2 DO
//WHILE #pos_head < #pos_tail-2 DO
//IF PEEK(area := #buf_areaVar.Area, dbNumber := #buf_areaVar.DBNum, byteOffset := #i) = #frameTail1 AND
// PEEK(area := #buf_areaVar.Area, dbNumber := #buf_areaVar.DBNum, byteOffset := #i +1) = #frameTail2 THEN
#tmp_status := 2; //找到了帧尾
//EXIT; // 找到帧尾立即退出
//END_IF;
//#pos_head := #pos_head + 1;
//END_WHILE;
//END_FOR;
//IF #i=#pos_tail-2 THEN
//RETURN;