日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基础篇-verilog-单路串行ADC-TLC549

發布時間:2025/4/5 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基础篇-verilog-单路串行ADC-TLC549 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

注明:雖然此實驗來自于諸多入門教程,其中包括gao石的,但我個人覺得他的時序寫的不好,沒有完全遵循芯片的時序,它直接用AD——CLK的上升沿讀取AD_DATA, 但是,事實上,芯片時序,并不是在8位全在上升沿讀取。
8位串行模數轉換器
8位開關電容逐次逼近的方法實現A/D
內部具有4MHz的系統時鐘,轉換速度小于17us
允許的最大轉換速率是40000次/s(一個周期,采樣下來,再讀取。)
電源3V到6V
方便采用3線串行接口方式與各種微處理器進行連接





最高有效位(A7)在CS降低后自動置于數據輸出總線上。剩下的7位(a6 - a0)在前7個I / O時鐘的邊緣上被鎖定了。B7-B0遵循同樣的方式。
根據NOTEs的意思,也就是DA_DATA遵循某種時序串行吐出data,那么,在何時才吐出的是DATA的哪一位呢?
這就要遵循一定的時序關系。
這種關系便是:
在第一個CLK的上升沿讀取A7,第一個CLK到第六個CLK的下降沿讀取A6——A0。
思路:狀態機:3個狀態
1:轉換狀態(也可視作初始狀態)
2:1.4us(CS由高變低狀態)
3:DA_CLK(采樣狀態)
//-----------------------------------------------------------------------------2018.11.6 23:00
//------------------------------------------------------------------------------- 明日再來寫

系統時鐘是4M,并非是采樣時鐘,注意采樣在SAMPLE階段,也就是后4個時鐘周期進行的。外接時鐘速率1.1M并不是指的采樣速率,那是接口讀取速率。串行芯片,我門需要注意的是一個周期,采樣時間+轉換時間=1/40_000 而在并行芯片中,往往是給的CLOCK即采樣時鐘。
下圖是AD904芯片時序,在DATA_change階段進行采樣,并進行完成相關的量化。

下面的代碼,串行TLC549,采樣后,存儲在8位寄存器當中

module AD_TLC549 #(parameter T_conv=12'd850,//轉換時間50M*17us=850parameter T_su=8'd70,//準備時間50M*1.4us=70usparameter AD_CLK_nop=4'd8,//定義8個AD_CLKparameter AD_CLK_circle_time=6'd46,//0.92usparameter AD_CLK_circle_time_half=6'd23 //23*50=0.46us ) ( input sys_clk, input RST_N, input AD_DATA, //------------------- output AD_CLK, output CS_N,output reg [AD_CLK_nop-1:0] AD_out_DATA //串行的AD_DATA轉并行的8位寄存器);wire AD_CLK_edg; reg AD_out_reg_finish;//串行轉并行完成標志 reg [11:0] T_conv_cnt=0;//轉換時間的計數器 reg [7:0] T_su_cnt=0;//準備時間的計數器 reg [3:0] AD_CLK_cnt=0;//AD_CLK個數計數器 reg [5:0] AD_CLK_circle_time_cnt=0;//一個AD_CLK的高/低電平時間計數器 reg AD_CLK_reg_reg;//用于緩存一拍AD_CLK,實現下降沿檢測//設置輸出寄存器 reg AD_CLK_reg=0; reg CS_N_reg;reg [AD_CLK_nop-1:0] AD_out_reg;//采用三段式狀態機 /*有限狀態機,三段式建模風格*/ /*三個過程*/ //狀態編碼 localparam transition_state = 3'b001,//數據轉換狀態ready_1_4_state = 3'b010,//準備采樣狀態Acess_sample_state = 3'b100;//采樣狀態 //這里可以把數據轉換狀態視作初始狀態,1沒有時鐘,2 CS_N為高,也無效。 reg [2:0] now_state=transition_state; reg [2:0] next_state=transition_state;//1.實現狀態轉換:實現當前狀態now_state到next_state的轉換 always @ (posedge sys_clk) beginif(!RST_N)now_state<=transition_state;elsenow_state<=next_state; end //2.設置狀態切換條件,產生下一個狀態 always@(*) begincase(now_state)transition_state:if(T_conv_cnt==T_conv) //如果轉換時間36next_state=ready_1_4_state;elsenext_state=transition_state;ready_1_4_state:if(T_su_cnt==T_su)next_state=Acess_sample_state;elsenext_state=ready_1_4_state; Acess_sample_state:if(AD_CLK_cnt<AD_CLK_nop)next_state=Acess_sample_state;elsenext_state=transition_state; default:;endcaseend//3.產生每個狀態機的條件輸出值 always @ (posedge sys_clk) begincase(next_state)transition_state:beginT_conv_cnt<=T_conv_cnt+1;T_su_cnt<=0;AD_CLK_cnt<=0;endready_1_4_state:beginT_su_cnt<=T_su_cnt+1;T_conv_cnt<=0;endAcess_sample_state:beginif (AD_CLK_edg)AD_CLK_cnt <= AD_CLK_cnt + 1'b1;elseAD_CLK_cnt <= AD_CLK_cnt;endendcaseend //4.設置每個輸出值 //1.CS_N的輸出值 always@(posedge sys_clk) beginif(!RST_N)beginCS_N_reg<=1; //end else if(now_state==transition_state)beginCS_N_reg<=1; //endelse beginCS_N_reg<=0; //CS_N低電平有效end end assign CS_N=CS_N_reg;//2.AD_CLK的輸出值 always@(posedge sys_clk) beginif(!RST_N)AD_CLK_circle_time_cnt<=0;else if(now_state==Acess_sample_state)AD_CLK_circle_time_cnt<=(AD_CLK_circle_time_cnt<AD_CLK_circle_time-1)?(AD_CLK_circle_time_cnt+1'b1):0;elseAD_CLK_circle_time_cnt<=0; endalways@ (posedge sys_clk) beginif(!RST_N)AD_CLK_reg<=0;else if(now_state==Acess_sample_state)AD_CLK_reg <= (AD_CLK_circle_time_cnt <=AD_CLK_circle_time_half-1) ? 1'b1 : 1'b0;elseAD_CLK_reg<=0; end //3.AD_CLK_nop_edg控制 always @ (posedge sys_clk) beginAD_CLK_reg_reg<=AD_CLK_reg; //寄存一拍 endassign AD_CLK_edg = AD_CLK_reg_reg&(~AD_CLK_reg);//判斷下降沿assign AD_CLK=AD_CLK_reg;//4.AD_DATA_reg控制讀取........控制在什么時候,把串行AD_DATA的數據寫入多位的寄存器AD_DATA_reg之中,時機不對,自然寫入的數肯定就不對 always @ (posedge sys_clk) beginif((now_state==ready_1_4_state)&(next_state==Acess_sample_state))AD_out_reg[AD_CLK_nop-1]<=AD_DATA;else if(AD_CLK_edg&(AD_CLK_cnt<=AD_CLK_nop-1))AD_out_reg[AD_CLK_nop-1-1:0]<={AD_out_reg[AD_CLK_nop-1-1-1:0],AD_DATA};//移位循環實現串行轉并行else if(AD_CLK_cnt==AD_CLK_nop)//在第8個時鐘下降沿的時候,代表了AD_DATA_reg已經移位完成,之所以沒有剛好設置第7個下降沿,是擔心第7個下降沿還在讀取。AD_out_reg_finish<=1;elsebeginAD_out_reg<=AD_out_reg;AD_out_reg_finish<=0; endendalways @ (posedge sys_clk) beginif(AD_out_reg_finish==1) //只有在讀取8位完畢后,再將這8位數更新AD_out_DATA<=AD_out_reg;elseAD_out_DATA<=AD_out_DATA; endendmodule // Copyright (C) 1991-2013 Altera Corporation // Your use of Altera Corporation's design tools, logic functions // and other software and tools, and its AMPP partner logic // functions, and any output files from any of the foregoing // (including device programming or simulation files), and any // associated documentation or information are expressly subject // to the terms and conditions of the Altera Program License // Subscription Agreement, Altera MegaCore Function License // Agreement, or other applicable license agreement, including, // without limitation, that your use is for the sole purpose of // programming logic devices manufactured by Altera and sold by // Altera or its authorized distributors. Please refer to the // applicable agreement for further details.// ***************************************************************************** // This file contains a Verilog test bench template that is freely editable to // suit user's needs .Comments are provided in each section to help the user // fill out necessary details. // ***************************************************************************** // Generated on "11/08/2018 16:19:41"// Verilog Test Bench template for design : AD_TLC549 // // Simulation tool : ModelSim (Verilog) // `timescale 1 ns/ 1 ps module AD_TLC549_vlg_tst(); // constants // general purpose registers reg eachvec; // test vector input registers reg AD_DATA; reg RST_N; reg sys_clk; // wires wire AD_CLK; wire [7:0] AD_out_DATA; wire CS_N;// assign statements (if any) AD_TLC549 i1 ( // port map - connection between master ports and signals/registers .AD_CLK(AD_CLK),.AD_DATA(AD_DATA),.AD_out_DATA(AD_out_DATA),.CS_N(CS_N),.RST_N(RST_N),.sys_clk(sys_clk) ); initial begin $display("Running testbench"); #0 sys_clk=0; #0 RST_N=0; #40 RST_N=1; #0 AD_DATA=1;end //------------------------------------------ always begin #10 sys_clk=~sys_clk; end endmodule


在第8個AD_clk過后才更新AD_out_DATA


整體效果:

符合AD_CLK 一個周期0.92us,半個周期長度也符合,檢查了

符合1.4us



以下是工程連接:
https://download.csdn.net/download/ciscomonkey/10773104

總結

以上是生活随笔為你收集整理的基础篇-verilog-单路串行ADC-TLC549的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。