<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統 > 設計應用 > 基于DDS的任意波形、信號發生器設計

          基于DDS的任意波形、信號發生器設計

          作者:時間:2023-12-14來源:電子森林收藏

          實驗任務

          • 任務:基于核心板 和 底板 完成波形設計并觀察調試結果
          • 要求:通過底板上的旋轉編碼器控制串行DAC芯片DAC081S101基于DDS技術產生波形可選、頻率可調的常見波形信號。
          • 解析:驅動旋轉編碼器得到操作信息,通過邏輯控制波形和頻率寄存器,設計DDS模塊根據波形和頻率寄存器控制波形數據的輸出,波形數據通過串行DAC驅動模塊傳送到底板的DAC芯片進行轉換,得到波形信號輸出。

          實驗目的

          前面章節我們學習了旋轉編碼器的工作原理及驅動方法,本實驗主要學習DDS技術的原理及實現,IP核rom模塊的例化使用,串行DAC芯片DAC081S101的驅動設計。

          本文引用地址:http://www.ex-cimer.com/article/202312/453884.htm
          • 學習數模轉換器DAC的相關知識
          • 串行(SPI接口)DAC芯片DAC081S101的驅動設計
          • 學習DDS技術的原理及實現
          • 完成波形設計實現

          設計框圖

          根據前面的實驗解析我們可以得知,該設計總體可以拆分成如下功能模塊實現,

          • Debounce:給旋轉編碼器按鍵功能輸出進行消抖
          • Encoder:旋轉編碼器旋轉功能驅動
          • logicctrl:根據旋轉編碼器的操作信息控制波形選擇和頻率控制寄存器 * DDS:直接數字式頻率合成器的實現,根據波形選擇和頻率控制信息產生波形數據 * rom:波形數據存儲器,存儲正弦波波表數據 * DAC081S101driver:驅動SPI接口DAC芯片實現數模轉換。

          Top-Down層次設計


          模塊結構設計

          實驗原理

          DAC及DDS介紹

          上一節我們學習了ADC的相關知識,DAC與ADC功能相反,DAC是數字模擬轉換器(英語:Digital to analog converter,英文縮寫:DAC)是一種將數字信號轉換為模擬信號(以電流、電壓或電荷的形式)的設備。在很多數字系統中(例如計算機),信號以數字方式存儲和傳輸,而數字模擬轉換器可以將這樣的信號轉換為模擬信號,從而使得它們能夠被外界(人或其他非數字系統)識別。

          DAC模型

          上圖兩個都是8位DAC模型,轉換精度為 2的8次方等于256,即將Vref分成256份,DAC轉換輸出模擬電壓最小步進為Vref / 256,模擬電壓 Vout = N * Vref / 256 。

          • 并行DAC與數字電路接口包含一根clk和8根data管腳,clk為芯片時鐘管腳,data為芯片數據管腳,每個clk周期從data管腳輸出8bit的數據,完成一次數模轉換,所以clk頻率等于轉換率。
          • 串行DAC(以DAC081S101為例)與數字電路接口為三根線(sync,clk,din),兼容三線SPI總線,sync為幀同步管腳,clk為芯片時鐘管腳,din為芯片數據管腳,當DAC幀同步信號拉低后每個clk周期從din發送1bit的數據,但是根據DAC081S101的時序,需要16個clk完成一次DA轉換,所以clk頻率至少等于采樣率的16倍。

          DDS是直接數字式頻率合成器(Direct Digital Synthesizer)的英文縮寫。與傳統的頻率合成器相比,DDS具有低成本、低功耗、高分辨率和快速轉換時間等優點,廣泛使用在電信與電子儀器領域,是實現設備全數字化的一個關鍵技術。DDS是一種全數字化的頻率合成器,由相位累加器、波形ROM、D/A轉換器和低通濾波器構成。時鐘頻率給定后,輸出信號的頻率取決于頻率控制字,頻率分辨率取決于累加器位數,相位分辨率取決于ROM的地址線位數,幅度量化噪聲取決于ROM的數據位字長和D/A轉換器位數。

          DDS框圖

          DAC模塊電路連接

          這里我們以底板上的DAC模塊電路,其電路圖如下:

          DAC模塊電路

          如DAC模塊電路所示,直接連接DAC081S101芯片的控制端,ADC有6個管腳,2腳VCC為VCC和Vref功能復用,即VCC = Vref。DAC后端是運放電路LMV721,運放模塊為電壓跟隨電路,再往后端射頻端子輸出。

          DAC模塊驅動設計

          前面我們了解DAC081S101芯片和之間連接有三根線(sync、clk、din),兼容三線SPI總線,關于SPI串行總線上節已詳細介紹,這里我們直接查看DAC081S101的芯片手冊。

          DAC081S101管腳說明表:

          DAC081S101管腳說明表

          注:Din信號在SCLK的節拍下傳輸數據,當SCLK下降沿時Din數據被鎖存到移位寄存器,所以FPGA控制在上升沿更新Din數據。

          DAC081S101串行通信時序如下圖:

          DAC081S101串行通信時序

          注:SCLK空閑時為低電平,CPOL = 0,上升沿(第二個邊沿)采樣,CPHA = 1,如果例化通用SPI核完成設計,需要采用SPI的第二種工作模式。

          DAC081S101輸入寄存器

          注: 16個時鐘完成一次DAC轉換,傳輸的16位數據,最高2位為無效數據,次2位為模式口控制數據,再次8位為DAC有效數據(DB7~DB0),最低4位為無效數據。

          針對DAC081S101時序,我們用Verilog設計一個計數器,當計數器值不同時完成不同操作,實現一次DAC轉換,程序實現如下:

          reg [7:0] cnt;always @(posedge clk or negedge rst_n)
          	if(!rst_n) cnt <= 1'b0;
          	else if(cnt >= 8'd34) cnt <= 1'b0;
          	else cnt <= cnt + 1'b1; 
          	reg [7:0] data;
          	always @(posedge clk or negedge rst_n)
          	if(!rst_n) begin
          		dac_sync <= HIGH; dac_clk <= LOW; dac_dat <= LOW;
          	end else case(cnt)
          		8'd0 : begin dac_sync <= HIGH; 
          		dac_clk <= LOW; 
          		data <= dac_data; end
          		8'd1,8'd3,8'd5,8'd7,8'd9,8'd11,8'd13,8'd15,
          		8'd17,8'd19,8'd21,8'd23,8'd25,8'd27,8'd29,8'd31,
          		8'd33: begin dac_sync <= LOW; 
          		dac_clk <= LOW;
          		end
          		8'd2 : begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_dat <= LOW; 
          		end //15
          		8'd4 : begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_dat <= LOW; 
          		end //14
          		8'd6 : begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_dat <= LOW; 
          		end //13
          		8'd8 : begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_dat <= LOW; 
          		end //12
          		8'd10: begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_dat <= data[7]; 
          		end //11
          		8'd12: begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_dat <= data[6]; 
          		end //10
          		8'd14: begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_dat <= data[5]; 
          		end //9
          		8'd16: begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_dat <= data[4]; 
          		end //8
          		8'd18: begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_dat <= data[3]; 
          		end //7
          		8'd20: begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_dat <= data[2]; 
          		end //6
          		8'd22: begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_dat <= data[1]; 
          		end //5
          		8'd24: begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_dat <= data[0]; 
          		end //4
          		8'd26: begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_dat <= LOW; 
          		end //3
          		8'd28: begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_done <= HIGH; 
          		end //2
          		8'd30: begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		dac_done <= LOW; 
          		end //1
          		8'd32: begin dac_sync <= LOW; 
          		dac_clk <= HIGH; 
          		end //0
          		8'd34: begin dac_sync <= HIGH; 
          		dac_clk <= LOW; 
          		end
          		default : begin dac_sync <= HIGH; 
          		dac_clk <= LOW;  
          		end
          	endcase

          到這我們就完成了串行DAC芯片DAC081S101的驅動設計,整個采樣周期用了35個系統時鐘,如果我們采用12MHz時鐘作為該模塊系統時鐘,轉換率Fs = 12M / 35 = 342.86 Ksps,DAC主頻Fsclk = 12 MHz / 2 = 6MHz,DAC081S101芯片手冊Fsclk最高頻率為30MHz,所以想要更高的轉換率,可以將系統時鐘的頻率從12 MHz倍頻到60 MHz。

          模塊接口如下:clk和rstn為系統時鐘及復位,dacsync,dacclk和dacdat為DAC控制管腳,dacdata為DAC轉換數據,dacdone脈沖對應一次DAC轉換的完成

          module DAC081S101_driver
          (
          input				clk,		//系統時鐘
          input				rst_n,  	//系統復位,低有效
          output	reg			dac_done,	//DAC采樣完成標志
          input			[7:0]	dac_data,	//DAC采樣數據
          output	reg			dac_sync,	//SPI總線CS
          output	reg			dac_clk,	//SPI總線SCLK
          output	reg			dac_dat		//SPI總線MOSI
          );
          DDS設計實現

          波表數據示意圖

          如上圖所示,以8位DAC為例,將一個周期的正弦波分割成256份,得到256個相位波形量化數據,設計一個存儲器,寬度為8,深度為256,將256個相位波形量化數據放入存儲器中,我們就得到了一個正弦波波表。我們可以通過例化rom的IP核實現波表的設計,具體的操作如下:

          第一步我們需要有波表數據初始化文件(.mif文件),方便再例化rom核時配置需要的初始化數據,得到波表數據初始化文件的方法很多,簡單介紹兩種:

          1.在Quartus軟件中,選擇File → New → Memory Files → Memory Initialization File,配置存儲深度和位寬,然后將Matlab或Excel等計算的波表數據填入,如下:

          MIF文件創建

          2.安裝正弦波數據生成器(網上搜索下載)工具軟件,配置相應的參數,直接導出生成初始化.mif文件。

          第二步例化rom核,打開Tools菜單下的IP Catalog工具,依次找到Libraty → Basic Functions → On Chip Memory → ROM:1-PORT,配置存儲器寬度和深度,選擇剛剛生成的初始化文件,其他選項默認即可,點擊Finish完成rom的IP核例化。

          ROM 

          ROM

          第三步更改配置模式,因為例化了rom的IP核,需要初始化數據,所以需要更改配置模式。打開Assignments菜單下的Device選項,點擊Device and Pin Opetions,找到Configuration → Configuration mode,下拉列表中選擇最后一項,點擊OK保存。

          設置FPGA配置模式

          打開rom核中的Verilog文件,端口聲明如下:

          input   [7:0]  address;
          input          clock;
          output  [7:0]  q;

          其中clock為存儲器時鐘,address為存儲器地址,q對應address地址中的數據輸出,到這里我們的正弦波表就創建好了。

          并行DAC應用框圖

          如果我們有上圖電路的硬件,當FPGA按照時鐘的節拍產生波形數據,就可以得到對應的模擬輸出了,我們來看一個簡單的DDS產生鋸齒波例子:

          module SimpleDDS(clk, dac_dat);
          input clk;
          output [7:0] dac_dat;//24位相位累加器
          reg [23:0] phase_acc;
          always @(posedge clk) phase_acc <= phase_acc + 24'b1;//相位地址
          wire [23:0] phase = phase_acc;
          assign dac_dat = phase[23:16];  //鋸齒波
          endmodule

          程序中可以看到DDS模塊在每個clk周期都會產生一個8位數據,并行DAC每個clk進行一次DAC轉換,主頻等于轉換率,程序是成立的。對串行DAC(以DAC081S101為例),需要16個clk才能將DDS模塊1次產生的8位數據轉換,所以邏輯上,DDS模塊中的clk端口信號應該跟DAC驅動模塊的轉換率同步,而不是和系統時鐘或主頻同步。

          波形選擇

          上面程序中累加器phase_acc隨時鐘clk自加1,傳輸給并行DAC的數據同樣自加,最后得到鋸齒波輸出,當clk為100MHz時,鋸齒波頻率為100MHz / 2^24 = 5.96Hz。

          鋸齒波輸出:鋸齒波

          想要輸出三角波,只需要把DAC數據輸出賦值的語句改為:

          assign dac_dat = phase[23]? ~phase[22:15]:phase[22:15];     //三角波

          三角波輸出:三角波

          想要輸出方波,只需要把DAC數據輸出賦值的語句改為:

          assign dac_dat = phase[23]? 8'hff : 8'h00;     //方波

          方波輸出:方波

          想要輸出正弦波,只需要把DAC數據輸出賦值的語句改為波表存儲器的例化:

          rom u1
          (
          .clock		(clk		),
          .address	(phase[23:16]	),
          .q		(sin_dat	)
          );

          我們知道了各種波形的產生方法,我們可以同時產生多種波形信號,然后根據波形選擇端口變量wave的值選擇輸出的波形數據,程序實現如下:

          wire [7:0] sin_dat; //正弦波
          wire [7:0] saw_dat = phase[23:16];  //鋸齒波
          wire [7:0] tri_dat = phase[23]? (~phase[22:15]) : phase[22:15]; //三角波
          wire [7:0] squ_dat = phase[23]? 8'hff : 8'h00;  //方波 
          always @(*) begin
              case(wave)
                  2'b00: dac_dat = sin_dat;   //正弦波
                  2'b01: dac_dat = saw_dat;   //鋸齒波
                  2'b10: dac_dat = tri_dat;   //三角波
                  2'b11: dac_dat = squ_dat;   //方波
                  default: dac_dat = sin_dat; //正弦波
              endcaseend 
          rom u1(.clock		(clk		),
          .address	(phase[23:16]	),
          .q		(sin_dat	)
          );

          頻率調節

          上面簡單的DDS設計中, 將相位累加器的控制改為:

          always @(posedge clk) phase_acc <= phase_acc + 24'd2;

          這樣原來需要2^24個clk周期完成的相位增量,現在只需要2^23個clk周期,同樣的相位增量花費時間減少一半,即模擬輸出信號頻率是原來的2倍,改變被加數就會改變頻率,如果我們定義一個端口變量finc作為被加數,使用邏輯調節finc的值就可以調節頻率,f_inc被稱為頻率控制字

          always @(posedge clk) phase_acc <= phase_acc + f_inc;

          相位調節

          上面簡單的DDS設計中, 將相位地址的控制改為:

          wire [23:0] phase = phase_acc + 24'b1;

          相位累加器每次加一個固定的偏移得到全新的相位地址,使波形數據整體上產生相位偏移,不改變輸出的頻率,如果我們定義一個端口變量pinc作為被加數,使用邏輯調節pinc的值就可以調節相位,pinc被稱為相位控制字 <code verilog> wire [23:0] phase = phaseacc + p_inc; </code>

          系統總體實現

          底板上旋轉編碼器帶有按鍵功能,我們使用按鍵消抖模塊完成按鍵信號的消抖處理,前面章節我們還學習了旋轉編碼器旋轉功能的驅動,剛剛講到控制波形的波形選擇和頻率輸出其實就是控制兩個端口參數wave和f_inc,所以從旋轉編碼器的驅動輸出到DDS端口參數的控制,我們還需要一個邏輯模塊。

          按動旋轉編碼器的按鍵切換信號發生器的波形輸出,依次為正弦波、鋸齒波、三角波、方波,波形選擇功能程序實現如下:

          localparam  SIN = 2'b00, SAW = 2'b01, TRI = 2'b10, SQU = 2'b11;//波形輸出選擇
          always @(posedge clk or negedge rst_n) begin
              if(!rst_n) wave <= SIN;
              else if(O_pulse)begin
                  case(wave)
                      SIN: wave <= SAW;
                      SAW: wave <= TRI;
                      TRI: wave <= SQU;
                      SQU: wave <= SIN;
                      default: wave <= SIN;
                  endcase
              end else wave <= wave;
              end

          轉動旋轉編碼器調節信號發生器的輸出頻率,左旋(逆時針)頻率減小,左旋(逆時針)頻率增加,頻率控制功能程序實現如下:

          //頻率控制
          always@(posedge clk or negedge rst_n) begin
              if(!rst_n) f_inc <= 24'ha0000;
              else if(L_pulse) begin
                  if(f_inc <= 24'h10000) f_inc <= f_inc;
                  else f_inc <= f_inc - 24'h10000;
              end else if(R_pulse) begin
                  if(f_inc >= 24'h140000) f_inc <= f_inc;
                  else f_inc <= f_inc + 24'h10000;
              end else f_inc <= f_inc;
              end

          上電默認情況下,頻率控制字f_inc的值為24’ha0000,那么在模擬信號周期內采樣點n = 2^24 / 10 / 2^16 = 25.6。我們設計的DAC驅動轉換率為342.86 Ksps,那么對應模擬信號頻率 f = 342.86K / 25.6 = 13393Hz = 13.4KHz左右。

          旋轉編碼器調節頻率控制字的步進及頻率控制字最小值都為24’h10000,對應頻率步進值及輸出模擬信號最小頻率都等于1.34KHz(運算方法同上)。

          將設計中所有模塊例化連線,完成整體設計,再次強調:DDS模塊的時鐘信號與DAC模塊中的轉換率信號同步,所以DDS模塊中的clk要和DAC081S101driver模塊中的dacdone信號連接。

          綜合后的設計框圖如下:

          RTL設計框圖

          實驗步驟

          1. 雙擊打開Quartus Prime工具軟件;
          2. 新建工程:File → New Project Wizard(工程命名,工程目錄選擇,設備型號選擇,EDA工具選擇);
          3. 新建文件:File → New → Verilog HDL File,鍵入設計代碼并保存;
          4. 設計綜合:雙擊Tasks窗口頁面下的Analysis & Synthesis對代碼進行綜合;
          5. 管腳約束:Assignments → Assignment Editor,根據項目需求分配管腳;
          6. 設計編譯:雙擊Tasks窗口頁面下的Compile Design對設計進行整體編譯并生成配置文件;
          7. 程序燒錄:點擊Tools → Programmer打開配置工具,Program進行下載;
          8. 觀察設計運行結果。

          實驗現象

          將設計加載到FPGA中,使用示波器觀察底板DAC射頻端子信號輸出,按動旋轉編碼器觀察不同的波形輸出,轉動旋轉編碼器觀察頻率的變化。

          默認輸出

          正弦波輸出

           

          鋸齒波輸出

           

          三角波輸出

           

          方波輸出



          評論


          相關推薦

          技術專區

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();