【MM32F5270开发板试用】+ FLEXCAN1收发通信测试
本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:小会
一、电路图部分
MM32F5270开发板上有两路CAN,这里使用CAN1来测试收发通信。CAN部分电路图如下:
二、程序部分
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发出数据。
3.2、串口输出
串口同时显示接收和发出的数据