根据802.15.4协议,chapter15.2.7,PHR部分的编码,除了一些控制参数外,在后面添加了6位单错纠正双错检测码(SECDED),用于纠错能力的提升,这6位汉明码为PHR部分提供了至少1bit的纠错能力,以及至少2bit的检错能力。此码块由汉明码构成,与一般汉明码不同的是,改码并没有穿插在信息位中间,而是放在了信息位后方,形成系统码的样式。
- 检错
那么在接收端接收到一串PHR,如何检验它正确与否还是很简单的,只需要将收到的PHR,做与发送端同样的操作,生成SECDED,再与接收到的SECDED进行比较即可,但这种方法没有利用SECDED的性质。
另一种的方法是,将接收到的SECDED码的每一位校验位,与生成它的信息位,进行异或,比如上图中的b18,要与b1,b0,b8,b6,b4,b3,b10,b11同时进行异或,若结果为0,则证明这8位信息位,以及一位校验位没有出错(当然还是存在出错概率的,只不过很低)。在对每一位校验位进行完异或操作后,若结果均为0,则证明PHR传输无误,若有一位不为0,则证明传输有误,需要进行纠错。 - 纠错
在上一步,我们已经求得了校验位与信息位的异或结果。因为在传输过程中,有偶数位同时出错的可能性,若出现偶数位错误,则无法发现出错,我们姑且认为,结果为0,代表不出错,是正确的校验集合;结果为1,代表出错,是存在错误的校验集合。
故我们只需要将出错的校验集合求交集,并且去除该交集在正确的校验集合中的元素,即可得到出错的bit位。
下面简单给出示例代码:
``function [errorBit,RQ] = HammingDecode(PHR)
%检测两个错误,纠正一个错误
%errorBit为错误比特的位数,-2代表错误在校验位,-1代表无需纠错或无法纠错
%RQ为重传参数,可以断定PHR传输错误,需要重新传输
errorBit = -1;
RQ = 0;
HammingMatrix = [2,1,9,7,5,4,11,12;
1,7,6,4,3,10,11,13;
2,9,8,4,3,10,11,-1;
9,8,7,6,5,10,11,-1;
13,12,-1,-1,-1,-1,-1,-1];
B = [];
B(1) = mod(PHR(19)+PHR(1)+PHR(2)+PHR(9)+PHR(7)+PHR(5)+PHR(4)+PHR(11)+PHR(12), 2);
B(2) = mod(PHR(18)+PHR(1)+PHR(7)+PHR(6)+PHR(4)+PHR(3)+PHR(10)+PHR(11)+PHR(13), 2);
B(3) = mod(PHR(17)+PHR(2)+PHR(9)+PHR(8)+PHR(4)+PHR(3)+PHR(10)+PHR(11), 2);
B(4) = mod(PHR(16)+PHR(9)+PHR(8)+PHR(7)+PHR(6)+PHR(5)+PHR(10)+PHR(11), 2);
B(5) = mod(PHR(15)+PHR(13)+PHR(12), 2);
B(6) = mod(PHR(14)+PHR(1)+PHR(2)+PHR(3)+PHR(4)+PHR(5)+PHR(6)+PHR(7)+PHR(8)+PHR(9)+PHR(10)+PHR(11)+PHR(12)+PHR(13)+PHR(15)+PHR(16)+PHR(17)+PHR(18)+PHR(19), 2);
flag = B(6);
errorCount = [];
if flag == 0 %要么错误个数为0,无需纠正,要么错误个数为大于等于2的偶数,无法纠正
for i = 1 : 5
if B(i) == 1
errorCount = [errorCount,i];
end
end
if isempty(errorCount)%说明传输无误
return
else %错误个数为大于等于2的偶数,无法纠正
RQ = 1;
return
end
end
if flag == 1
for i = 1 : 5
if B(i) == 1
errorCount = [errorCount,i];
end
end
if isempty(errorCount)%说明传输错误的比特在校验位上,无需纠正
errorBit = -2;
return
end
end
C = 1:19;%求错误bit所在的集合
for i = 1 : length(errorCount)
C = intersect(C,HammingMatrix(errorCount(i)😅);
end
D = 1:5;%将集合中正确的bit去除
rightCount = setdiff(D,errorCount);
for i = 1 : length(rightCount)
C = setdiff(C,HammingMatrix(rightCount(i)😅);
end
if ~isempty(C)
errorBit = C;
end
end``