-
前言
前篇文章关于ARINC429的功能描述已经完成,链接如下:
ARINC429说明书_Eidolon_li的博客-CSDN博客
正式文章对于ARINC429的总线发送驱动说明,本文档只描述作者的思想以及仿真结果,不包括完整源码,请只需要源码的同学谨慎进入
-
描述:
本项目非使用协议芯片,ARINC429驱动皆由FPGA完成,相较于协议芯片FPGA驱动的优点在于价格便宜、协议灵活不但兼容美标12.5K和100K的速率,同样支持俄标18977(最高支持250K速率)。
-
FPGA环境
FPGA的优点就不在唠叨了,有兴趣的同学可以查一下,
序号 | 项目 | 描述 |
1 | 电脑 | Window10 |
2 | FPGA | XC6SLX9(够用) |
3 | CPLD(降低成本) | MAX V(基本上够用) |
4 | CPLD(国产CPLD) | PGC系列(有富余) |
5 | 描述语言 | Verilog |
6 | 软件(以Xilinx为例) | ISE14.7(有研究国产化的朋友可以试试PGC) |
7 | 仿真软件 | Modelsim10.6D |
注:FPGA和CPLD均可实现ARINC429的驱动,区别在于资源数量以及国产FPGA的推广(当前国产FPGA种类众多但无法与Xilinx公司产品相抗衡,特别是高端芯片上,不过目前在低端市场基本上可以替换,缺点对于官方IP核较少,但最基本的RAM、FIFO、PLL、MULT之类均有,优点在于价格优势,以及大环境下的支持。在这里为国产FPGA摇旗呐喊一下,希望尽快能代替Xilinx芯片)。
-
干货-FPGA驱动模块框图
-
干货-FPGA驱动模块接口说明
序号 | 名称 | 方向 | 位宽 | 描述 |
1 | I_sys_cLK | I | 1 | 系统输入时钟,当前时钟为16Mhz |
2 | I_rstn | I | 1 | 系统复位管脚,同步复位 |
3 | I_trans_dat32b | I | 32 | ARINC429发送数据 |
4 | I_trans_daten | I | 1 | ARINC429发送使能,以一个时钟脉冲为准 |
5 | O_dri_busy | O | 1 | 驱动模块忙状态(0:代表忙;1:代表可以应答),当前状态ARINC429发送使能若再次发送,则造成当前帧和下一帧发送失败 |
6 | O_dri_dat | O | 2 | 使用2Bit数据表示双极归零码 |
7 | O_dri_slp | O | 1 | 指示当前输出速率(12.5K或100K) |
-
干货-FPGA驱动模块详细说明
ARINC429模块输入
由于ARINC429协议可知,ARINC429数据基本分为4个部分,分别是校验、SDI、数据、LABLE组成:
- 校验:校验为奇偶校验,即其余31个数据累加得出的结果与数据传输的结果相比较,一样为正确不一样为错误,故该校验可由串口直接透传、也可使用FPGA自动计算得到。
- SDI:有串口直接透传
- 数据:有串口直接透传
- LABLE:LABLE数据与其他数据不一致,其最高位先发,最后发送抵字节
故32BIT数据组合如下:
always @(posedge I_system_clk)
if(rxdaten && rxd_dat_cnt == 3)
begin
rxd_data[31:24] <= rxdat ;
end
else
rxd_data[31:24] <= rxd_data[31:24] ;
always @(posedge I_system_clk)
if(rxdaten && rxd_dat_cnt == 4)
begin
rxd_data[23:16] <= rxdat ;
end
else
rxd_data[23:16] <= rxd_data[23:16] ;
always @(posedge I_system_clk)
if(rxdaten && rxd_dat_cnt == 5)
begin
rxd_data[15:8] <= rxdat ;
end
else
rxd_data[15:8] <= rxd_data[15:8] ;
always @(posedge I_system_clk)
if(rxdaten && rxd_dat_cnt == 6)
begin
rxd_data[7:0] <= {rxdat[0],rxdat[1],rxdat[2],rxdat[3],rxdat[4],rxdat[5],rxdat[6],rxdat[7]} ;
end
else
rxd_data[7:0] <= rxd_data[7:0] ;
always @(posedge I_system_clk)
rxd_scussed_reg <= rxd_sucess ;
always @(posedge I_system_clk)
if(rxd_scussed_reg && ~rxd_sucess)
rxd_den <= 1'b1 ;
else
rxd_den <= 1'b0 ;
reg [31:0] arinc_dat ;
always @(posedge I_system_clk)
if(~I_system_rstn)
arinc_dat <= 32'b0 ;
else if(rxd_scussed_reg && ~rxd_sucess)
arinc_dat <= rxd_data ;
else
arinc_dat <= arinc_dat ;
wire w_parity ;
assign w_parity = arinc_dat[28] + arinc_dat[27] + arinc_dat[26] + arinc_dat[25] +
arinc_dat[24] + arinc_dat[23] + arinc_dat[22] + arinc_dat[21] +
arinc_dat[20] + arinc_dat[19] + arinc_dat[18] + arinc_dat[17] +
arinc_dat[16] + arinc_dat[15] + arinc_dat[14] + arinc_dat[13] +
arinc_dat[12] + arinc_dat[11] + arinc_dat[10] + arinc_dat[9] +
arinc_dat[8] + arinc_dat[7] + arinc_dat[6] + arinc_dat[5] +
arinc_dat[4] + arinc_dat[3] + arinc_dat[2] + arinc_dat[1] +
arinc_dat[0] + r_ctrl[1] + r_ctrl[0] ;
assign O_rs232_arincrdat = r_ctrl[4] ? {r_ctrl[5],arinc_dat[28:8],r_ctrl[1:0],arinc_dat[7:0]} : {w_parity,arinc_dat[28:8],r_ctrl[1:0],arinc_dat[7:0]} ;
assign O_rs232_rden = rxd_den ;
ARINC429输出
由于ARINC429采用双极归零码,必须用2BIT才能表示这三个状态(正、零、负),故使用FPGA参数化,得到代码如下:
parameter [1:0] HIGH = 2'b01 ,
parameter [1:0] ZERO = 2'b00 ,
parameter [1:0] LOW = 2'b10
ARINC429时序控制
根据ARINC429速率(12.5K和100K)计数生成与之匹配的时序,自此程序可独立完成
-
仿真波形
12.5K速率
100K速率