测试下开发板的CAN1收发通信测试
一、电路图部分
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、串口输出
串口同时显示接收和发出的数据