信号调制的目的是是一种波形的某些特性按照另一种波形或信号而变化的过程或处理方法。而在无线电通信中,将电磁波作为信息传输的载体,信息为待传输的基带信号,即调制信号,特点是频率较低,频带较宽且相互重叠,为了适合单一信道传输,必须进行调制。
调制的原因:需要将待传输的基带信号也即是调制信号加载到高频振荡信号上的过程,其实质是将基带信号搬移到高频载波上去,频谱搬移,目的是将待传输的模拟信号或数字信号变换成适合信道传输的高频信号,保证解调的正确性。
FM调频是使载波的频率随调制信号的大小变化而变化,而振幅保持不变的调制方式。
调频信号数学表达式:
原理: cosAcosB = 1/2(cos(A+B) + cos(A-B))
m(n)序列就是最终解调结果,而求 m(n)的过程被称为鉴频。但是该方法计算量过大且占用资源,可使用改进算法,规避FM鉴频器存在的“门限效应”和反正切运算。
Q(n)当前Q路采样点;I(n)当前I路采样点
I( n-1),Q(n-1) 指上一拍I 路的值和 Q路的值
%***************调制过程********
%读音频文件
%产生载波
%产生两个调制信号的dac I Q路调制数据
%进行正交调制
%*********************
fs = 16e6;%载波采样率 16mhz
fc = 1e6;%载波中心频率 1mhz
df = 75e3;%最大频偏 75khz
fm = 16e3;%音频采样率 16khz
%2^23 为相位累加器; fs = 16e6;32767=2^15-1 音频最大值(16位)
kf = df*(2^32/fs)/32767;%调频灵敏度 , 75k 为最大频偏
AC=1024;%幅度
%***************
%read pcm file
file = fopen('v3edu.pcm','r');%file 为文件的句柄
m = fread(file,'int16');
figure(1);
plot(m);
m_len = length(m)*fs/fm;%按照载波采样率的长度计算
%用DDS 生成载波信号 1mhz
%计算频率控制字 w
w= fc*2^32/fs;%1mhz 载波的频率控制字
%实现载波查表的过程,生成载波的ROM
n=0:1/1024:1023/1024;
s_rom=sin(2*pi*n);
c_rom=cos(2*pi*n);
%相位累加器,读取rom,生成信号
w_r=0;
rrom_addr=0;%读查找表的地址
%zeros(1,10); 1行10个0
cw_sin=zeros(1,m_len); %定义向量的长度
cw_cos=zeros(1,m_len);
%for循环内部完成DDS操作,累加-》取高10位-》送到rom-》取出来的幅值就是1mhz频率
for i=1:m_len
w_r = w_r + w;%相位累加
if(w_r > 2^32)%作32位累加器的溢出判断
w_r = w_r -2^32;
end
rrom_addr=round(w_r/2^22);% /2^22 取高10位,取整,读查找表地址
if rrom_addr==0
rrom_addr=1;
end
cw_sin(i)= s_rom(rrom_addr);%寻址,得到载波
cw_cos(i)= c_rom(rrom_addr);%寻址,得到载波
end
%测试 DDS
%plot(cw_sin(1:3000),'r');
%hold on;
%plot(cw_cos(1:3000),'b');
%对音频信号重采样,即1个点复制1下,复制1000次,升采样
m_t= zeros(1,m_len); %16mhz
for i=1:length(m)
for j=1:fix(fs/fm) %复制1000次
m_t((i-1)*fix(fs/fm)+j)=m(i);%同一个16k的采样点复制1000次,这样就是16M采样点
end
end
%频率控制字:kf * m_t
%*************************
%调制 sin 和 cos 信号
w_r=0;
rrom_addr=0;%读查找表的地址
%zeros(1,10); 1行10个0
dac_i=zeros(1,m_len); %定义向量的长度
dac_q=zeros(1,m_len);
%for循环内部完成DDS操作,累加-》取高10位-》送到rom-》取出来的幅值就是1mhz频率
for i=1:m_len
w_r = w_r + kf*m_t(i);%相位累加
if(w_r > 2^32)%作32位累加器的溢出判断
w_r = w_r -2^32;
elseif(w_r <0)
w_r = w_r + 2^32;%负的溢出时,纠正为正数
end
rrom_addr=round(w_r/2^22);% /2^22 取高10位
if rrom_addr==0
rrom_addr=1;
end
%得到 I Q 路数据,下一步可进行混频
dac_q(i)= AC*s_rom(rrom_addr);%寻址,得到载波
dac_i(i)= AC*c_rom(rrom_addr);%寻址,得到载波
end
%**********************
%正交调制
s_t= zeros(1,m_len);%s_t最终调制好的载波
for i=1:m_len
s_t(i)=dac_i(i)*cw_cos(i)+dac_q(i)*cw_sin(i)*(-1);
end
%*******************************
%正交解调
i_data=zeros(1,m_len);
q_data=zeros(1,m_len);
for i=1:m_len
i_data(i)=s_t(i)*cw_cos(i);
q_data(i)=(-1)*s_t(i)*cw_sin(i);
end
% I Q 路数据进行低通滤波,把高频分量滤除
%滤波器抽头系数 taps filter
NUM = [-7.894e-05, -2.483e-04, -4.516e-04, -7.089e-04, -1.035e-03, -1.435e-03, -1.903e-03, -2.417e-03, -2.938e-03, -3.415e-03, -3.778e-03, -3.948e-03, -3.837e-03, -3.357e-03, -2.42e-03, -9.524e-04, 1.106e-03, 3.791e-03, 7.113e-03, 1.105e-02, 1.554e-02, 2.051e-02, 2.583e-02, 3.135e-02, 3.691e-02, 4.233e-02, 4.742e-02, 5.199e-02, 5.588e-02, 5.894e-02, 6.105e-02, 6.213e-02, 6.213e-02, 6.105e-02, 5.894e-02, 5.588e-02, 5.199e-02, 4.742e-02, 4.233e-02, 3.691e-02, 3.135e-02, 2.583e-02, 2.051e-02, 1.554e-02, 1.105e-02, 7.113e-03, 3.791e-03, 1.106e-03, -9.524e-04, -2.42e-03, -3.357e-03, -3.837e-03, -3.948e-03, -3.778e-03, -3.415e-03, -2.938e-03, -2.417e-03, -1.903e-03, -1.435e-03, -1.035e-03, -7.089e-04, -4.516e-04, -2.483e-04, -7.894e-05];
%
adc_i=conv(i_data,NUM);%卷积,得到I路低频分量
adc_q=conv(q_data,NUM);
%conv会叠加上抽头系数-1个数据点,长度会改变
% FM解调
c_len=length(adc_i);%conv运算后length会改变,重新取length
cr=zeros(1,c_len);
cj=zeros(1,c_len);
for i=2:c_len% n-1=1
cr(i) = adc_i(i)*adc_i(i)+adc_q(i)*adc_q(i);%I(n)^2+ Q(n)^2
cj(i) = adc_i(i-1)*adc_q(i)-adc_i(i)*adc_q(i-1); % I(n-1)*Q(n) - I(n)*Q(n-1);
end
%angle用于存储解调出的数据
angle= zeros(1,c_len);
for i=1:c_len
if cr(i) == 0
angle(i) = 0;
else
angle(i) = (cj(i)/cr(i))*2^16;% *2^16 位宽转换
end
end
%以取均值的方式完成降采样,16M -》 16K
d_len=length(angle);
sum=0;
cnt=0;
demout=zeros(1,fix(d_len*(fm/fs)));
dcnt=1;
for i=1:d_len
sum=sum+angle(i);
if cnt==fs/fm % 完成1000次的累加,进行平均,并且存储到demout
demout(dcnt)=sum/cnt;
dcnt = dcnt+1;
cnt =0;
sum =0;
end
cnt=cnt+1;
end
figure(2);
plot(demout);
%FM解调-方法2 近似arctan求法
c_len = length(adc_i);
cr = zeros(1,c_len);
cj = zeros(1,c_len);
for i = 2:c_len
cr(i) = adc_i(i)*adc_i(i-1) + adc_q(i)*adc_q(i-1);
cj(i) = adc_q(i)*adc_i(i-1) - adc_i(i)*adc_q(i-1);
end
figure;
subplot(2,1,1);plot(cr(200:end-200));title('cr');
subplot(2,1,2);plot(cj(200:end-200));title('cj');
% angle = atan2(cj,cr);
pi4 = 2^16 * pi/4;
pi34 = 2^16 * pi*3/4;
cjabs = zeros(1,c_len);
angle = zeros(1,c_len);
for i = 1:c_len
if (cr(i) == 0 && cj(i) == 0)
angle(i) = 0;
else
cjabs(i) = cj(i);
if cjabs(i) < 0
cjabs(i) = -cjabs(i);
end
if cr(i) >= 0
% angle(i) = pi4 - pi4 * (cr(i) - cj_r(i))/(cr(i) + cj_r(i)); % pi4 = pi/4
angle(i) = pi4*(2^16 - 2^16 * (cr(i) - cjabs(i))/(cr(i) + cjabs(i)));
else
% angle(i) = pi34 - pi4 * (cr(i) + cj_r(i))/(cj_r(i) -cr(i)); %pi34 = pi *3/4
angle(i) = pi4*(3*2^16 - 2^16 * (cr(i) + cjabs(i))/(cjabs(i) - cr(i)));
end
if cj(i) < 0
angle(i) = -angle(i);
end
end
end
angle = fix(angle)/2^16;
figure;plot(angle);title(' angle ');