概述
ARINC1977年7月,美国航空电子工程委员会提出了429总线协议,规定了航空电子设备与相关系统之间的数字信息传输要求。ARINC429广泛应用于先进的民航客机,如B-737、B757、B-俄罗斯军用飞机也选择了类似的技术。我们对应的标准是HB6096-SZ-01。ARINC总线结构简单,性能稳定,抗干扰性强。最大的优势在于可靠性高,这是由于非集中控制、传输可靠、错误隔离性好。
HI-3582是HOLT公司研发的ARINC429协议收发器可以ARINC429协议串行数据分析后,转换为16位并行数据,支持两个接收和一路发送,每个接收器都有标签识别和32×32 FIFO模拟线路接收机,每个接收器最多可编程16个标签。独立发射机有32个 X 32 FIFO内置线路驱动器。独立发射机有一个32 X 32 FIFO内置线路驱动器。FIFO可使用外部状态引脚或轮询HI-3582/HI-监控3583状态寄存器。其它新功能包括32位数据或奇偶校验的可编程选项,以及解读32位数字的能力。
硬件调试
HI-3582硬件比较简单,需要3582电源.3V和±10V供电,其中±10V用来产生ARINC429通信差分信号。时钟选用1MHz提供外部晶振。HI-3582管脚较多,除了16位并行数据总线接口外,还有许多控制和个管脚都需要使用。选择符合基本通信功能的管脚进行连接。主控芯片这里选择的是STM32F407单片机驱动HI-连接3582芯片时,16位数据总线数据总线STM32单片机的一个Port这样可以方便地读写数据,有利于软件开发,提高通信效率。
另外ARINC通信接口连接与429RS422总线类似,TX和RX信号交叉连接,正接正,负接负。
软件调试
初始化配置
HI-控制寄存器和状态寄存器的3582寄存器。
- 配置芯片的工作方式是控制寄存器
- 状态寄存器用于查询芯片的工作状态,也可以通过外部管脚查询
共有16个控制寄存器CR0~CR15.设备的通信速率、通信格式和数据识别功能可以设置。本实验使用100Kbps通信速率,然后通信数据第32位选择奇怪的校准位置,不使用LABEL识别和SDI比较功能。
控制寄存器配置
从上面的时序图可以看出,通过给予CWSTR低电平脉冲管脚可以通过数据总线写入控制寄存器数据。然后可以得到以下代码。
/* * 设置控制寄存器函数 */ static void ctrlRegConfig(uint16_t value) { HalGPIOPortConfig(HAL_HI3582_DB_PORT, HAL_IO_OUTPUT); ///设置数据总线的输出方向 HalGPIOSetLevel(HAL_HI3582_PIN_CWSTR, 1); //先拉高CWSTR HalGPIOPortSetLevel(HAL_HI3582_DB_PORT, value); /// HalGPIOSetLevel(HAL_HI3582_PIN_CWSTR, 0); //CWSTR管脚给低电平 delay100NS(); delay100NS(); //≥100NS 数据有效 HalGPIOSetLevel(HAL_HI3582_PIN_CWSTR, 1); delay100NS(); //≥40NS 保持 }
我们可以根据之前的初始配置描述和设置函数来实现HI-3582的初始化。 为了更直观、更方便地配置参数,我们首先定义了寄存器的变量格式,我们选择了联合体和结构体的组合。如下所示:
#pragma pack(1) typedef struct { int cr0_recv1clk : 1; int cr1_labelRW : 1; int cr2_enableLabelRx1 : 1; int cr3_enableLabelRx2 : 1; int cr4_32ndBitParity : 1; int cr5_selfTest : 1; int cr6_recv1Decoder : 1; int cr7 : 1; int cr8 : 1; int cr9_recv2Decoder : 1; int cr10 : 1; int cr11 : 1; int cr12_txParity : 1; int cr13_txclk : 1; int cr14_recv2clk : 1; int cr15_dataFormat : 1; } Hi3582CtrlReg_t; #pragma pack() typedef union { unsigned short value; Hi3582CtrlReg_t ctrlReg; } Hi3582CtrlRegConfig_t;
这样使用起来更方便,不用单独去找哪一位对应哪个寄存器了,代码维护起来也清晰。初始化代码如下:
void hi3582Init(void) { Hi3582CtrlRegConfig_t cfg; cfg.ctrlReg.cr0_recv1clk = 0; //recv1 100kbps cfg.ctrlReg.cr1_labelRW = 0; //normal cfg.ctrlReg.cr2_enableLabelRx1 = 0; //Disable label recognition cfg.ctrlReg.cr3_enableLabelRx2 = 0; cfg.ctrlReg.cr4_32ndBitParity = 1; //32nd bit is parity cfg.ctrlReg.cr5_selfTest = 1; //FIXME:self test 0=test, 1=normal cfg.ctrlReg.cr6_recv1Decoder = 0; //rx1 decoder disabled cfg.ctrlReg.cr7 = 0; cfg.ctrlReg.cr8 = 0; cfg.ctrlReg.cr9_recv2Decoder = 0; cfg.ctrlReg.cr10 = 0; cfg.ctrlReg.cr11 = 0; cfg.ctrlReg.cr12_txParity = 0; //odd parity cfg.ctrlReg.cr13_txclk = 0; //tx 100kbps cfg.ctrlReg.cr14_recv2clk = 0; //recv2 100kbps cfg.ctrlReg.cr15_dataFormat = 1; //Unscramble data ctrlRegConfig(cfg.value); }
接收数据
根据时序图,我们可以知道芯片在收到有效数据时D/Rx管脚会降低,所以我们只需要监控管脚,知道是否可以读取数据。然后根据具体的时间顺序控制从总线读取有效数据。由于总线为16位,数据需要读取两次。
/* * 读取数据 * @chnl: 通道号,1=接收通道1, 2=接收通道2 */ static uint32_t readDataBus(uint8_t chnl) { uint16_t byte1, byte2; uint32_t value; uint8_t enpin = (chnl == 1 ? HAL_HI3582_PIN_EN1 : HAL_HI3582_PIN_EN2); HalGPIOSetLevel(HAL_HI3582_PIN_EN1, 1); HalGPIOPortConfig(HAL_HI3582_DB_PORT, HAL_IO_INPUT); __nop(); __nop(); /*read byte 1*/ HalGPIOSetLevel(HAL_HI3582_PIN_SEL, 0); delay60NS();//>10ns HalGPIOSetLevel(enpin, 0); delay100NS(); delay100NS(); delay100NS(); delay100NS(); //max 235ns byte1 = HalGPIOPortGetLevel(HAL_HI3582_DB_PORT); HalGPIOSetLevel(enpin, 1); /*read byte 2*/ delay60NS();//>10ns HalGPIOSetLevel(HAL_HI3582_PIN_SEL, 1); delay100NS(); HalGPIOSetLevel(enpin, 0); delay100NS(); delay100NS(); delay10NS();
delay100NS(); //max 235ns
byte2 = HalGPIOPortGetLevel(HAL_HI3582_DB_PORT);
HalGPIOSetLevel(enpin, 1);
delay500NS(); // max 520ns
delay60NS();
value = byte2;
value = (value << 16) + byte1;
return value;
}
发送数据
同样根据发送数据的时序图可以得出,发送函数
static void writeDataBus(uint32_t value)
{
uint16_t data1, data2;
HalGPIOPortConfig(HAL_HI3582_DB_PORT, HAL_IO_OUTPUT);
data1 = (uint16_t)value;
data2 = (uint16_t)(value >> 16);
HalGPIOSetLevel(HAL_HI3582_PIN_ENTX, 0);
HalGPIOPortSetLevel(HAL_HI3582_DB_PORT, data1);
HalGPIOSetLevel(HAL_HI3582_PIN_PL1, 0);
delay100NS();
delay100NS(); //>120ns
HalGPIOSetLevel(HAL_HI3582_PIN_PL1, 1);
delay100NS(); //hold time >70ns
delay100NS(); //hold + tpl2 en > 110
HalGPIOPortSetLevel(HAL_HI3582_DB_PORT, data2);
HalGPIOSetLevel(HAL_HI3582_PIN_PL2, 0);
delay100NS();
delay100NS(); //>120ns
HalGPIOSetLevel(HAL_HI3582_PIN_PL2, 1);
delay100NS(); //hold time >70ns
HalGPIOSetLevel(HAL_HI3582_PIN_ENTX, 1);
}
总结
总的来说,HI-3582是一款性价比较高的ARINC429总线收发器,使用过程中也比较稳定。缺点是并行总线需要用到主控芯片更多的管脚,而且通信协议都是自定义的时序,不是标准的总线协议会增加开发难度。