diff --git a/Matlab/comm/lab5_0.m b/Matlab/comm/lab5_0.m new file mode 100644 index 0000000..f71a8e1 --- /dev/null +++ b/Matlab/comm/lab5_0.m @@ -0,0 +1,72 @@ +clc +%================================================ +%已知抽样值以△为单位 +%================================================ +x = 2047 %抽样值/量化单位△ +pcmcode = pcmEnCode(x) %调用pcmCode()函数实现PCM编码 +amp = pcmDeCode(pcmcode) %调用pcmDecode()函数实现PCM译码 +amp = pcmDecode(pcmcode) +%qerror = x-amp %求量化误差 +%================================================ +%已知抽样值为实际电压值,则需先转换为以△为单位 +%================================================ +% M = 5; %设置量化范围 -5~+5 +% delta = M/2^11; %求量化单位△ +% y = +2.5 %设置抽样值/V +% y0 = round(y/delta) %将抽样值转换为以△为单位 +% pcmcode = pcmCode(y0) %PCM编码 +% amp=pcmDecode(pcmcode); %PCM译码 +% amp = amp*delta %转换为实际电压值 +% qerror=y-amp %求量化误差 + + +function pcmcode = pcmEnCode(s) + start_t=[0,2.^(4:11)]; + width_t=[1,1,2,4,8,16,32,64]; + pcm=0; + if s>0 + pcm=pcm+bitshift(1,7); + else + s=abs(s) + end + for i = 0:7 + if s < start_t(i+2) + pcm=pcm+bitshift(i,4); + pcm=pcm+floor((s-start_t(i+1))/width_t(i+1)); + break + end + end + pcmcode=dec2bin(pcm,8); +end + +function amp = pcmDeCode(pcmcode) + start_t=[0,2.^(4:11)]; + width_t=[1,1,2,4,8,16,32,64]; + code=bin2dec(pcmcode); + isNeg=0; + if code < 128 + isNeg=1; + k=bitshift(bitand(code,0b01111111),-4); + amp=start_t(k+1) ... + + double(mod(bitand(code,0b01111111),16)) ... + * width_t(k+1); + if isNeg=1 amp=-amp;end +end + +%PCM译码函数 +function amp = pcmDecode(pcmcode) + code_table=[0,2.^(4:11)]; %段落起始电平表 + delta=[1,1,2,4,8,16,32,64]; %段内量化间隔表 + codeDec=bin2dec(pcmcode); %二进制编码字符串转换为十进制数值 + ucode=bitand(codeDec,0b01111111); %屏蔽极性位 + k=bitshift(ucode,-4); %右移4位,提取段落码 + x0=code_table(k+1); %查表求段落起始电平 + m=bitand(ucode,0b00001111); %提取段内码 + x1=double(m)*delta(k+1); %求段内量化电平 + dV=x0+x1+delta(k+1)/2; %译码输出电平 + if codeDec<=128 %处理极性 + amp=-dV; + else + amp=dV; + end +end