小会 · 2022年08月24日 · 河南

【MM32F5270开发板试用】+ FLEXCAN1收发通信测试

测试下开发板的CAN1收发通信测试

一、电路图部分

MM32F5270开发板上有两路CAN,这里使用CAN1来测试收发通信。CAN部分电路图如下:
001.png

二、程序部分

2.1、can初始化

void init_flexcan1(void)
{
        /* Set the baudrate and bit time for resynchronization. */
        FLEXCAN_TimConf_Type flexcan_tim_conf;
        flexcan_tim_conf.EnableExtendedTime = true;
        flexcan_tim_conf.PhaSegLen1 = 2u;
        flexcan_tim_conf.PhaSegLen2 = 1u;
        flexcan_tim_conf.PropSegLen = 1u;
        flexcan_tim_conf.JumpWidth = 1u;    
    
        /* Setup FlexCAN. */
    FLEXCAN_Init_Type flexcan_init;
    flexcan_init.MaxXferNum = 15u; /* The max amount of mbs to be used. */
    flexcan_init.ClockSource = FLEXCAN_ClockSource_Periph; /* Use peripheral clock. */
    flexcan_init.BaudRate = 500000u; /* Set baudrate. */
    flexcan_init.ClockFreqHz = CLOCK_APB1_FREQ; /* Set clock frequency. */
    flexcan_init.SelfWakeUp = FLEXCAN_SelfWakeUp_BypassFilter; /* Use unfiltered signal to wake up flexcan. */
    flexcan_init.WorkMode = FLEXCAN_WorkMode_Normal; /* Normal workmode, can receive and transport. */
    flexcan_init.Mask = FLEXCAN_Mask_Global; /* Use global mask for filtering. */
    flexcan_init.EnableSelfReception = false; /* Not receiving mb frame sent by self. */
    flexcan_init.EnableTimerSync = true; /* Every tx or rx done, refresh the timer to start from zero. */
    flexcan_init.TimConf = &flexcan_tim_conf; /* Set timing sychronization. */
    FLEXCAN_Init(FLEXCAN1, &flexcan_init);    
        
        /* Set tx mb. */
    FLEXCAN_ResetMb(FLEXCAN1, 2u);
    FLEXCAN_SetMbCode(FLEXCAN1, 2u, FLEXCAN_MbCode_TxInactive);
        
        /* Set rx mb. */
    FLEXCAN_RxMbConf_Type flexcan_mb_conf;
    flexcan_mb_conf.Id = APP_FLEXCAN_XFER_ID; /* Id for filtering with mask and receiving. */
    flexcan_mb_conf.MbType = FLEXCAN_MbType_Data; /* Only receive standard data frame. */
    flexcan_mb_conf.MbFormat = FLEXCAN_MbFormat_Standard;
    FLEXCAN_SetRxMb(FLEXCAN1, 0u, &flexcan_mb_conf);
    FLEXCAN_SetMbCode(FLEXCAN1, 0u, FLEXCAN_MbCode_RxEmpty);/* Set for receiving. */

    /* Enable intterupts for rx mb. */
    FLEXCAN_EnableMbInterrupts(FLEXCAN1, FLEXCAN_INT_MB_0|FLEXCAN_INT_MB_2, true);
    NVIC_EnableIRQ(FlexCAN1_IRQn);
}

2.2、CAN发送

void flexcan1_tx(uint8_t * tx_buf)
{
    FLEXCAN_Mb_Type mb;
    mb.ID = 0x200; /* Indicated ID number. */
    mb.TYPE = FLEXCAN_MbType_Data; /* Data frame type. */
    mb.FORMAT = FLEXCAN_MbFormat_Standard; /* STD frame format. */
    mb.PRIORITY = FLEXCAN1_XFER_PRIORITY; /* The priority of the frame mb. */

    /* Set the information. */
    mb.BYTE0 = tx_buf[0];
    mb.BYTE1 = tx_buf[1];
    mb.BYTE2 = tx_buf[2];
    mb.BYTE3 = tx_buf[3];
    mb.BYTE4 = tx_buf[4];
    mb.BYTE5 = tx_buf[5];
    mb.BYTE6 = tx_buf[6];
    mb.BYTE7 = tx_buf[7];

    /* Set the workload size. */
    mb.LENGTH = APP_FLEXCAN_XFER_BUF_LEN;

    /* Send. */
    FLEXCAN_WriteTxMb(BOARD_FLEXCAN_PORT, FLEXCAN1_TX_MB_CH, &mb);
    FLEXCAN_SetMbCode(BOARD_FLEXCAN_PORT, FLEXCAN1_TX_MB_CH, FLEXCAN_MbCode_TxDataOrRemote); /* Write code to send. */
}

2.3、can收发中断和接收

/* Interrupt request handler. */
void BOARD_FLEXCAN_IRQHandler(void)
{
    /* Judge the xfer event. */
    if (0u!= (FLEXCAN_GetMbStatus(FLEXCAN1) & FLEXCAN_STATUS_MB_0) )
    {
        /* Clear flexcan mb interrupt flag. */
        FLEXCAN_ClearMbStatus(FLEXCAN1, FLEXCAN_STATUS_MB_0);
        /* Update the flag. */
        app_flexcan_rx_flag = true;
    }
        
        if ( 0u != (FLEXCAN_GetMbStatus(BOARD_FLEXCAN_PORT) & FLEXCAN1_TX_MB_STATUS) )
    {
        /* Clear flag. */
        FLEXCAN_ClearMbStatus(BOARD_FLEXCAN_PORT, FLEXCAN1_TX_MB_STATUS);
        /* Update the flag. */
        app_flexcan_tx_flag = true;
    }
        
}


/* Receive a message frame. */
void flexcan1_read(uint8_t *rx_buf)
{
    /* Read the info from mb and reconstruct for understanding. */
    FLEXCAN_ReadRxMb(FLEXCAN1, 0u, &app_flexcan_rx_mb);
    rx_buf[0] = app_flexcan_rx_mb.BYTE0;
    rx_buf[1] = app_flexcan_rx_mb.BYTE1;
    rx_buf[2] = app_flexcan_rx_mb.BYTE2;
    rx_buf[3] = app_flexcan_rx_mb.BYTE3;
    rx_buf[4] = app_flexcan_rx_mb.BYTE4;
    rx_buf[5] = app_flexcan_rx_mb.BYTE5;
    rx_buf[6] = app_flexcan_rx_mb.BYTE6;
    rx_buf[7] = app_flexcan_rx_mb.BYTE7;
}

2.4、can收发测试

void can_test(void)
{
    uint8_t tx_flag=0;
    
    if(app_flexcan_rx_flag == true)
    {
        app_flexcan_rx_flag = false;
        /* Read the message. */
        flexcan1_read(app_flexcan_rx_buf);
        printf("app_flexcan_read() at timestamp %u with id %u: ", (unsigned)app_flexcan_rx_mb.TIMESTAMP, (unsigned)app_flexcan_rx_mb.ID);
        for (uint8_t i = 0u; i<APP_FLEXCAN_XFER_BUF_LEN; i++)
        {
                printf("%u ", (unsigned)app_flexcan_rx_buf[i]);
        }
        printf("\r\n\r\n");
        tx_flag=1;
    }
    
    if(tx_flag==1)
    {
        tx_flag=0;
        printf("app_flexcan_tx() sending: ");
        for (uint8_t i = 0u; i < APP_FLEXCAN_XFER_BUF_LEN; i++)
        {
                app_flexcan_tx_buf[i] = app_flexcan_rx_buf[i];
                printf("%u ", (unsigned)app_flexcan_tx_buf[i]);
        }
        printf("\r\n");
        flexcan1_tx(app_flexcan_tx_buf);

        /* Wait for reception. */
        while (!app_flexcan_tx_flag) /* This flag will be on when the Tx interrupt is asserted. */
        {
        }
        app_flexcan_tx_flag = false;
        printf("app_flexcan_tx() done.\r\n\r\n");
    }
}

三、程序运行

使用CAN适配器与开发板之间数据通信。测试波特率:500kbps,标准帧数据格式。

3.1、CAN调试工具数据

开发板CAN1收到0x378标准帧数据后,通过CAN1将数据通过地址0x200发出数据。
003.png

3.2、串口输出

串口同时显示接收和发出的数据

002.png

推荐阅读
关注数
6100
内容数
272
灵动MM32 MCU相关技术知识,欢迎关注~
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息