ARINC429总线收发器 -- HI-3593调试记录

这篇具有很好参考价值的文章主要介绍了ARINC429总线收发器 -- HI-3593调试记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

​ HI-3593是一款ARINC429协议收发器芯片,和之前介绍的HI-3582芯片功能一样,该芯片支持两路接收和一路发送,其中每个接收机具有标签识别、32×32 FIFO和模拟线路接收机。不同的是HI-3593通信接口为SPI总线,可以减少MCU的硬件管脚负担,而且HI-3593片内集成DC/DC 转换器用于产生双极性ARINC 429差分电压以便直接驱动ARINC 429总线,就不用像HI-3582那样需要提供±10V信号,这样使电路设计更加简洁。

硬件设计

​ HI-3593硬件设计十分方便,电源方面只需要提供3.3V供电,外部提供1MHz的时钟信号。如果你像我一样不使用标签过滤器的话,除了SPI总线以外,MCU只需要使用RxINT、RxFLAG、TFULL这几个状态管脚即可。参考设计如下图:
429协议,芯片驱动,单片机,stm32,嵌入式硬件

寄存器配置

​ HI-3593通过SPI总线通信,使用的是SPI模式0,最高支持10MHz通信速率,对于ARINC429的通信速率来说已经绰绰有余了。HI-3593主要的寄存器有接收控制寄存器(0x10,0x24)、发送控制寄存器(0x08)、ACLK分频寄存器(0x38)和标志中断寄存器(0x34),基本上初始化这几个寄存器就可以正常通信了。

  • 接收控制寄存器
    429协议,芯片驱动,单片机,stm32,嵌入式硬件
    ​根据以上寄存器位的描述,很多时候需要翻转接收到的429消息的LABEL,这时RFLIP就要置1。我们不需要过滤SD9/10信息,所以SDON设置为0。PARITY为1,使能奇偶校验。LABREC、PLON为0,不使能标签过滤。RATE为0,设置为429通信速率为高速,也就是100kbps。

  • 发送控制寄存器
    429协议,芯片驱动,单片机,stm32,嵌入式硬件
    TFLIP和上面接收翻转功能一样,置1后发送时翻转Label数据。TMODE置1,只要数据有效就发送出去。SELFTEST是自测试位,置1后会内部收发自环。PARITY和RATE同上。

  • ACLK分频寄存器
    429协议,芯片驱动,单片机,stm32,嵌入式硬件
    这里使用的是1MHz外部晶振,所以DIV设置位0x00

  • 标志中断寄存器
    429协议,芯片驱动,单片机,stm32,嵌入式硬件
    可以通过RxFLAG和RxINT管脚来判断是否接收到有效数据。RxFLAG设置为0,这样FIFO内接收到有效数据后管脚会变高,当数据被完全读取后管脚又被拉低。RxINT同样设置为0,当接收到有效数据会产生一个高脉冲中断信号。RxFLAG管脚适合用轮询的方法判断FIFO是否有数据,RxINT适用于中断的方式接收数据。由于ARINC429速率并不高,所以本文采用的是轮询方式接收数据,通过查询RxFLAG管脚是否为高,来判断FIFO内是否接收到有效数据。

参考程序

本例程是结合上面寄存器配置,通过轮询的方式接收数据,寄存器初始化时采用了结构体位域的方式进行配置,这样更加方便直观的设置每一位寄存器。通信过程中发现了一个问题,就是我发送的数据和接收端接收到的数据正好高低位翻转了,现在还没找到具体原因,只能通过函数dataFlip先翻转了数据然后再发送,有知道具体原因的朋友可以留言告诉我一下。文章来源地址https://www.toymoban.com/news/detail-518468.html


#include "ARINC429.h"
#include "Hal.h"

#define ARINC_SELF_TEST 0

/*管脚定义*/
#define ARINC_TFULL_PIN  0x42
#define ARINC_TEMPTY_PIN 0x43
#define ARINC_R1FLAG_PIN 0x44
#define ARINC_R1INT_PIN  0x45
#define ARINC_R2FLAG_PIN 0x46
#define ARINC_R2INT_PIN  0x22
#define ARINC_RESET_PIN  0x47

/*Regs定义*/
#define ARINC_SEND_CTRL_WREG  0x08
#define ARINC_SEND_CTRL_RREG  0x84
#define ARINC_FIFO_DATA_REG   0x0C
#define ARINC_RECV1_CTRL_WREG 0x10
#define ARINC_RECV1_CTRL_RREG 0x94
#define ARINC_RECV2_CTRL_WREG 0x24
#define ARINC_RECV2_CTRL_RREG 0xB4
#define ARINC_INT_FLAG_WREG   0x34
#define ARINC_INT_FLAG_RREG   0xD0
#define ARINC_ACLK_DIV_WREG   0x38
#define ARINC_ACLK_DIV_RREG   0xD4
#define ARINC_FIFO_SEND_REG   0x40
#define ARINC_RECV1_FIFO_REG  0xA0
#define ARINC_RECV2_FIFO_REG  0xC0

#define ARINC_DATA_VALID(ch) (HalGPIOGetLevel(ARINC_R##ch##FLAG_PIN) == 0)

/*寄存器结构体*/
#pragma pack(1)
typedef struct
{
    int RATE  : 1;
    int PLON  : 1;
    int LABREC: 1;
    int PARITY: 1;
    int SDON  : 1;
    int SD10  : 1;
    int SD9   : 1;
    int RFLIP : 1;
}ARINCRecvCtrlReg_t;

typedef struct
{
    int RATE    : 1;
    int X       : 1;
    int TPARITY : 1;
    int ODDEVEN : 1;
    int SELFTEST: 1;
    int TMODE   : 1;
    int TFLIP   : 1;
    int HIZ     : 1;
}ARINCSendCtrlReg_t;

typedef struct 
{
    int X2   :1;
    int DIV  :4;
    int X1   :3;
}ARINCAclkDivReg_t;

typedef struct 
{
    int R1FLAG :2;
    int R1INT  :2;
    int R2FLAG :2;
    int R2INT  :2;
}ARINCINTReg_t;

typedef struct
{
    int label : 8;
    int sdi : 2;
    int data : 19;
    int ssm : 2;
    int parity : 1;
} ARINC429Data_t; 
#pragma pack()

typedef union 
{
    uint8_t val;
    ARINCRecvCtrlReg_t recvCtrl;
    ARINCSendCtrlReg_t sendCtrl;
    ARINCAclkDivReg_t aclkDiv;
    ARINCINTReg_t intFlag;
}ARINCReg_t;

typedef union
{
    uint32_t db;
    ARINC429Data_t ex;
} ARINCdataFlip_t;

static ARINC429DataRecv_cb g_recvCallback = NULL;

static uint32_t dataFlip(uint32_t data) //翻转高低字节
{
    uint32_t result = data;
#if 1
    result = (data >> 24);
    result |= (data >> 8) & 0xff00;
    result |= (data << 8) & 0xff0000;
    result |= (data << 24);
#endif	
    return result;
}

static void chipReset(void) //硬件复位
{
    HalGPIOSetLevel(ARINC_RESET_PIN, 1);
    HalWaitMs(1);
    HalGPIOSetLevel(ARINC_RESET_PIN, 0);  //reset
    HalWaitMs(1);
}

static void regsConfig(void) //寄存器初始化函数
{
    ARINCReg_t reg;

    reg.recvCtrl.RFLIP = 1; //是否翻转前八位LABEL数据
    reg.recvCtrl.SD9   = 0;
    reg.recvCtrl.SD10  = 0; 
    reg.recvCtrl.SDON  = 0; //是否匹配SD9\10两位,否
    reg.recvCtrl.PARITY = 1; //接收字的奇偶性检查启用
    reg.recvCtrl.LABREC = 0; //标签过滤关闭
    reg.recvCtrl.PLON  = 0; //优先级标签寄存器的不使能
    reg.recvCtrl.RATE  = 0; //高速数据传输速率
    HalSPIWriteReg(ARINC_RECV1_CTRL_WREG, reg.val);
    HalSPIWriteReg(ARINC_RECV2_CTRL_WREG, reg.val);

    reg.sendCtrl.HIZ = 0; //设置该位使片内线路驱动器输出进入高阻态
    reg.sendCtrl.TFLIP = 1; //是否翻转前八位LABEL数据

    reg.sendCtrl.TMODE = 1; //只要数据是有效的就会被立即发送
    reg.sendCtrl.SELFTEST = ARINC_SELF_TEST; //自测试
    reg.sendCtrl.ODDEVEN = 0; //偶校验
    reg.sendCtrl.TPARITY = 1; //使能校验位
    reg.sendCtrl.X = 0;
    reg.sendCtrl.RATE = 0; //高速数据传输速率
    HalSPIWriteReg(ARINC_SEND_CTRL_WREG, reg.val);

    reg.val = 0;
    reg.aclkDiv.DIV = 0; //1MHz
    HalSPIWriteReg(ARINC_ACLK_DIV_WREG, reg.val);

    reg.intFlag.R1FLAG = 0; //接收器1 FIFO为空时, R1FLAG变高
    reg.intFlag.R1INT  = 0; //当有效消息被接收,R1INT为高脉冲
    reg.intFlag.R2FLAG = 0;
    reg.intFlag.R2INT  = 0;
    HalSPIWriteReg(ARINC_INT_FLAG_WREG, reg.val);
}

static uint32_t readData(uint8_t chnl) //读通道数据
{
    uint8_t reg;
    uint32_t data;
    if(chnl == 1)
    {
        reg = ARINC_RECV1_FIFO_REG;
    }
    else
    {
        reg = ARINC_RECV2_FIFO_REG;
    }
    
    HalSPIRead(reg, (uint8_t *)&data, sizeof(uint32_t));
    
    return dataFlip(data);
}

/*发送数据*/
void ARINC429Send(unsigned char label, unsigned int value, unsigned char ssm)
{
    ARINCdataFlip_t data;
    uint32_t num;

    memset(&data, 0, sizeof(ARINCdataFlip_t));
    data.ex.label = label;
    data.ex.data = value;
    data.ex.ssm = ssm;
    data.ex.sdi = 0;
    
    num = dataFlip(data.db);
    HalSPIWrite(ARINC_FIFO_DATA_REG, (uint8_t *)&num, sizeof(uint32_t));
}

static void dataRecvHandle(void)
{
    ARINCdataFlip_t data;
    if(ARINC_DATA_VALID(1)) //通过RxFLAG管脚判断是否接收到有效数据
    {
        data.db = readData(1); //读通道1数据
        if(g_recvCallback != NULL)
        {
            g_recvCallback(data.ex.label, data.ex.data, data.ex.ssm);
        }
    }

    if(ARINC_DATA_VALID(2))
    {
        data.db = readData(2);
        if(g_recvCallback != NULL)
        {
            g_recvCallback(data.ex.label, data.ex.data, data.ex.ssm);
        }
    }
}

/*初始化*/
void ARINC429Init(ARINC429DataRecv_cb recvHandle)
{
    chipReset();
    regsConfig();
    g_recvCallback = recvHandle;
}

void ARINC429Poll(void)
{
    dataRecvHandle(); //轮询接收
}


到了这里,关于ARINC429总线收发器 -- HI-3593调试记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • GT高速收发器

    GT高速收发器概述 10G以太网子系统通过AXI4-Stream接口提供10gb /s以太网MAC、物理编码子层(PCS)和物理介质附件(PMA)传输和接收功能。该子系统还提供了可选的高精度时间戳功能,兼容IEEE Std 1588-2008(也称为IEEE1588v2)。这适用于10GBASE-R标准。10G以太网MAC子系统框图如图所示。 Xilinx

    2024年02月05日
    浏览(44)
  • AD9361收发器中文手册

    因最近公司需要,借此机会和大家一起学习AD9361 制作不易,记得三连哦,给我动力,持续更新! 工程文件下载: 纯硬件SPI配置AD9361    提取码:g9jy ----------------------------------------------------------------------------------------         接收RF信号,并将其转换成可供BBP使用的数字数据

    2023年04月19日
    浏览(48)
  • CAN收发器与CAN控制器

    CAN收发器是一种用于CAN总线通信的专用芯片,主要用于将CAN控制器和CAN总线物理层之间的信号进行转换和调节。它的主要作用是将CAN控制器输出的数字信号转换为CAN总线所需要的物理信号,同时将CAN总线上接收到的物理信号转换为数字信号,并将其传递给CAN控制器进行处理。

    2024年01月24日
    浏览(50)
  • 缓冲器/驱动器/收发器IC

    记录学习未使用过的IC,开发使用新的IC,哎,就是玩 本编文章主要介绍缓冲器/驱动器/收发器 FPGA或MCU低驱动能力引脚 单向长距离信号 1.SN74HCT245NSR DIR高电平,A到B可控制,B到A不可控制 DIR低电平,B到A可控制,A到B不可控制 OE高电平,所有通道端口高阻 OE低电平,所有通道端

    2024年02月09日
    浏览(50)
  • 基于vivado+Verilog FPGA开发 — GT收发器

    代码规范:Verilog 代码规范_verilog代码编写规范-CSDN博客 开发流程:FPGA基础知识----第二章 FPGA 开发流程_fpga 一个项目的整个流程-CSDN博客   源码下载:GitHub - Redamancy785/FPGA-Learning-Record: 项目博客:https://blog.csdn.net/weixin_51460407 零、低速通信接口的缺陷 1、同步通信要求传输数据

    2024年04月17日
    浏览(64)
  • “GT/Serdes/高速收发器”相关的FPGA调研

    根据FPGA使用的要点,GT/Serdes/高速收发器这样的,进行检索,及FPGA的接口培训信息,整理成表如下: 序号 一级搜集 二级搜集 引申 1 知乎ID FPGA个人练习生 FPGA实现图像去雾 基于暗通道先验算法 纯verilog代码加速 提供2套工程源码和技术支持 没玩过GT资源都不好意思说自

    2024年02月08日
    浏览(43)
  • FPGA的高速收发器(GTX/GTY/GTP)的快速上手教程

            工作中有对GT收发器的使用需求, 学习的过程中,看手册,看别人的文章。有些大佬写得非常好,但他们可能不是针对使用来写的,我在实际使用IP核的过程中,还是会有很多疑惑。         所以我就针对怎么使用GTX等IP核写的这几篇文章,希望可以帮助到想快速学

    2024年04月15日
    浏览(57)
  • rtl8221b+mcu,2.5g光纤收发器的开发备份

    1、rtl8221b是一款2.5g的光电转换的phy 系统的构建如下 为了省成本,不用mac来对接其中的gmii接口直接接光模块 2、mdio和mdc由mcu的gpio来模拟,在csdn上有很多的文章来参考 mdio的参数如下 不想看英文可以参考下面的文章 MDIO(clause 22 与 clause 45)接口简介以及FPGA Verilog 实现_Angry Noob的

    2024年02月12日
    浏览(44)
  • FPGA-结合协议时序实现UART收发器(一):UART协议、架构规划、框图

    记录FPGA的UART学习笔记,以及一些细节处理,主要参考奇哥fpga学习资料。 本次UART主要采用计数器方法实现,实现uart的稳定性发送和接收功能,最后实现串口数据回环进行功能测试。 UART协议如图。 包含:空闲位、起始位、数据位、校验位、停止位、空闲位(一般没有) 对于

    2024年02月08日
    浏览(67)
  • 赛灵思7系列FPGA GT收发器中的RX均衡器

            串行信号经过传输媒介时,必然伴随着衰减或者扭曲。为了减少信号衰减带来的串行误码率,并且兼顾功耗与性能,GT收发器提供了两种信号改善方法:一种是LPM模式(low-power mode),另一种是DFE模式(判决反馈均衡器 Decision Feedback Equalizer )。         DFE模式

    2024年02月03日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包