zoukankan      html  css  js  c++  java
  • FPGA之SSI接口协议实现

         SSI(Synchronous Serial Interface,同步串行接口)是一个全双工的串行接口,允许芯片与多种串行设备通信。它是高精度绝对编码器种一种比较常见的接口方式,采用主机主动式读出方式,即在主控者发出的时钟脉冲的控制下,从最高有效位(MSB)开始同步传输数据。下面以SSI3为例,具体讲解它的接口实现方式。

    时序图

    注意事项

    1、时钟频率:100kHz至2MHz,这里取1MHz,就是1T=1us.

    2、数据发送阶段:Trc=(16+0.5)us(SSI3数据位是16位)

    3、Tmu(数据更新待阶段)=20us+/-1us;

    4、Timg(数据等待阶段)必须要大于Tmu(数据更新阶段),为了保证满足时序要求,这里Timg只要大于21us即可;

    5、一个完整工作周期=Trc(数据发送阶段)+Timg(数据等待阶段)=(16+0.5+21)us,也就是一个完整工作周期至少要>37.5us,这里为了保证满足时序需求,取到40us。

    6、当检测到Error为0(可靠数据),将数据发送阶段的16bit数据保存输出即可。

    程序设计

    设计目的:按照时序要求,FPGA输出1M的采样时钟给编码器,当error为0时,采样16bit数据输出

    1、SSI3的数据线为外部输入信号,为了避免亚稳态,需要将数据打拍消抖处理

     1  always  @(posedge clk or negedge rst_n)begin    //prevent the Metastability
     2       if(rst_n==1'b0)begin
     3           data_in_ff0<=0;
     4           data_in_ff1<=0;
     5           data_in_ff2<=0;
     6       end
     7       else begin
     8           data_in_ff0<=data_in;
     9           data_in_ff1<=data_in_ff0;
    10           data_in_ff2<=data_in_ff1;
    11       end
    12   end

     2、设计采样时钟

     1  //produce 1M clk 
     2      always @(posedge clk or negedge rst_n)begin
     3          if(!rst_n)begin
     4              cnt <= 0;
     5          end
     6          else if(add_cnt)begin
     7              if(end_cnt)
     8                  cnt <= 0;
     9              else
    10                  cnt <= cnt + 1;
    11          end
    12      end
    13 
    14      assign add_cnt = flag_begin==1  ;       
    15      assign end_cnt = add_cnt && cnt== 50-1 ;   //1us ,pruduce 1M
    16 
    17      //begin
    18      always @(posedge clk or negedge rst_n)begin
    19          if(!rst_n)begin
    20              cnt_bit <= 0;
    21          end
    22          else if(add_cnt_bit)begin
    23              if(end_cnt_bit)
    24                  cnt_bit <= 0;
    25              else
    26                  cnt_bit <= cnt_bit + 1;
    27          end
    28      end
    29 
    30      assign add_cnt_bit = end_cnt;       
    31      assign end_cnt_bit = add_cnt_bit && cnt_bit==40-1 ;    //set up 40us   
    32 
    33      assign dout_clk_high=add_cnt==1&&cnt==1-1&&cnt_bit>=2-1&&cnt_bit<=18-1;
    34      assign dout_clk_low =add_cnt==1&&cnt==25-1&&cnt_bit>=1-1&&cnt_bit<=17-1;
    35 
    36      always  @(posedge clk or negedge rst_n)begin
    37          if(rst_n==1'b0)begin
    38              dout_clk<=1;
    39          end
    40          else if(dout_clk_high==1)begin
    41              dout_clk<=1;
    42          end
    43          else if(dout_clk_low==1)begin
    44              dout_clk<=0;
    45          end
    46          
    47      end

    上板验证

     注意:未经允许,禁止转载,违法必究!

  • 相关阅读:
    CDN用户访问调度流程
    最近复习原型 终于明白了一点 写下原型相对比较完美的一种继承方式
    flex布局学习
    Vuex基本使用
    Promise的基本使用
    创建对象的几种方式
    父访问子的数据方法
    购物车案例
    插槽的使用
    ref获取DOM元素
  • 原文地址:https://www.cnblogs.com/tanqiqi/p/12667363.html
Copyright © 2011-2022 走看看