在一个功能中调用不同的CAN控制器?

问题描述 投票:0回答:2

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

我想创建一个CAN总线网关,我有NXP DEVKIT-MPC5748G。所有CAN总线都设置好并适用于tx和rx。现在我想创建一个操作不同CAN控制器的功能。其中8个,所以我希望不要写8个相同的功能只有使用CAN控制器不同。

您可以像这样设置控制器:

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; }

但我无法弄清楚如何做到这一点。可以吗?

感谢正确方向的所有帮助。 :)

最好的问候,Joakim

编辑澄清

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;

希望这是你要求的。

c
2个回答
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);

0
投票

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

/********************************************************************************/
/* Tx function for FlexCAN 1-7                                                  */
/********************************************************************************/
void Tx_Msg_1_7(volatile struct CAN_1_7_tag *port, uint32_t mb, uint32_t dlc, uint32_t id, uint8_t txData[])
{
    int i = 0;                      // Used in for loops

    port->MB[mb].CS.B.CODE = 0x8;   // MB TX inactive
    port->MB[mb].CS.B.DLC = dlc;    // Message length max 8 bytes
    port->MB[mb].CS.B.RTR = 0;      // Remote frame disable
    port->MB[mb].CS.B.SRR = 1;      // Not used with standard id

    if (id > 0x7FF) // CAN id 29 bits
    {
        port->MB[mb].CS.B.IDE = 1;                      // EXT CAN id
        port->MB[mb].ID.B.ID_STD = id >> 18 & 0x7FF;    // CAN id (11 bits)
        port->MB[mb].ID.B.ID_EXT = id & 0x3FFFF;        // CAN id (18 bits)
    }
    else            // CAN id 11 bits
    {
        port->MB[mb].CS.B.IDE = 0;      // STD CAN id
        port->MB[mb].ID.B.ID_STD = id;  // CAN id (11 bits)
        port->MB[mb].ID.B.ID_EXT = 0;   // CAN id (18 bits), always 0
    }

    for(i = 0; i < dlc; i++)
    {
        port->MB[mb].DATA.B[i] = txData[i];
    }

    port->MB[mb].CS.B.CODE = 0xC;         // MB once transmit data
}
© www.soinside.com 2019 - 2024. All rights reserved.