首页/文章/ 详情

FPGA入门5——DAC3283寄存器配置,SPI通信

10月前浏览314

今天讲的是FPGA SPI的配置主要是以TI的DAC3283为例

主要有写时序和读时序如下图1,图2所示:

图1:写时序

图2:读时序

今天主要介绍的是写时序:SCLK是DAC3283的串行接口时钟输入。串行数据使能SDENB是DAC3283的使能端。SDIO是串行数据输入端,将DAC3283的输入数据在SCLK的上升边缘上触发。

图3:写时序状态流程图

代码实现:

    module spi_ctrl(  input wire sclk,//系统时钟50Mhz  input wire  rst_n,  input wire  work_en,  ouput   reg   conf_end,  output  wire  spi_clk,//小于50-60Mhz,这里使用1Mhz  output  wire  spi_sdi,  output  wire  spi_csn  input  wire  spi_sdo//读输入管脚先不进行编程);parameter  IDLE = 5'b0_0001;parameter  WAIT = 5'b0_0010;parameter  R_MEM= 5'b0_0100;parameter  W_REG= 5'b0_1000;parameter  STOP = 5'b1_0000;parameter  H_DIV_CYC = 5'd25-1;//按位与a=&4'b001=1'b0,相邻两位相与reg  [4:0]  state;//状态机寄存器变量,编码方式采用独热码reg  [4:0]  div_cnt;reg   clk_p=1'b0;wire  clk_n;reg   pose_flag;reg   [3:0] wait_cnt;reg   [3:0] shift_cnt;reg   [4:0] r_addr;wire   [15:0] r_data;wire  wren;reg   [15:0] shift_buf;reg   data_end;reg   sdi;reg   csn;reg   tck;//分频计数器always @(posedge sclk or negedge rst_n)  if(rst_n==1'b0)    div_cnt <= 5'd0;  else if(div_cnt==H_DIV_CYC)    div_cnt <= 'd0;  else     div_cnt=div_cnt+1'b1;//发送数据时钟,分频计数器时钟不允许做寄存器触发时钟,也就是不能卸载always块的触发列表中always @ (posedge sclk or negedge rst_n)  if(rst_n==1'b0)    clk_p<=1'b0;  else if(div_cnt==H_DIV_CYC)      clk_p<=  ~clk_p;assign  clk_n=~clk_p;//时钟沿alwsys @ (posedge sclk or negedge  rst_n)  if(rst_n==1'b0)    pose_flag<=1'b0;  else if(clk_p==1'b0 && div_cnt==H_DIV_CYC)    pose_flag<=1'b1;  else    pose_flag<=1'b0;//等待时间alwsys @ (posedge sclk or negedge  rst_n)  if(rst_n==1'b0)    wait_cnt<='d0;  else if(state==WAIT &&pose_flag==1'b1)    wait_cnt<=wait_cnt+1;  else if(state !=WAIT)    wait_cnt<=4'd0;//shift移出数据alwsys @ (posedge sclk or negedge  rst_n)  if(rst_n==1'b0)    shift_cnt<='d0;  else if(state==W_REG && pose_flag==1'b1)    shift_cnt=shift_cnt+1'b1;  else if(state != W_REG)    shift_cnt<=4'd0;//读mem的地址产生always@(posedge sclk or negedge rst_n)  if(rst_n==1'b0)    r_addr<='d0;  else if(stete=R_MEM)    r_addr<=r_addr+1'b1;assign wren=1'b0;always@(posedge sclk or negedge rst_n)  if(rst_n==1'b0)    shift_buf<='d0;  else if(state==R_MEM)    shift_buf<=r_data;    else if(state==W_REG && pose_flag==1'b1)    shift_buf<=(shift_buf[14:0],1'b1);//data_end 最后一个需要移位的数据always@(posedge sclk or negedge rst_n)  if(rst_n==1'b0)    data_end<=1'b0;  else if(state==R_MEM && (&r_addr) ==1'b1)//等效于r_addr==5'd31    data_end<=1'b1;//数据输出always @ (posedge sclk or negedge rst_n)  if(rst_n==1'b0)    sdi<=1'b0;  else if(state==W_REG)    sdi<=shift_buf[15];  else if(state!=W_REG)    sdi<=1'b0;//使能信号always @ (posedge sclk or negedge rst_n)  if(rst_n==1'b0)    csn<=1'b0;  else if(state==W_REG)    csn<=1'b0;  else    csn<=1'b1;//时钟always @ (posedge sclk or negedge rst_n)  if(rst_n==1'b0)    tck<=1'b0;  else if(state<=W_REG)    tck<=clk_n;  else    tck<=1'b0;assign  spi_clk=tck;assign  spi_csn=csn;assign  spi_sdi=sdi;//fms   always@(posedge sclk or negedge rst_n)  if(rst_n==1'b0)    state<=IDLE;  else case (state)    IDLE:if(work_en==1'b1)      state<=WAIT;    WAIT:if(wait_cnt[3]=1'b1)      state<=R_MEM;    R_MEM:state<=W_REG;    W_REG:if(shift_cnt==4'd15&& pose_flag==1'b1&&data_end!=1'b1)          state<=WAIT;      else if (shift_cnt==4'd15&&pose_flag==1'b1&&data_end==1'b1)          state<STOP;    STOP:    state<=STOP;    default:  state<=IDLE;  endcase//输出标志,级联使用always @ (posedge sclk or negedge rst_n)  if(rst_n==1'b0)    conf_end<=1'b0;  else if(state==STOP)    conf_end<=1'b1;//例化语句endmodule//时钟skew时钟的相位偏差度,时钟偏斜

    测试代码

      `timescale  1ns/1ns  module  tb_ex_spi;  reg  sclk;  reg  rat_n;  reg  work_en;initial  begin  rst_n=0;  sclk=0;  #100;  rst_n=1;endinitial begin  work_en=0;  #150  work_en=1;endalways #10 sclk=~sclk;spi_ctrl  spi_ctrl_inst(  .sclk   (sclk);  .rst_n  (rst_n);  .work_en   (work_en);  .conf_end   ();  .spi_clk   ();  .spi_sdi   ();  .spi_csn   ();  .spi_sdo   (););endmodule
      来源:集成电路小刚
      通信SCL
      著作权归作者所有,欢迎分享,未经许可,不得转载
      首次发布时间:2023-06-27
      最近编辑:10月前
      集成电路小刚
      硕士 立志成为集成电路领域专家
      获赞 3粉丝 31文章 69课程 0
      点赞
      收藏
      未登录
      还没有评论

      课程
      培训
      服务
      行家

      VIP会员 学习 福利任务 兑换礼品
      下载APP
      联系我们
      帮助与反馈