• 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

    上板验证

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

  • 相关阅读:
    make menuconfig出错需要安装文件
    编译内核,配置内核make menuconfig
    busbox编译出错,arm-linux-未找到命令
    screen命令
    Shell系列
    ExtJS清除表格缓存
    ExtJS发送POST请求 参数格式为JSON
    ExtJS实现分页grid paging
    ExtJS错误解决 Cannot read property 'on' of undefined
    解决com.mongodb.MongoException$CursorNotFound: cursor 0 not found on server
  • 原文地址:https://www.cnblogs.com/tanqiqi/p/12667363.html
Copyright © 2020-2023  润新知