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

 

上板验证

 

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

 

 

posted @ 2020-04-09 16:22  谭渣渣  阅读(4084)  评论(22编辑  收藏  举报