NXP MCU 技术论坛
直播中

席毖庸

8年用户 1055经验值
擅长:596874
私信 关注
[问答]

LCP54628 MCAN如何配置?

有人可以帮我配置 CAN 协议吗?
在这个项目中,我使用 OM13098 开发板和 LPC54628 微控制器,我正在使用 MCUXpressoIDE v11.6.0 和 SDK 版本 2.12。
我看到并编译了 SDK 中的示例,但我认为这些示例有些奇怪。
我正在尝试使用 CAN 协议进行环回测试,但以下示例代码 (lpcxpresso54628_mcan_loopback) 可以在 CAN0_RD (RX) 和 CAN0_TD (TX) 之间没有物理连接的情况下执行此环回。这样,对一个实际应用程序没有用。这是正确的?

我希望开发一个示例代码,其中 CAN0 通过中断工作,并且只在我将 RX 与 TX 物理连接时工作,就像在串行通信中一样。
以后打算用CAN1开发master CAN,用CAN0开发slave CAN。
下面是我正在使用并试图揭开这个谜团的示例代码。如果有人可以帮助我,请联系我好吗?

回帖(1)

飘逸的D

2024-1-17 15:59:37
首先,您需要在 MCUXpresso IDE 中创建一个 CAN 项目。根据您的开发板和微控制器型号,选择相应的 SDK 和驱动程序支持包。您需要确保正确设置时钟和引脚。

在代码中,您需要配置 CAN 控制器的位速率、数据位数等。如果您想使用中断而不是轮询来处理接收的数据,您需要启用相应的中断标志,并创建一个中断处理程序。以下是一个示例:

``` c
#define EXAMPLE_CAN CAN0
#define RX_MESSAGE_BUFFER_NUM (1)
#define TX_MESSAGE_BUFFER_NUM (2)

volatile bool txComplete = false;
volatile bool rxComplete = false;
volatile bool isError = false;

void CAN0_IRQ0_IRQHandler(void)
{
    uint32_t status = CAN_GetStatusFlag(EXAMPLE_CAN);

    if (status & CAN_IR_RF0N_MASK)
    {
        can_message_t rxMsg;
        uint8_t rxFrame[8];

        /* Handle received message */
        if (CAN_ReadRxMb(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &rxMsg, rxFrame) == kStatus_Success)
        {
            /* Process received message */
            rxComplete = true;
        }
        else
        {
            isError = true;
        }

        /* Clear flag */
        CAN_ClearStatusFlag(EXAMPLE_CAN, CAN_IR_RF0N_MASK);
    }

    if (status & CAN_IR_TC_MASK)
    {
        /* Handle transmission complete */
        txComplete = true;

        /* Clear flag */
        CAN_ClearStatusFlag(EXAMPLE_CAN, CAN_IR_TC_MASK);
    }

    /* Handle other interrupt flags if needed */
}

void CAN_Init(void)
{
    can_general_config_t canGeneralConfig;
    can_message_buffer_config_t messageBufferConfig;

    /* Initialize CAN */
    CAN_GetDefaultConfig(&canGeneralConfig);
    canGeneralConfig.enableLoopBack = true;
    CAN_Init(EXAMPLE_CAN, &canGeneralConfig, CLOCK_GetFreq(kCLOCK_Flexcomm0));

    /* Configure message buffer */
    CAN_SetRxMsgBuff(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &messageBufferConfig);
    CAN_SetTxMsgBuff(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, &messageBufferConfig);

    /* Enable interrupts */
    CAN_EnableInterrupts(EXAMPLE_CAN, CAN_IE_RF0NE_MASK | CAN_IE_TC_MASK | /* Other interrupt flags if needed */);
    NVIC_SetPriority(CAN0_IRQn, 2);  /* Set priority */
    EnableIRQ(CAN0_IRQn);
}

void CAN_Send(void)
{
    can_message_t txMsg;
    uint8_t txFrame[8] = {0};

    /* Fill in transmission message */
    txMsg.id = 0x123;
    txMsg.format = kCAN_FrameFormatStandard;
    txMsg.type = kCAN_FrameTypeData;
    txMsg.len = 8;
    txMsg.data = txFrame;

    /* Send message */
    if (CAN_WriteTxMb(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, &txMsg) == kStatus_Success)
    {
        /* Wait for transmission to complete */
        while (!txComplete)
        {
            // Wait for the flag to be set
        }

        txComplete = false;
    }
    else
    {
        isError = true;
    }
}

void CAN_Receive(void)
{
    can_message_t rxMsg;
    uint8_t rxFrame[8];

    /* Read received message */
    if (CAN_ReadRxMb(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &rxMsg, rxFrame) == kStatus_Success)
    {
        /* Process received message */
        rxComplete = true;
    }
    else
    {
        isError = true;
    }
}

int main(void)
{
    /* Initialize CAN */
    CAN_Init();

    /* Send and receive messages */
    while (1)
    {
        CAN_Send();

        while (!rxComplete)
        {
            // Wait for a message to be received
        }

        CAN_Receive();

        /* Check for errors */
        if (isError)
        {
            // Handle error
            isError = false;
        }

        /* Reset flags */
        rxComplete = false;
    }
}
```

请注意,此示例使用轮询来等待接收到的数据,直到中断发生。如果您想在中断中处理数据,您可以将轮询代码部分移动到中断处理程序中。此外,此示例使用循环发送和接收消息,因此不需要将 TX 和 RX 物理连接。要测试物理连接,请将 CAN 接收器连接到 CAN 发射器,并尝试发送和接收消息。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分