調頻信號FM的原理與matlab與FPGA實現

平臺:matlab r2021b,vivado2023.1

本文知識內容摘自《軟件無線電原理和應用》

調頻(FM)是載波的瞬時頻率隨調制信號成線性變化的一種調制方式,音頻調頻信號的數學表達式可以寫為:

s(t)=A[cos(\omega _{c}t+k_{\Omega }\int_{0}^{t}v_{\Omega (t)dt})]

Fm頻率調制,載波的幅度隨著調制波形的幅度變化而變化。

其中\omega _{c}為載波頻率,v_{\Omega }t為調制信號,k_{\Omega }為調制角頻率。

下面是FM調制的matlab實現

clc;
clear;
% 設置參數
fs = 312.5e6;       % 采樣率
fc = 20e6;          % 載波頻率
fm = 1e6;           % 調制信號頻率,內調制最大3mhz
t1 = 0:1/fs:2;      % 時間序列,1微秒
t = t1(1:5000);     %RW需要取整數計算出的頻率是真實
% 生成調制信號
m = cos(2*pi*fm*t);%正弦波
% m = square(2*pi*fm*t);%方波
% m = sawtooth(2*pi*fm*t, 0.5);%三角波
% m = sawtooth(2*pi*fm*t);% 鋸齒波
% 例如,y=x^2;t=1-5;
% Q=cumtrapa(t,y);
% q0=0;
% q1=0.5*(4+1)+0=2.5;
% q2=0.5*(9+3)+2.5=9;
% q3=0.5*(16+9)+9=21.5;
% q4=0.5*(25+16)+21.5=42;
% 計算積分累計積分結果,返回一個向量
integral_term = cumtrapz(t, m);% 生成載波信號
c = cos(2*pi*fc*t);
% FM調制,
kf = 100e6; % 調頻系數
k = 2*pi*fc*t;
k1= kf*integral_term;
s = cos(2*pi*fc*t + kf*integral_term);
% 繪制時域波形
figure(1);
subplot(3,1,1);
plot(t*1e6, m);
title('調制信號');
xlabel('時間 (μs)');
ylabel('幅度');subplot(3,1,2);
plot(t*1e6, c);
title('載波信號');
xlabel('時間 (μs)');
ylabel('幅度');subplot(3,1,3);
plot(t*1e6, s);
title('調制后信號');
xlabel('時間 (μs)');
ylabel('幅度');figure(2);
subplot(1,1,1);
plot(t*1e6, c, 'r', 'LineWidth', 2); % 使用紅色繪制載波信號,線條寬度為2
title('載波信號');
xlabel('時間 (μs)');
ylabel('幅度');
hold on;plot(t*1e6, s, 'k', 'LineWidth', 2); % 使用黑色繪制調制后信號,線條寬度為2
title('調制后信號');
xlabel('時間 (μs)');
ylabel('幅度');% 繪制頻域波形
figure(3);
% 計算頻譜
N = length(t);
f = (-fs/2:fs/N:fs/2-fs/N); % 頻率向量
M = fftshift(fft(m));
C = fftshift(fft(c));
S = fftshift(fft(s));subplot(3,1,1);
plot(f, abs(M)/N,'b');
title('調制信號頻譜');
xlabel('頻率 (GHz)');
ylabel('幅度');subplot(3,1,2);
plot(f, abs(C)/N,'g');
title('載波信號頻譜');
xlabel('頻率 (GHz)');
ylabel('幅度');subplot(3,1,3);
plot(f, abs(S)/N,'r');
title('調制后信號頻譜');
xlabel('頻率 (GHz)');
ylabel('幅度');

調制波為余弦波時時域和頻域圖像

當調制信號為方波時。

為鋸齒波時

FPGA的實現

當我們的調制波是一個余弦波時。

可以看到我們的調制波形是一個余弦波。載波也是一個余弦波,調制波的頻率隨著調制波形的積

分變化而變化。其變化規律如下。

余弦波時,積分量在0,pi和2pi時最小,對應著在0時頻偏最小,在pi/2時頻率與載波相同,在pi時

頻偏正向最大。在3*pi/2時又與載波頻率相同。在2pi時達到了最小頻偏。

在邏輯中有幾種產生正余弦波形的方式,基于DDS的波形發生器,基于cordic的波形發生器。這里我們使用cordic來產生我們的載波和調制波。

關于cordic的頻率控制字這里說明一下。Cordic是你對其輸入一個角度,他給你計算出y(cos,sin)的一個結果。所以我們需要對頻率控制字執行一個累加的過程。其中cordic的角度范圍表示為(-pi,pi)。

關于輸出的頻率計算公式為

f_{o}=\tfrac{phase*fs}{2^{N-2}}

其中f_{o}為輸出頻率,phase為相位控制字,f_{s}為采樣率。2^{N-2}是因為cordic將數據的范圍量化到(-pi,pi)。

所以我們需要控制cordic的累加量

p=p+pi+po

其中p為頻率控制字,pi為載波的頻率控制字,po為頻偏控制字。

例如我們要載波為fi,最大頻偏為fo。假定現在的采樣率時鐘為fs。根據公式

可以算出載波的頻率控制字為

pi=\frac{?{?{}2^{14}}*fi}{fs}

可以算出最大頻偏控制字為

po=\frac{?{?{}2^{14}}*fo}{fs}

所以又調制波的幅度最大為16’h4000=16’d16384表示最大為正1v。
所以po與幅度的對應關系為

k=\frac{?{?{}2^{14}}*fo}{fs*2^{14}}=\tfrac{fo}{fs}

所以最大頻偏和調制波幅度的關系為

po=\frac{fo}{fs}*x

其中x為調制波幅度

邏輯實現現在假定調制波為1mhz,載波為8mhz,最大頻偏為2mhz,采樣率為512mhz。

插入FPGA代碼

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/06/06 21:09:44
// Design Name: 
// Module Name: vtf_cordic
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//module vtf_cordic;reg             aclk;
reg             rst_n;
reg             s_axis_phase_tvalid;
reg  [15 : 0]   s_axis_phase_tdata;
reg  [15 : 0]   s_axis_phase_tdata_0;wire            m_axis_dout_tvalid;
wire [31 : 0]   m_axis_dout_tdata;wire [15:0]     sin ;
wire [15:0]     cos ;
wire [15:0]     sin0 ;
wire [15:0]     cos0 ;cordic_0 u_cordic_0 (.aclk                         (aclk                         ),// input wire aclk.s_axis_phase_tvalid          (s_axis_phase_tvalid          ),// input wire s_axis_phase_tvalid.s_axis_phase_tdata           (s_axis_phase_tdata           ),// input wire [15 : 0] s_axis_phase_tdata.m_axis_dout_tvalid           (m_axis_dout_tvalid           ),// output wire m_axis_dout_tvalid.m_axis_dout_tdata            ({sin,cos}                    )// output wire [31 : 0] m_axis_dout_tdata
);cordic_0 u_cordic_1 (.aclk                         (aclk                         ),// input wire aclk.s_axis_phase_tvalid          (s_axis_phase_tvalid          ),// input wire s_axis_phase_tvalid.s_axis_phase_tdata           (s_axis_phase_tdata_0           ),// input wire [15 : 0] s_axis_phase_tdata.m_axis_dout_tvalid           (                             ),// output wire m_axis_dout_tvalid.m_axis_dout_tdata            ({sin0,cos0}                  )// output wire [31 : 0] m_axis_dout_tdata
);initial
beginaclk    =0;rst_n   =0;#100;rst_n   =1;#100;s_axis_phase_tvalid =1;endreg     [15:0]      wave_add;
reg     [15:0]      phase_tdata;
reg     [15:0]      phase_tdata_0;
//產生一個載波
always@(posedge aclk or negedge rst_n)
beginif(rst_n == 1'b0)beginwave_add  <= 16'b0;endelse beginwave_add  <= 16'd32;end
end
always@(posedge aclk or negedge rst_n)
beginif(rst_n == 1'b0)beginphase_tdata  <= 16'b0;endelse beginphase_tdata  <= phase_tdata + wave_add;end
end
always@(posedge aclk or negedge rst_n)
beginif(rst_n == 1'b0)beginphase_tdata_0  <= 16'b0;endelse if(phase_tdata >= 16'h0 && phase_tdata <= 16'h4000 )beginphase_tdata_0  <= phase_tdata;endelse if(phase_tdata > 16'h4000 && phase_tdata <= 16'h8000 )beginphase_tdata_0  <= phase_tdata - 16'h4000;endelse if(phase_tdata > 16'h8000 && phase_tdata <= 16'hc000 )beginphase_tdata_0  <= phase_tdata - 16'h8000;endelse if(phase_tdata > 16'hc000 && phase_tdata <= 16'hffff )beginphase_tdata_0  <= phase_tdata - 16'hc000;endelse beginphase_tdata_0  <= phase_tdata;end
end
always@(posedge aclk or negedge rst_n)
beginif(rst_n == 1'b0)begins_axis_phase_tdata  <= 16'b0;endelse begins_axis_phase_tdata  <= 16'he000 + phase_tdata_0;end
end//-------------------------------------------------------------------
reg     [15:0]      wave_add_m;
reg     [15:0]      phase_tdat_m;
reg     [15:0]      phase_tdata_0_m;wire    [15:0]      sinsin={sin[15],sin[15],sin[15],sin[15],sin[15],sin[15],sin[15],sin[15],sin[15:8]};
//產生一個方波
always@(posedge aclk or negedge rst_n)
beginif(rst_n == 1'b0)beginwave_add_m  <= 16'b0;endelse beginwave_add_m  <= sinsin + 16'd262;end
end
always@(posedge aclk or negedge rst_n)
beginif(rst_n == 1'b0)beginphase_tdat_m  <= 16'b0;endelse beginphase_tdat_m  <= phase_tdat_m + wave_add_m;end
end
always@(posedge aclk or negedge rst_n)
beginif(rst_n == 1'b0)beginphase_tdata_0_m  <= 16'b0;endelse if(phase_tdat_m >= 16'h0 && phase_tdat_m <= 16'h4000 )beginphase_tdata_0_m  <= phase_tdat_m;endelse if(phase_tdat_m > 16'h4000 && phase_tdat_m <= 16'h8000 )beginphase_tdata_0_m  <= phase_tdat_m - 16'h4000;endelse if(phase_tdat_m > 16'h8000 && phase_tdat_m <= 16'hc000 )beginphase_tdata_0_m  <= phase_tdat_m - 16'h8000;endelse if(phase_tdat_m > 16'hc000 && phase_tdat_m <= 16'hffff )beginphase_tdata_0_m  <= phase_tdat_m - 16'hc000;endelse beginphase_tdata_0_m  <= phase_tdat_m;end
end
always@(posedge aclk or negedge rst_n)
beginif(rst_n == 1'b0)begins_axis_phase_tdata_0  <= 16'b0;endelse begins_axis_phase_tdata_0  <= 16'he000 + phase_tdata_0_m;end
endalways#0.977 aclk = ~aclk;endmodule

仿真為

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/35852.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/35852.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/35852.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

open()函數——打開文件并返回文件對象

自學python如何成為大佬(目錄):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 open()函數用于打開文件&#xff0c;返回一個文件讀寫對象&#xff0c;然后可以對文件進行相應讀寫操作。 語法參考 open()函數的語法格式如下&…

用Idea運行Python失敗,同級目錄下的模塊無法導入試試這個方法

哈嘍,大家好,我是木頭左! 在Python編程中,經常會遇到需要導入同級目錄下的模塊的情況。然而,有時候在使用IDEA運行Python時,可能會遇到無法導入同級目錄下的模塊的問題。這個問題可能是由于Python解釋器沒有正確識別到同級目錄下的模塊導致的。那么,如何解決這個問題呢?…

【K8s】專題六(2):Kubernetes 穩定性之健康檢查

以下內容均來自個人筆記并重新梳理&#xff0c;如有錯誤歡迎指正&#xff01;如果對您有幫助&#xff0c;煩請點贊、關注、轉發&#xff01;歡迎掃碼關注個人公眾號&#xff01; 目錄 一、基本介紹 二、工作原理 三、探針類型 1、存活探針&#xff08;LivenessProbe&#x…

docker入門配置

1、創建配置鏡像 由于國內docker連接外網速度慢&#xff0c;采用代理 vi /etc/docker/daemon.json添加以下內容 {"registry-mirrors": ["https://9cpn8tt6.mirror.aliyuncs.com","https://dockerproxy.com","https://hub-mirror.c.163.co…

SOA和ESB介紹

SOA&#xff08;面向服務的架構&#xff09; 面向服務的架構&#xff08;Service-Oriented Architecture&#xff0c;SOA&#xff09;是一種設計理念&#xff0c;用于構建松耦合的、可互操作的、模塊化的服務。在SOA架構中&#xff0c;應用程序被劃分為一系列的服務&#xff0c…

電腦屏幕花屏怎么辦?5個方法解決問題!

“我剛剛打開電腦就發現我的電腦屏幕出現了花屏的情況。這讓我很困惑&#xff0c;我應該怎么解決這個問題呢&#xff1f;求幫助。” 在這個數字時代的浪潮中&#xff0c;電腦早已成為我們生活中不可或缺的一部分。然而&#xff0c;當你正沉浸在緊張的游戲對戰中&#xff0c;或是…

從零到一學FFmpeg:AVCodecContext 結構體詳析與實戰

文章目錄 前言一、函數原型二、功能描述三、使用場景四、使用實例 前言 avio_open是FFmpeg庫中的一個函數&#xff0c;用于打開一個I/O&#xff08;輸入/輸出&#xff09;上下文&#xff0c;以便于讀寫文件、網絡流或其他類型的媒體數據源。這個函數是FFmpeg進行文件操作的基礎…

谷歌上搞下來的,無需付費,可以收藏!

在數字化時代&#xff0c;我們越來越依賴于智能設備來獲取信息和知識。中國智謀App正是這樣一款應用&#xff0c;它將中國古代的智慧與謀略書籍帶入了我們的移動設備&#xff0c;讓我們能夠隨時隨地學習和領悟。而且提供文言文的原文和譯文。 軟件下載方式&#xff1a;谷歌上搞…

39.右鍵彈出菜單管理游戲列表

上一個內容&#xff1a;38.控制功能實現 以 ??????? 38.控制功能實現 它的代碼為基礎進行修改 效果圖&#xff1a; 點擊設置之后的樣子 點擊刪除 點擊刪除之后的樣子 實現步驟&#xff1a; 首先添加一個菜單資源&#xff0c;右擊項目資源選擇下圖紅框 然后選擇Menu 然…

【C語言】字符/字符串+內存函數

目錄 Ⅰ、字符函數和字符串函數 1 .strlen 2.strcpy 3.strcat 4.strcmp 5.strncpy 6.strncat 7.strncmp 8.strstr 9.strtok 10.strerror 11.字符函數 12. 字符轉換函數 Ⅱ、內存函數 1 .memcpy 2.memmove 3.memcmp Ⅰ、字符函數和字符串函數 1 .strlen 函數原型&#xff1a;…

《計算機英語》 Unit 6 Internet 互聯網

Section A Internet 互聯網 The Internet is a global system of interconnected computer networks that use the standard Internet protocol suite (TCP/IP) to link several billion devices worldwide. 互聯網是一個全球性的互連計算機網絡系統&#xff0c;使用標準的互聯…

python多線程加速web服務

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、代碼實現&#xff1f;1.引入庫2.讀入數據 總結 前言 提示&#xff1a;這里可以添加本文要記錄的大概內容&#xff1a; 1 提示&#xff1a;以下是本篇文章…

15、Spring~容器啟動過程

15、Spring~容器啟動過程 容器啟動過程AnnotationConfigApplicationContext類的四個構造器&#xff1a;啟動過程詳解無參構造方法refresh()方法prepareRefresh()方法prepareBeanFactory()方法invokeBeanFactoryPostProcessors()方法registerBeanPostProcessors()方法finishBean…

蘋果CMS-V10 搭建教程踩坑,跳過部分驗證

我突發奇想,想要安裝一個CMS 蘋果CMS搭建教程-CSDN博客 然后就有了下面的問題 結論是zip相關依賴未安裝, 通過 apt install php-zip, 重新打開安裝頁面,同樣如此 最后依據某個網站提示,修改 "\\192.168.1.200\root\var\www\html\maccms\application\install\control…

JSR 303全解析:如何在Java項目中實施高效數據校驗

1. JSR 303是什么&#xff1f; JSR 303&#xff08;Java Specification Request 303&#xff09;&#xff0c;也稱為Bean Validation&#xff0c;是Java中的一個規范&#xff0c;用于定義Java對象的校驗規則。 1.1 JSR 303的主要功能 注解驅動&#xff1a;通過注解直接在Jav…

多家國產大模型提供OpenAI API服務替代方案,谷歌將推出明星網紅AI聊天機器人

ChatGPT狂飆160天&#xff0c;世界已經不是之前的樣子。 更多資源歡迎關注 1、OpenAI終止對中國提供服務 6月25日凌晨&#xff0c;多個用戶收到OpenAI的推送郵件&#xff0c;信中稱&#xff0c;自今年7月9日起&#xff0c;將開始阻止來自非支持國家和地區的API&#xff08;應…

3.任務的創建與刪除

1.什么是任務&#xff1f; 任務可以理解為進程/線程&#xff0c;創建一個任務&#xff0c;就會在內存開辟一個空間。 任務通常都含有while(1)死循環 2.任務創建與刪除相關的函數 3.CUBEMAX相關配置 編輯一個led1閃爍的任務

小程序使用echarts和echarts配置項總結(全網最簡單詳細)

文章目錄 概要小程序中使用echarts1. ec-canvas2. 下載項目3. 去echarts官網定制&#xff1a;4.點擊下載5.引入使用 echarts的option配置知識點歸納整理&#xff08;還在更新&#xff09;&#xff1a;小結 概要 小程序中使用echarts&#xff08;簡單詳細&#xff09; 小程序中…

解密城市酷選為何異軍突起!打造消費新潮流的排隊免單模式

一、城市酷選平臺簡介 在數字化浪潮席卷全球的今天&#xff0c;城市酷選作為一個前沿的消費平臺&#xff0c;憑借其獨特的排隊免單模式&#xff0c;成功吸引了眾多消費者和商家的目光。該平臺不僅整合了線上線下的資源&#xff0c;更通過數字化手段&#xff0c;為消費者提供了…

云計算 | 期末梳理(中)

1. 經典虛擬機的特點 多態(Polymorphism):支持多種類型的OS。重用(Manifolding):虛擬機的鏡像可以被反復復制和使用。復用(Multiplexing):虛擬機能夠對物理資源時分復用。2. 系統接口 最基本的接口是微處理器指令集架構(ISA)。應用程序二進制接口(ABI)給程序提供使用硬件資源…