%filtercoequant.m
%调用filtercompare0函数生成滤波器系数;
h_pm = filtercompare0;
%将生成的滤波器系数数据写入FPGA所需的txt文件中。
fid = fopen('D:\matalb_dw\filtercoequant\m\lpf.txt','w');
%fopen:将数据按指定格式读入到matlab中的函数
%fid:file ID,文件代号,
%返回值为+N,即正整数表示文件打开成功,文件代号是N
%返回值为-1,表示文件打开不成功
%'w',写入(文件若不存在,自动创建)
%若为'r',则表示只读。
fprintf(fid,'%12.12f\r\n',h_pm);
%fprintf:将数据按指定格式写入到指定的文本文件中;
%fid:文件句柄;
%format,%d整数,%f小数形式,
% %6.2f:总长度为6位,小数点后保留2位,如3.14159,输出为0003.14。
%\r\n:回车
fclose(fid);
%关闭fid
%量化滤波系数
qm=8;%量化位宽为8bit;
q8 = round(h_pm/max(abs(h_pm))*(2^(qm-1)-1));
%最大值为 0111_1111,1111_1111;(-127~+127)
s_q8 = sum(abs(q8));
%系数的绝对值之和。
q8_bin = dec2bin(q8+2^qm*(q8<0));
%dec2bin:把十进制数转换成二进制形式补码,并存在一个字符串中。
%q>0时,q8+2^qm*(q8<0) == q8;
%q<0时,q8+2^qm*(q8<0) == q8+2^qm;补码作为正整数+原码的绝对值=2^qm.
qm=10;
%量化位宽为10bit;
q10 = round(h_pm/max(abs(h_pm))*(2^(qm-1)-1));
qm=4;
q4 = round(h_pm/max(abs(h_pm))*(2^(qm-1)-1));
%获取量化前后滤波器的幅频响应数据。
q_pm = 20*log10(abs(fft(h_pm,1024)));
q_pm = q_pm-max(q_pm);
q_pm8 = 20*log10(abs(fft(q8,1024)));
q_pm8 = q_pm8-max(q_pm8);
q_pm10 = 20*log10(abs(fft(q10,1024)));
q_pm10 = q_pm10-max(q_pm10);
q_pm4 = 20*log10(abs(fft(q4,1024)));
q_pm4 = q_pm4-max(q_pm4);
%设置幅频响应的横坐标为Hz
x_f = [0:(8000/length(q_pm)):8000/2];
%只显示正频率部分的幅频响应
m_pm = q_pm(1:length(x_f));
m_pm8 = q_pm8(1:length(x_f));
m_pm10 = q_pm10(1:length(x_f));
m_pm4 = q_pm4(1:length(x_f));
%绘制幅频响应曲线
plot(x_f,m_pm,'-',x_f,m_pm4,'.',x_f,m_pm8,'-.',x_f,m_pm10,'--');
xlabel('频率/Hz');
ylabel('幅度/dB');
legend('未量化','4位量化','8位量化','10位量化');
grid;
本文需要调用上篇文章的filtercompare0.m
图像如下:
可以看到4位量化存在较大偏差,8位和10位基本与未量化的一直,所以,可以选用8位量化的系数。