学习笔记:DAC与ACD"/>
SPI学习笔记:DAC与ACD
一、SPI协议简介
SPI = Serial Peripheral Interface,是串行外围设备接口,是一种高速,全双工,同步的通信总线。常规只占用四根线,节约了芯片管脚,PCB的布局省空间。现在越来越多的芯片集成了这种通信协议,常见的有EEPROM、FLASH、AD转换器等。
二、遵循SPI协议控制DAC:tlv5618
1.时序分析
从tlv5618芯片的数据手册中可找到其时序特性:
由tw确定sclk时钟频率为20MHz;根据DIN时序可知在SCLK上升沿DIN改变,在SCLK下降沿读取DIN;tsu与thd长度之和小于tw,故直接用20MHz时钟设计DIN长度即可满足;tsu用于限制CS的起止点,在仿真时检验并调整使CS满足tsu即可。
2.模块框图
根据时序图可知,用线性序列机即可(LSM)实现。定义的信号如下:
3.代码实现
//采用线性序列机(LSM)来实现
module dac_driver(input fpga_clk ,input rst_n ,input dac_pulse ,input [15:0]dac_data ,output reg cs_n ,//low level validoutput reg sclk ,output reg mosi ,output reg dac_sig ,output reg dac_done
);//供电电压不同,参数最小值不同,这里按照兼容VDD = 5V 和 VDD = 3V 的参数设计
// tsu(cs-ck) : 20ns //
// tsu(c16-cs): 20ns //
// th(D): 10ns //
// th(csh):50ns //
// sclk : 20Mhz //
//
// D15 - D12 : 设置位 根据手册来设置 //
// D11 - D0 : 数据位 需要转化的电压值 //wire clk_40m ;
pll pll_inst(.inclk0(fpga_clk),.c0(clk_40m));//detect dac_pulse
reg dac_pulse_reg ;
always@(posedge fpga_clk or negedge rst_n)
if(!rst_n)dac_pulse_reg <= 0 ;
else dac_pulse_reg <= dac_pulse ;//dac_sig
always@(posedge fpga_clk or negedge rst_n)
if(!rst_n) dac_sig <= 0 ;
else if( (dac_pulse_reg == 0) & ( dac_pulse == 1) )dac_sig <= 1 ;
else if( dac_done )dac_sig <= 0 ;// dac_cnt : 0 - 15
reg [5:0]dac_cnt ;
always@(posedge clk_40m or negedge rst_n)
if(!rst_n) begindac_cnt <= 0 ;end
else if(dac_sig)begindac_cnt <= dac_cnt + 1 ; if(dac_cnt == 34 )dac_cnt <= 0 ;end
elsedac_cnt <= 0 ;//dac_done:
always@(posedge clk_40m or negedge rst_n)
if(!rst_n) dac_done <= 0 ;
else if( dac_cnt == 34 )dac_done <= 1 ;
else if( dac_done )dac_done <= 0 ;// cs_n
always@(posedge clk_40m or negedge rst_n)
if(!rst_n) cs_n <= 1 ;
else if(dac_sig)beginif(dac_cnt < 32 )cs_n <= 0 ;elsecs_n <= 1 ;end// sclk
always@(posedge clk_40m or negedge rst_n)
if(!rst_n) sclk <= 0 ;
else if(dac_sig)beginsclk <= !sclk ; end
else sclk <= 0 ;//mosi
always@(posedge clk_40m or negedge rst_n)
if(!rst_n) mosi <= 0 ;
else if(dac_sig)begincase(dac_cnt)0 : mosi <= dac_data[15] ;2 : mosi <= dac_data[14] ;4 : mosi <= dac_data[13] ;6 : mosi <= dac_data[12] ;8 : mosi <= dac_data[11] ;10 : mosi <= dac_data[10] ;12 : mosi <= dac_data[9] ;14 : mosi <= dac_data[8] ;16 : mosi <= dac_data[7] ;18 : mosi <= dac_data[6] ;20 : mosi <= dac_data[5] ;22 : mosi <= dac_data[4] ;24 : mosi <= dac_data[3] ;26 : mosi <= dac_data[2] ;28 : mosi <= dac_data[1] ; 30 : mosi <= dac_data[0] ; 32 : mosi <= 0 ; default:;endcaseend
else mosi <= 0 ;endmodule
`timescale 1ns/1ns
module dac_driver_tb();reg fpga_clk ;
reg rst_n ;
reg dac_pulse ;
reg [15:0]dac_data ;
wire cs_n ;
wire sclk ;
wire mosi ;
wire dac_done ;dac_driver dac_driver_inst(.fpga_clk(fpga_clk) ,.rst_n(rst_n) ,.dac_pulse(dac_pulse) ,.dac_data(dac_data) ,.cs_n(cs_n) ,//low level valid.sclk(sclk) ,.mosi(mosi) ,.dac_done(dac_done)
);initial fpga_clk = 0 ;
always #10 fpga_clk = ! fpga_clk ;initial
beginrst_n = 0 ;dac_pulse = 0 ;dac_data = 0 ;#100 ;rst_n = 1 ;#100 ;dac_data = 16'h5a5a ;#100 ;dac_pulse = 1 ;#40 ;dac_pulse = 0 ;#100;wait(dac_done);#3000 ;dac_data = 16'ha5a5 ;#100 ;dac_pulse = 1 ;#40 ;dac_pulse = 0 ;#100;wait(dac_done);#3000 ;$stop;endendmodule
4.仿真验证
由图可知,tsu为25ns,th(csh)为50ns,满足要求。
更多推荐
SPI学习笔记:DAC与ACD
发布评论