赞
踩
ARINC429总线协议是美国航空电子工程委员会于1977年7月提出的,协议标准规定了航空电子设备及有关系统间的数字信息传输要求。ARINC429广泛应用在先进的民航客机中,如B-737、B757、B-767,俄制军用飞机也选用了类似的技术。我们与之对应的标准是HB6096-SZ-01。ARINC429总线结构简单、性能稳定,抗干扰性强。最大的优势在于可靠性高,这是由于非集中控制、传输可靠、错误隔离性好。
HI-3582是HOLT公司研发的ARINC429协议收发器,可将ARINC429协议串行数据解析后转换为16位并行数据,该芯片支持两路接收和一路发送,其中每个接收机具有标签识别、32×32 FIFO和模拟线路接收机,每个接收器最多可编程16个标签。独立发射机有一个32 X 32 FIFO和一个内置线路驱动器。所有三个FIFO的状态都可以使用外部状态引脚或通过轮询HI-3582/HI-3583状态寄存器进行监控。其他新功能包括32位数据或奇偶校验的可编程选项,以及解读32位字的能力。
HI-3582硬件相对简单一些,电源方面需要用到3.3V和±10V供电,其中±10V用来产生ARINC429通信的差分信号。时钟选用1MHz外部晶振提供。HI-3582管脚比较多,除了16位的并行数据总线接口以外,还有许多控制和标识管脚,但并非每个管脚都需要用到,选择满足基本通信功能的管脚进行连接即可。主控芯片这里选择的是STM32F407单片机来驱动HI-3582芯片,连接时16位数据总线最好顺序接到STM32单片机的某个Port上,这样可以很方便的读取和写入数据,有利于软件开发和提高通信效率。
另外ARINC429的通信接口连接和RS422总线类似,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(); delay100NS(); 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总线收发器,使用过程中也比较稳定。缺点是并行总线需要用到主控芯片更多的管脚,而且通信协议都是自定义的时序,不是标准的总线协议会增加开发难度。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。