FPGA 429 接口设计

429通信 FPGA接口设计

429总线协议标准规定了航空电子设备及有关系统间的数字信息传输要求,ARINC429总线结构简单,性能稳定,抗干扰性强,最大优势在于可靠性高,飞机上的429数据总线,用在系统和设备之间传送上千种不同类型的参数,如航向,真空速,马赫数,高度等。

429总线单向传输,传输速度分高低速,高速模式速率是100Kb/s,低速模式速率应用在12-14.5Kb/s(本次设计低速采用12.5K),速率误差范围在1%之内,高速和低速不能在同一条传输总线上传输,数据字以双极回零脉冲形式发送,HI高电平+10v,中电平0v, 低电平-10v,字与字之间以4位0电平分开,这也作为字同步。

FPGA接口收发数据电平转换为429标准总线电气特性,可以利用光电耦合器HPCL_0631的通断实现电平转换,HPCL_0631兼容LSTTL/TTL电平协议,方便同FPGA的I/O直接交联,为保证光耦正常工作,需串联680欧电阻,硬件电路如下图一。信号转换关系图如图二所示。

图一:

图二:

 

 

429通信FPGA接口程序主要分为3部分组成:时钟产生模块,并转串数据发送模块(含奇数校验),传转并数据接收模块(不含奇数校验),各模块分别时序仿真。

1、  时钟产生模块

Clk_in 输入10Mhz时钟

Rst 模块复位信号

Select 时钟模式选择(为1产生100K 时钟输出,为0产生12.5K时钟输出)

Bclk  429时钟信号输出

图三 :时钟模块波形图

 

 

2、  并转串数据发送模块(含奇校验)

Data_in(30:0)准备发送的31位有效数据(模块内已添加奇数校验);

Bclk  100K/12.5k 429时钟输入

Clk  模块系统时钟10M

In_en 为高表示有有效数据

Reset 模块复位

Ser_outa 高电平空闲状态,低电平表示429逻辑1

Ser_outb 高电平空闲状态,低电平表示429逻辑0

图四:发送数据模块波形图

 

3、  串转并数据接收模块

Data_out(30:0)准备发送的32位有效数据(奇校验未做处理,含1位奇校验);

Bclk  100K/12.5k 429时钟输入

Clk  模块系统时钟10M

out_en 为高表示数据输出有效

Reset 模块复位

Ser_in_a 高电平空闲状态,低电平表示429逻辑1

Ser_in_b 高电平空闲状态,低电平表示429逻辑0

图五:接收模块波形图

附件源程序:

///clk_div

module clkdiv(

rst, select, clk_in, bclk

    );

   input rst;

input select;  //=1 100kbps /// =0 12.5kbps

input clk_in;      //10Mhz

output bclk;     

reg[15:0] cnt1=0;

reg bclk=0;      

wire [15:0] bps;

wire [7:0] bps_2;

assign bps=select? 50:400;

assign bps_2=bps/2;

always @(posedge clk_in or posedge rst)

begin

if(rst)

 bclk<=1'b0;  

else if(cnt1==(bps_2-1))

    begin

 bclk<=~bclk;

 cnt1<=cnt1+1;

 end

 else if (cnt1<(bps-1))

    cnt1<=cnt1+1;

else 

 cnt1<=0;

end

endmodule

 

///数据接收模块

module rx_data(

   clk,reset,bclk,ser_in_a,ser_in_b,data_out,out_en

    );

input clk;   //1-10M

input reset;

input bclk;  // 100k  12.5k

input ser_in_a;

input ser_in_b;

output reg [31:0]data_out;

output reg out_en;

 

wire ser_in_null;

wire ser_in_dat;

reg [7:0] bclk_cnt;

reg [35:0]data_buf;

 

assign ser_in_null=ser_in_a & ser_in_b;

assign ser_in_dat=(~ser_in_a) & ser_in_b;

 

 

////count 36

always @ (posedge bclk or posedge reset)

begin

  if(reset)

    bclk_cnt<=0;

 else

      begin

                bclk_cnt<=bclk_cnt+1;

                      if(bclk_cnt==35)

                       begin

                               bclk_cnt<=0;

                               out_en<=1;

                               end

                               else

                                out_en<=0;

                     end

 

end

 

// data buffer shift register

always @ (posedge bclk or posedge reset)

begin

if (reset)

           data_buf <=36'h0;

else if (~ser_in_null)

           data_buf <={ser_in_dat, data_buf[35:1]};  ///YOU YI

end

 

///data_out

always @ (posedge clk or posedge reset)

begin

if (reset)

           data_out <=32'hx;

else if (out_en)//(out_en& (data_buf[35]==~^data_buf[34:4]))

           data_out <=data_buf[35:4];  ///YOU XIAO BIT

           else

            data_out <=32'hxxx;

end

endmodule

 

///数据发送模块

 

module tx_data(

 clk,reset,bclk,ser_outa,ser_outb,data_in,in_en

    );

input clk;

input reset;

input bclk;  // 100k  12.5k

output ser_outa;

output ser_outb;

input [30:0]data_in;

input in_en;

 

reg ser_outa,ser_outb;

wire even_odd;

reg  [35:0]data_buff;

wire [35:0]data_buf;

reg [7:0] bit_count=0;

reg tx_busy;

 

assign data_buf[31]=in_en? ~^data_in:0; //ji odd

assign data_buf[35:32]=0;

assign data_buf[30:0]=in_en ? data_in:0;

 

// output bit counter

always @ (posedge bclk or posedge reset)

begin

if (reset)

           bit_count <=8'h0;

else if (in_en)

   begin

           bit_count <=bit_count + 8'h1;

           tx_busy <= 1'b1;

   if (bit_count==35)

   begin

           bit_count <=8'h0;

           tx_busy <= 1'b0;

           end

           end

end

 

 

// data shift register

 

always @ (posedge bclk or posedge reset)

begin

  

if (reset)

           data_buff <=36'b0;

else if (~tx_busy)

   data_buff<=data_buf;

else if (tx_busy)

           data_buff <={1'b0, data_buff[35:1]};

end

 

always @(posedge clk or posedge reset)

begin

if (reset)

      begin

           ser_outa <= 1'b0;

           ser_outb <= 1'b0;

           end

else if (in_en)

      begin

       if(data_buff[0]==1)

                     begin

               ser_outa <= data_buff[0]& (~bclk);

               ser_outb <=1;

                     end

      else if (data_buff[0]==0)

       begin

               ser_outa <= 1;

               ser_outb <=(~data_buff[0])& (~bclk);

                     end

              else

                begin

           ser_outa <= 1;

                ser_outb <= 1;

                      end

                    end

end

endmodule

你可能感兴趣的:(FPGA,fpga,XILINX,429)