sujingliang · 1 天前

【Mini-F5375-OB开发板评测】3、CAN实验

目的:熟悉MM32 CAN的实现方式,通过loopback模式演示收发是否符合预期。

实验基于以下面例程为模板修改完成:
LibSamples_MM32F5370_V0.10.3\Samples\LibSamples\FlexCAN\FlexCAN_Interrupt

还是以loopback模式进行CAN实验,loopback的好处是自发自收可以方便的验证CAN模块的可用性。

一、CAN引脚的修改

例程中的CAN收发引脚为:PD8(CAN1_RX),PD9(CAN1_TX)

而Mini-F5375-OB原理图上可以看到,开发板上引脚为PI1(CAN1_RX),PI0(CAN1_TX)
image.png

复用为FA9
image.png

因此FlexCAN_Configure函数中引脚初始化部分改为:

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOI, ENABLE);
    GPIO_PinAFConfig(GPIOI, GPIO_PinSource0, GPIO_AF_9);
    GPIO_PinAFConfig(GPIOI, GPIO_PinSource1, GPIO_AF_9);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_FLOATING;
    GPIO_Init(GPIOI, &GPIO_InitStruct);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_1;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOI, &GPIO_InitStruct);

二、loopback模式修改

继续FlexCAN_Configure函数中修改:

  FLEXCAN_GetDefaultConfig(&FlexCAN_ConfigStruct);
    FlexCAN_ConfigStruct.baudRate             = 250000; /* 250kbps */
    FlexCAN_ConfigStruct.clkSrc               = Enum_Flexcan_ClkSrc1;
    FlexCAN_ConfigStruct.enableLoopBack       = true;//false;
    FlexCAN_ConfigStruct.disableSelfReception = false;//true;
    FlexCAN_ConfigStruct.enableIndividMask    = false;//tr

使能loopback

三、其他部分说明

1、发送MB定义

例程中定义了3个发送MB:7(发送标准帧)、8(发送扩展帧)、9(发送远程帧)。

 FLEXCAN_TxMbConfig(FLEXCAN1, 7, ENABLE);
    FLEXCAN_TxMbConfig(FLEXCAN1, 8, ENABLE);
    FLEXCAN_TxMbConfig(FLEXCAN1, 9, ENABLE);

    FLEXCAN_TransferCreateHandle(FLEXCAN1, &FlexCAN_Handle, FlexCAN_Transfer_Callback, NULL);

2、接收MB定义

接收MB id:
0x111、0x222、0x333、0555对应MB序号:10、11、12、13

 FlexCAN_RxMB_ConfigStruct.id     = FLEXCAN_ID_STD(0x111);
    FlexCAN_RxMB_ConfigStruct.format = Enum_Flexcan_FrameFormatStandard;
    FlexCAN_RxMB_ConfigStruct.type   = Enum_Flexcan_FrameTypeData;
    FLEXCAN_RxMbConfig(FLEXCAN1, 10, &FlexCAN_RxMB_ConfigStruct, ENABLE);

    FLEXCAN_SetRxIndividualMask(FLEXCAN1, 10, FLEXCAN_RX_MB_STD_MASK(0xFFF, 0, 0));

    FlexCAN_MB10_FrameStruct.length = (uint8_t)(8);
    FlexCAN_MB10_FrameStruct.type   = (uint8_t)Enum_Flexcan_FrameTypeData;
    FlexCAN_MB10_FrameStruct.format = (uint8_t)Enum_Flexcan_FrameFormatStandard;
    FlexCAN_MB10_FrameStruct.id     = FLEXCAN_ID_STD(0x111);

    FlexCAN_MB10_TransferStruct.mbIdx = 10;
    FlexCAN_MB10_TransferStruct.frame = &FlexCAN_MB10_FrameStruct;
    FLEXCAN_TransferReceiveNonBlocking(FLEXCAN1, &FlexCAN_Handle, &FlexCAN_MB10_TransferStruct);

    /* STD */
    FlexCAN_RxMB_ConfigStruct.id     = FLEXCAN_ID_STD(0x222);
    FlexCAN_RxMB_ConfigStruct.format = Enum_Flexcan_FrameFormatStandard;
    FlexCAN_RxMB_ConfigStruct.type   = Enum_Flexcan_FrameTypeData;
    FLEXCAN_RxMbConfig(FLEXCAN1, 11, &FlexCAN_RxMB_ConfigStruct, ENABLE);

    FLEXCAN_SetRxIndividualMask(FLEXCAN1, 11, FLEXCAN_RX_MB_STD_MASK(0xFFF, 0, 0));

    FlexCAN_MB11_FrameStruct.length = (uint8_t)(8);
    FlexCAN_MB11_FrameStruct.type   = (uint8_t)Enum_Flexcan_FrameTypeData;
    FlexCAN_MB11_FrameStruct.format = (uint8_t)Enum_Flexcan_FrameFormatStandard;
    FlexCAN_MB11_FrameStruct.id     = FLEXCAN_ID_STD(0x222);

    FlexCAN_MB11_TransferStruct.mbIdx = 11;
    FlexCAN_MB11_TransferStruct.frame = &FlexCAN_MB11_FrameStruct;
    FLEXCAN_TransferReceiveNonBlocking(FLEXCAN1, &FlexCAN_Handle, &FlexCAN_MB11_TransferStruct);

    /* EXT */
    FlexCAN_RxMB_ConfigStruct.id     = FLEXCAN_ID_EXT(0x333);
    FlexCAN_RxMB_ConfigStruct.format = Enum_Flexcan_FrameFormatExtend;
    FlexCAN_RxMB_ConfigStruct.type   = Enum_Flexcan_FrameTypeData;
    FLEXCAN_RxMbConfig(FLEXCAN1, 12, &FlexCAN_RxMB_ConfigStruct, ENABLE);

    FLEXCAN_SetRxIndividualMask(FLEXCAN1, 12, FLEXCAN_RX_MB_EXT_MASK(0xFFF, 0, 1));

    FlexCAN_MB12_FrameStruct.length = (uint8_t)(8);
    FlexCAN_MB12_FrameStruct.type   = (uint8_t)Enum_Flexcan_FrameTypeData;
    FlexCAN_MB12_FrameStruct.format = (uint8_t)Enum_Flexcan_FrameFormatExtend;
    FlexCAN_MB12_FrameStruct.id     = FLEXCAN_ID_EXT(0x333);

    FlexCAN_MB12_TransferStruct.mbIdx = 12;
    FlexCAN_MB12_TransferStruct.frame = &FlexCAN_MB12_FrameStruct;
    FLEXCAN_TransferReceiveNonBlocking(FLEXCAN1, &FlexCAN_Handle, &FlexCAN_MB12_TransferStruct);

    /* RTR */
    FlexCAN_RxMB_ConfigStruct.id     = FLEXCAN_ID_STD(0x555);
    FlexCAN_RxMB_ConfigStruct.format = Enum_Flexcan_FrameFormatStandard;
    FlexCAN_RxMB_ConfigStruct.type   = Enum_Flexcan_FrameTypeRemote;
    FLEXCAN_RxMbConfig(FLEXCAN1, 13, &FlexCAN_RxMB_ConfigStruct, ENABLE);

    FLEXCAN_SetRxIndividualMask(FLEXCAN1, 13, FLEXCAN_RX_MB_EXT_MASK(0xFFF, 1, 0));

    FlexCAN_MB13_FrameStruct.length = (uint8_t)(8);
    FlexCAN_MB13_FrameStruct.type   = (uint8_t)Enum_Flexcan_FrameTypeRemote;
    FlexCAN_MB13_FrameStruct.format = (uint8_t)Enum_Flexcan_FrameFormatStandard;
    FlexCAN_MB13_FrameStruct.id     = FLEXCAN_ID_STD(0x555);

    FlexCAN_MB13_TransferStruct.mbIdx = 13;
    FlexCAN_MB13_TransferStruct.frame = &FlexCAN_MB13_FrameStruct;
    FLEXCAN_TransferReceiveNonBlocking(FLEXCAN1, &FlexCAN_Handle, &FlexCAN_MB13_TransferStruct);

3、标准帧发送报文函数

void FlexCAN_SendStandardFrameMessage(uint32_t ID, uint8_t *Buffer, uint8_t Length)
{
    flexcan_frame_t       FlexCAN_FrameStruct;
    flexcan_mb_transfer_t FlexCAN_MB_TransferStruct;

    FlexCAN_FrameStruct.length = (uint8_t)Length;
    FlexCAN_FrameStruct.type   = (uint8_t)Enum_Flexcan_FrameTypeData;
    FlexCAN_FrameStruct.format = (uint8_t)Enum_Flexcan_FrameFormatStandard;
    FlexCAN_FrameStruct.id     = FLEXCAN_ID_STD(ID);

    FlexCAN_FrameStruct.dataByte0 = Buffer[0];
    FlexCAN_FrameStruct.dataByte1 = Buffer[1];
    FlexCAN_FrameStruct.dataByte2 = Buffer[2];
    FlexCAN_FrameStruct.dataByte3 = Buffer[3];
    FlexCAN_FrameStruct.dataByte4 = Buffer[4];
    FlexCAN_FrameStruct.dataByte5 = Buffer[5];
    FlexCAN_FrameStruct.dataByte6 = Buffer[6];
    FlexCAN_FrameStruct.dataByte7 = Buffer[7];

    FlexCAN_MB_TransferStruct.mbIdx = 7;
    FlexCAN_MB_TransferStruct.frame = &FlexCAN_FrameStruct;

    FLEXCAN_TransferSendNonBlocking(FLEXCAN1, &FlexCAN_Handle, &FlexCAN_MB_TransferStruct);
}

4、发送扩展帧报文函数

void FlexCAN_SendExtendFrameMessage(uint32_t ID, uint8_t *Buffer, uint8_t Length)
{
    flexcan_frame_t       FlexCAN_FrameStruct;
    flexcan_mb_transfer_t FlexCAN_MB_TransferStruct;

    FlexCAN_FrameStruct.length = (uint8_t)Length;
    FlexCAN_FrameStruct.type   = (uint8_t)Enum_Flexcan_FrameTypeData;
    FlexCAN_FrameStruct.format = (uint8_t)Enum_Flexcan_FrameFormatExtend;
    FlexCAN_FrameStruct.id     = FLEXCAN_ID_EXT(ID);

    FlexCAN_FrameStruct.dataByte0 = Buffer[0];
    FlexCAN_FrameStruct.dataByte1 = Buffer[1];
    FlexCAN_FrameStruct.dataByte2 = Buffer[2];
    FlexCAN_FrameStruct.dataByte3 = Buffer[3];
    FlexCAN_FrameStruct.dataByte4 = Buffer[4];
    FlexCAN_FrameStruct.dataByte5 = Buffer[5];
    FlexCAN_FrameStruct.dataByte6 = Buffer[6];
    FlexCAN_FrameStruct.dataByte7 = Buffer[7];

    FlexCAN_MB_TransferStruct.mbIdx = 8;
    FlexCAN_MB_TransferStruct.frame = &FlexCAN_FrameStruct;

    FLEXCAN_TransferSendNonBlocking(FLEXCAN1, &FlexCAN_Handle, &FlexCAN_MB_TransferStruct);
}

5、发送远程帧报文函数

void FlexCAN_SendRemoteFrameMessage(uint32_t ID, uint8_t *Buffer, uint8_t Length)
{
    flexcan_frame_t       FlexCAN_FrameStruct;
    flexcan_mb_transfer_t FlexCAN_MB_TransferStruct;

    FlexCAN_FrameStruct.length = (uint8_t)Length;
    FlexCAN_FrameStruct.type   = (uint8_t)Enum_Flexcan_FrameTypeRemote;
    FlexCAN_FrameStruct.format = (uint8_t)Enum_Flexcan_FrameFormatStandard;
    FlexCAN_FrameStruct.id     = FLEXCAN_ID_STD(ID);

    FlexCAN_FrameStruct.dataByte0 = Buffer[0];
    FlexCAN_FrameStruct.dataByte1 = Buffer[1];
    FlexCAN_FrameStruct.dataByte2 = Buffer[2];
    FlexCAN_FrameStruct.dataByte3 = Buffer[3];
    FlexCAN_FrameStruct.dataByte4 = Buffer[4];
    FlexCAN_FrameStruct.dataByte5 = Buffer[5];
    FlexCAN_FrameStruct.dataByte6 = Buffer[6];
    FlexCAN_FrameStruct.dataByte7 = Buffer[7];

    FlexCAN_MB_TransferStruct.mbIdx = 9;
    FlexCAN_MB_TransferStruct.frame = &FlexCAN_FrameStruct;

    FLEXCAN_TransferSendNonBlocking(FLEXCAN1, &FlexCAN_Handle, &FlexCAN_MB_TransferStruct);
}

6、接收处理

void FlexCAN_RxMB_Handler(void)
{
    uint32_t ID = 0;
    uint8_t  Buffer[8], Length = 0;
        int i;

    if (FlexCAN_MB10_RxCompleteFlag == 1)
    {
        FlexCAN_MB10_RxCompleteFlag = 0;

        ID     = FlexCAN_MB10_FrameStruct.id;
        Length = FlexCAN_MB10_FrameStruct.length;

        Buffer[0] = FlexCAN_MB10_FrameStruct.dataByte0;
        Buffer[1] = FlexCAN_MB10_FrameStruct.dataByte1;
        Buffer[2] = FlexCAN_MB10_FrameStruct.dataByte2;
        Buffer[3] = FlexCAN_MB10_FrameStruct.dataByte3;
        Buffer[4] = FlexCAN_MB10_FrameStruct.dataByte4;
        Buffer[5] = FlexCAN_MB10_FrameStruct.dataByte5;
        Buffer[6] = FlexCAN_MB10_FrameStruct.dataByte6;
        Buffer[7] = FlexCAN_MB10_FrameStruct.dataByte7;

        if (FlexCAN_MB10_FrameStruct.format == (uint8_t)Enum_Flexcan_FrameFormatStandard)
        {
            if (FlexCAN_MB10_FrameStruct.type == (uint8_t)Enum_Flexcan_FrameTypeData)
            {
                FlexCAN_SendStandardFrameMessage((ID >> FLEXCAN_ID_STD_Pos), Buffer, Length);
            }
            else
            {
                FlexCAN_SendRemoteFrameMessage((ID >> FLEXCAN_ID_STD_Pos), Buffer, Length);
            }
        }
        else if (FlexCAN_MB10_FrameStruct.format == (uint8_t)Enum_Flexcan_FrameFormatExtend)
        {
            FlexCAN_SendExtendFrameMessage((ID >> FLEXCAN_ID_EXT_Pos), Buffer, Length);
        }

        FLEXCAN_TransferReceiveNonBlocking(FLEXCAN1, &FlexCAN_Handle, &FlexCAN_MB10_TransferStruct);
    }

    if (FlexCAN_MB11_RxCompleteFlag == 1)
    {
        FlexCAN_MB11_RxCompleteFlag = 0;

        ID     = FlexCAN_MB11_FrameStruct.id;
        Length = FlexCAN_MB11_FrameStruct.length;

        Buffer[0] = FlexCAN_MB11_FrameStruct.dataByte0;
        Buffer[1] = FlexCAN_MB11_FrameStruct.dataByte1;
        Buffer[2] = FlexCAN_MB11_FrameStruct.dataByte2;
        Buffer[3] = FlexCAN_MB11_FrameStruct.dataByte3;
        Buffer[4] = FlexCAN_MB11_FrameStruct.dataByte4;
        Buffer[5] = FlexCAN_MB11_FrameStruct.dataByte5;
        Buffer[6] = FlexCAN_MB11_FrameStruct.dataByte6;
        Buffer[7] = FlexCAN_MB11_FrameStruct.dataByte7;
            


        if (FlexCAN_MB11_FrameStruct.format == (uint8_t)Enum_Flexcan_FrameFormatStandard)
        {
            if (FlexCAN_MB11_FrameStruct.type == (uint8_t)Enum_Flexcan_FrameTypeData)
            {
                FlexCAN_SendStandardFrameMessage((ID >> FLEXCAN_ID_STD_Pos), Buffer, Length);
            }
            else
            {
                FlexCAN_SendRemoteFrameMessage((ID >> FLEXCAN_ID_STD_Pos), Buffer, Length);
            }
        }
        else if (FlexCAN_MB11_FrameStruct.format == (uint8_t)Enum_Flexcan_FrameFormatExtend)
        {
            FlexCAN_SendExtendFrameMessage((ID >> FLEXCAN_ID_EXT_Pos), Buffer, Length);
        }

        FLEXCAN_TransferReceiveNonBlocking(FLEXCAN1, &FlexCAN_Handle, &FlexCAN_MB11_TransferStruct);
    }

    if (FlexCAN_MB12_RxCompleteFlag == 1)
    {
        FlexCAN_MB12_RxCompleteFlag = 0;

        ID     = FlexCAN_MB12_FrameStruct.id;
        Length = FlexCAN_MB12_FrameStruct.length;

        Buffer[0] = FlexCAN_MB12_FrameStruct.dataByte0;
        Buffer[1] = FlexCAN_MB12_FrameStruct.dataByte1;
        Buffer[2] = FlexCAN_MB12_FrameStruct.dataByte2;
        Buffer[3] = FlexCAN_MB12_FrameStruct.dataByte3;
        Buffer[4] = FlexCAN_MB12_FrameStruct.dataByte4;
        Buffer[5] = FlexCAN_MB12_FrameStruct.dataByte5;
        Buffer[6] = FlexCAN_MB12_FrameStruct.dataByte6;
        Buffer[7] = FlexCAN_MB12_FrameStruct.dataByte7;

        if (FlexCAN_MB12_FrameStruct.format == (uint8_t)Enum_Flexcan_FrameFormatStandard)
        {
            if (FlexCAN_MB12_FrameStruct.type == (uint8_t)Enum_Flexcan_FrameTypeData)
            {
                FlexCAN_SendStandardFrameMessage((ID >> FLEXCAN_ID_STD_Pos), Buffer, Length);
            }
            else
            {
                FlexCAN_SendRemoteFrameMessage((ID >> FLEXCAN_ID_STD_Pos), Buffer, Length);
            }
        }
        else if (FlexCAN_MB12_FrameStruct.format == (uint8_t)Enum_Flexcan_FrameFormatExtend)
        {
            FlexCAN_SendExtendFrameMessage((ID >> FLEXCAN_ID_EXT_Pos), Buffer, Length);
        }

        FLEXCAN_TransferReceiveNonBlocking(FLEXCAN1, &FlexCAN_Handle, &FlexCAN_MB12_TransferStruct);
    }

    if (FlexCAN_MB13_RxCompleteFlag == 1)
    {
        FlexCAN_MB13_RxCompleteFlag = 0;

        ID     = FlexCAN_MB13_FrameStruct.id;
        Length = FlexCAN_MB13_FrameStruct.length;

        Buffer[0] = FlexCAN_MB13_FrameStruct.dataByte0;
        Buffer[1] = FlexCAN_MB13_FrameStruct.dataByte1;
        Buffer[2] = FlexCAN_MB13_FrameStruct.dataByte2;
        Buffer[3] = FlexCAN_MB13_FrameStruct.dataByte3;
        Buffer[4] = FlexCAN_MB13_FrameStruct.dataByte4;
        Buffer[5] = FlexCAN_MB13_FrameStruct.dataByte5;
        Buffer[6] = FlexCAN_MB13_FrameStruct.dataByte6;
        Buffer[7] = FlexCAN_MB13_FrameStruct.dataByte7;

        if (FlexCAN_MB13_FrameStruct.format == (uint8_t)Enum_Flexcan_FrameFormatStandard)
        {
            if (FlexCAN_MB13_FrameStruct.type == (uint8_t)Enum_Flexcan_FrameTypeData)
            {
                FlexCAN_SendStandardFrameMessage((ID >> FLEXCAN_ID_STD_Pos), Buffer, Length);
            }
            else
            {
                FlexCAN_SendRemoteFrameMessage((ID >> FLEXCAN_ID_STD_Pos), Buffer, Length);
            }
        }
        else if (FlexCAN_MB13_FrameStruct.format == (uint8_t)Enum_Flexcan_FrameFormatExtend)
        {
            FlexCAN_SendExtendFrameMessage((ID >> FLEXCAN_ID_EXT_Pos), Buffer, Length);
        }

        FLEXCAN_TransferReceiveNonBlocking(FLEXCAN1, &FlexCAN_Handle, &FlexCAN_MB13_TransferStruct);
    }
        
        
        for(i=0;i<8;i++)
        {
            printf("[%d] 0x%x,",i,Buffer[i]);
        }
        printf("\r\n");
}

在函数的最后增加了打印收到报文内容的功能。

四、运行

1、向序号为11的MB发送报文

0x222对应11。可以看到MB 11收到报文,符合预期

void FlexCAN_Interrupt_Sample(void)
{
    uint8_t Buffer[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};

    printf("\r\nTest %s", __FUNCTION__);
    FlexCAN_Configure();
    //FlexCAN_SendStandardFrameMessage(0x214, Buffer, sizeof(Buffer));
    while (1)
    {
        FlexCAN_SendStandardFrameMessage(0x222, Buffer, sizeof(Buffer));
        PLATFORM_LED_Toggle(LED1);
        PLATFORM_DelayMS(2000);
    }
}

image.png

2、向非已定义接收MB发送报文

0x888未定义,因此只有TX信息,无接收信息。

void FlexCAN_Interrupt_Sample(void)
{
    uint8_t Buffer[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};

    printf("\r\nTest %s", __FUNCTION__);
    FlexCAN_Configure();
    //FlexCAN_SendStandardFrameMessage(0x214, Buffer, sizeof(Buffer));
    while (1)
    {
        FlexCAN_SendStandardFrameMessage(0x888, Buffer, sizeof(Buffer));
        PLATFORM_LED_Toggle(LED1);
        PLATFORM_DelayMS(2000);
    }
}

image.png

推荐阅读
关注数
0
文章数
7
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息