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
上板验证
来源:oschina
链接:https://my.oschina.net/u/4306876/blog/4273255