在一个函数中调用不同的CAN控制器?

时间:2019-01-27 19:13:43

标签: c

我的第一个问题在这里。我根本不是专业程序员。只是为了在家里玩,所以我真的不知道我要问的正确术语。

我想创建一个CAN总线网关,并且拥有NXP DEVKIT-MPC5748G。所有的CAN总线都已设置并在TX和Rx上正常工作。现在,我想创建一个用于操纵不同CAN控制器的函数。它们中有8个,因此我希望不要只使用具有不同的CAN控制器而编写8个相等的函数。

您可以这样设置控制器:

CAN_1.CTRL1.B.CLKSRC = 0;

仅是设置时钟源的示例。

CAN_1具有这样的宏:

#define CAN_1 (*(volatile struct CAN_1_7_tag *) 0xFBEC0000UL)

在该结构中,有很多联合可以访问所有寄存器。现在,我想编写一个函数,该函数可以传递参数来告诉要使用的CAN控制器。我可以使用开关/案例样式的方式来执行此操作,但是该代码将很长而且很丑。

我想做这样的事情:

void Tx_Msg("type???" gwport, int mb, uint32_t id) {
    gwport.[mb].CS.B.CODE = 0x8; }

但是我不知道该怎么做。能做到吗?

感谢您在正确方向上提供的所有帮助。 :)

最诚挚的问候,约阿基姆

编辑以澄清

CAN_1_7_tag结构:

struct CAN_1_7_tag { 
  CAN_MCR_tag MCR;                     /* Module Configuration Register */
  CAN_CTRL1_tag CTRL1;                 /* Control 1 register */
  CAN_TIMER_tag TIMER;                 /* Free Running Timer */
  uint8_t CAN_reserved0[4];
  CAN_RXMGMASK_tag RXMGMASK;           /* Rx Mailboxes Global Mask Register */
  CAN_RX14MASK_tag RX14MASK;           /* Rx 14 Mask register */
  CAN_RX15MASK_tag RX15MASK;           /* Rx 15 Mask register */
  CAN_ECR_tag ECR;                     /* Error Counter */
  CAN_ESR1_tag ESR1;                   /* Error and Status 1 register */
  CAN_IMASK2_tag IMASK2;               /* Interrupt Masks 2 register */
  CAN_IMASK1_tag IMASK1;               /* Interrupt Masks 1 register */
  CAN_IFLAG2_tag IFLAG2;               /* Interrupt Flags 2 register */
  CAN_IFLAG1_tag IFLAG1;               /* Interrupt Flags 1 register */
  CAN_CTRL2_tag CTRL2;                 /* Control 2 register */
  CAN_ESR2_tag ESR2;                   /* Error and Status 2 register */
  uint8_t CAN_reserved1[8];
  CAN_CRCR_tag CRCR;                   /* CRC Register */
  CAN_RXFGMASK_tag RXFGMASK;           /* Rx FIFO Global Mask register */
  CAN_RXFIR_tag RXFIR;                 /* Rx FIFO Information Register */
  CAN_CBT_tag CBT;                     /* CAN Bit Timing Register */
  uint8_t CAN_reserved2[24];
  CAN_IMASK3_tag IMASK3;               /* Interrupt Masks 3 Register */
  uint8_t CAN_reserved3[4];
  CAN_IFLAG3_tag IFLAG3;               /* Interrupt Flags 3 Register */
  uint8_t CAN_reserved4[8];
  CAN_MB_tag MB[64];
  uint8_t CAN_reserved5[1024];
  CAN_RXIMR_tag RXIMR[96];             /* Rx Individual Mask Registers */
  uint8_t CAN_reserved6[512];
  CAN_FDCTRL_tag FDCTRL;               /* CAN FD Control Register */
  CAN_FDCBT_tag FDCBT;                 /* CAN FD Bit Timing Register */
  CAN_FDCRC_tag FDCRC;                 /* CAN FD CRC Register */
};

MCR寄存器示例。所有寄存器的工作方式都相同。

typedef union CAN_MCR_union_tag {      /* Module Configuration Register */
  vuint32_t R;
  struct {
    vuint32_t MDIS:1;                  /* Module Disable */
    vuint32_t FRZ:1;                   /* Freeze Enable */
    vuint32_t RFEN:1;                  /* Rx FIFO Enable */
    vuint32_t HALT:1;                  /* Halt FlexCAN */
    vuint32_t NOTRDY:1;                /* FlexCAN Not Ready */
    vuint32_t WAKMSK:1;                /* Wake Up Interrupt Mask */
    vuint32_t SOFTRST:1;               /* Soft Reset */
    vuint32_t FRZACK:1;                /* Freeze Mode Acknowledge */
    vuint32_t SUPV:1;                  /* Supervisor Mode */
    vuint32_t SLFWAK:1;                /* Self Wake Up */
    vuint32_t WRNEN:1;                 /* Warning Interrupt Enable */
    vuint32_t LPMACK:1;                /* Low-Power Mode Acknowledge */
    vuint32_t WAKSRC:1;                /* Wake Up Source */
    vuint32_t _unused_18:1;
    vuint32_t SRXDIS:1;                /* Self Reception Disable */
    vuint32_t IRMQ:1;                  /* Individual Rx Masking And Queue Enable */
    vuint32_t DMA:1;                   /* DMA Enable */
    vuint32_t _unused_14:1;
    vuint32_t LPRIOEN:1;               /* Local Priority Enable */
    vuint32_t AEN:1;                   /* Abort Enable */
    vuint32_t FDEN:1;                  /* CAN FD operation enable */
    vuint32_t _unused_10:1;
    vuint32_t IDAM:2;                  /* ID Acceptance Mode */
    vuint32_t _unused_7:1;
    vuint32_t MAXMB:7;                 /* Number Of The Last Message Buffer */
  } B;
} CAN_MCR_tag;

希望这就是您要的。

2 个答案:

答案 0 :(得分:0)

如果CAN_1定义为:

#define CAN_1 (*(volatile struct CAN_1_7_tag *) 0xFBEC0000UL)

然后,CAN_1是CAN_1_7_tag类型的结构,位于0xFBEC0000UL。 volatile限定符在此向编译器指示不应优化与CAN_1相关的任何东西,因为它可能被其他线程更改。

您可以将CAN控制器作为指针传递:

void Tx_Msg(volatile struct CAN_1_7_tag *p_gwport, int mb, uint32_t id)
{
    p_gwport->CTRL1.B.CLKSRC = 0;
    p_gwport->MB[mb].CS.B.CODE = 0x8;
}

然后,当调用此函数从特定的CAN控制器发送消息时,可以使用:

Tx_Msg(&CAN_1, 12, 25);
Tx_Msg(&CAN_4, 21, 45);

答案 1 :(得分:0)

再次感谢您的帮助。 CAN网关已启动并作为原型运行。 这是我的“最终”代码。

"filter" : {
    "script" : {
        "script" : "doc['score'].values.length > 10"
    }
}