在线时间290 小时
UID3591664
注册时间2019-9-22
NXP金币1396
TA的每日心情 | 擦汗 2024-4-22 18:23 |
---|
签到天数: 590 天 [LV.9]以坛为家II
金牌会员
- 积分
- 3586
- 最后登录
- 2024-4-29
|
本帖最后由 maoyanmcu 于 2020-11-8 22:47 编辑
本人本身不是弄CAN总线通信的,所以日常使用CAN是比较少的。
所以我是这篇就是直接参考了别人的一些资料来的,CAN_FD应该可以说是CAN的升级了,波特率更高,数据帧更长。帧结构也是发生了变化。
本次实验在官方例程下可以找到。loopback是回环测试,外部不需要接CAN芯片就能直接测试。我选择上一个工程测试。
外围电路使用一颗,TJA1050T芯片,作为收发芯片,物理层上不需要改变什么东西,只是协议上的变化。
- MCAN_Init(EXAMPLE_MCAN, &mcanConfig, MCAN_CLK_FREQ);
- /* Create MCAN handle structure and set call back function. */
- MCAN_TransferCreateHandle(EXAMPLE_MCAN, &mcanHandle, mcan_callback, NULL);
- /* Set Message RAM base address and clear to avoid BEU/BEC error. */
- MCAN_SetMsgRAMBase(EXAMPLE_MCAN, MSG_RAM_BASE);
- uint32_t *p = (uint32_t *)(MSG_RAM_BASE);
- memset(p, 0, (8U + CAN_DATASIZE) * sizeof(uint8_t));
- /* STD filter config. */
- rxFilter.address = STD_FILTER_OFS;
- rxFilter.idFormat = kMCAN_FrameIDStandard;
- rxFilter.listSize = 1U;
- rxFilter.nmFrame = kMCAN_reject0;
- rxFilter.remFrame = kMCAN_rejectFrame;
- MCAN_SetFilterConfig(EXAMPLE_MCAN, &rxFilter);
- stdFilter.sfec = kMCAN_storeinFifo0;
- /* Classic filter mode, only filter matching ID. */
- stdFilter.sft = kMCAN_classic;
- stdFilter.sfid1 = rxIdentifier;
- stdFilter.sfid2 = 0x7FFU;
- MCAN_SetSTDFilterElement(EXAMPLE_MCAN, &rxFilter, &stdFilter, 0);
- /* RX fifo0 config. */
- rxFifo0.address = RX_FIFO0_OFS;
- rxFifo0.elementSize = 1U;
- rxFifo0.watermark = 0;
- rxFifo0.opmode = kMCAN_FifoBlocking;
- rxFifo0.datafieldSize = kMCAN_8ByteDatafield;
- #if (defined(USE_CANFD) && USE_CANFD)
- rxFifo0.datafieldSize = BYTES_IN_MB;
- #endif
- MCAN_SetRxFifo0Config(EXAMPLE_MCAN, &rxFifo0);
- /* TX buffer config. */
- memset(&txBuffer, 0, sizeof(txBuffer));
- txBuffer.address = TX_BUFFER_OFS;
- txBuffer.dedicatedSize = 1U;
- txBuffer.fqSize = 0;
- txBuffer.datafieldSize = kMCAN_8ByteDatafield;
- #if (defined(USE_CANFD) && USE_CANFD)
- txBuffer.datafieldSize = BYTES_IN_MB;
- #endif
- MCAN_SetTxBufferConfig(EXAMPLE_MCAN, &txBuffer);
- /* Finish software initialization and enter normal mode, synchronizes to
- CAN bus, ready for communication */
- MCAN_EnterNormalMode(EXAMPLE_MCAN);
- if ((node_type == 'A') || (node_type == 'a'))
- {
- PRINTF("Press any key to trigger one-shot transmission\r\n\r\n");
- }
- else
- {
- PRINTF("Start to Wait data from Node A\r\n\r\n");
- }
- while (1)
- {
- if ((node_type == 'A') || (node_type == 'a'))
- {
- GETCHAR();
- /* Config TX frame data. */
- memset(tx_data, 0, sizeof(uint8_t) * CAN_DATASIZE);
- for (cnt = 0; cnt < CAN_DATASIZE; cnt++)
- {
- tx_data[cnt] = cnt;
- }
- tx_data[0] += numMessage++;
- txFrame.xtd = kMCAN_FrameIDStandard;
- txFrame.rtr = kMCAN_FrameTypeData;
- txFrame.fdf = 0;
- txFrame.brs = 0;
- txFrame.dlc = 8U;
- txFrame.id = txIdentifier << STDID_OFFSET;
- txFrame.data = tx_data;
- txFrame.size = CAN_DATASIZE;
- #if (defined(USE_CANFD) && USE_CANFD)
- txFrame.fdf = 1;
- txFrame.brs = 1;
- txFrame.dlc = DLC;
- #endif
- txXfer.frame = &txFrame;
- txXfer.bufferIdx = 0;
- MCAN_TransferSendNonBlocking(EXAMPLE_MCAN, &mcanHandle, &txXfer);
- while (!txComplete)
- {
- }
- txComplete = false;
- /* Start receive data through Rx FIFO 0. */
- memset(rx_data, 0, sizeof(uint8_t) * CAN_DATASIZE);
- /* the MCAN engine can't auto to get rx payload size, we need set it. */
- rxFrame.size = CAN_DATASIZE;
- rxXfer.frame = &rxFrame;
- MCAN_TransferReceiveFifoNonBlocking(EXAMPLE_MCAN, 0, &mcanHandle, &rxXfer);
- /* Wait until message received. */
- while (!rxComplete)
- {
- }
- rxComplete = false;
- /* After call the API of rMCAN_TransferReceiveFifoNonBlocking success, we can
- * only get a point (rxFrame.data) to the fifo reading entrance.
- * Copy the received frame data from the FIFO by the pointer(rxFrame.data). */
- memcpy(rx_data, rxFrame.data, rxFrame.size);
- PRINTF("Received Frame ID: 0x%x\r\n", rxFrame.id >> STDID_OFFSET);
- PRINTF("Received Frame DATA: ");
- cnt = 0;
- while (cnt < rxFrame.size)
- {
- PRINTF("0x%x ", rx_data[cnt++]);
- }
- PRINTF("\r\n");
- PRINTF("Press any key to trigger the next transmission!\r\n\r\n");
- }
- else
- {
- memset(rx_data, 0, sizeof(uint8_t) * CAN_DATASIZE);
- /* the MCAN engine can't auto to get rx payload size, we need set it. */
- rxFrame.size = CAN_DATASIZE;
- rxXfer.frame = &rxFrame;
- MCAN_TransferReceiveFifoNonBlocking(EXAMPLE_MCAN, 0, &mcanHandle, &rxXfer);
- while (!rxComplete)
- {
- }
- rxComplete = false;
- /* After call the API of rMCAN_TransferReceiveFifoNonBlocking success, we can
- * only get a point (rxFrame.data) to the fifo reading entrance.
- * Copy the received frame data from the FIFO by the pointer(rxFrame.data). */
- memcpy(rx_data, rxFrame.data, rxFrame.size);
- PRINTF("Received Frame ID: 0x%x\r\n", rxFrame.id >> STDID_OFFSET);
- PRINTF("Received Frame DATA: ");
- cnt = 0;
- while (cnt < rxFrame.size)
- {
- PRINTF("0x%x ", rx_data[cnt++]);
- }
- PRINTF("\r\n");
- /* Copy received frame data to tx frame. */
- memcpy(tx_data, rx_data, CAN_DATASIZE);
- txFrame.xtd = rxFrame.xtd;
- txFrame.rtr = rxFrame.rtr;
- txFrame.fdf = rxFrame.fdf;
- txFrame.brs = rxFrame.brs;
- txFrame.dlc = rxFrame.dlc;
- txFrame.id = txIdentifier << STDID_OFFSET;
- txFrame.data = tx_data;
- txFrame.size = rxFrame.size;
- txXfer.frame = &txFrame;
- txXfer.bufferIdx = 0;
- MCAN_TransferSendNonBlocking(EXAMPLE_MCAN, &mcanHandle, &txXfer);
- while (!txComplete)
- {
- }
- txComplete = false;
- PRINTF("Wait Node A to trigger the next transmission!\r\n\r\n");
- }
- }
复制代码 具体代码就是我们通过串口发送“A”或者“a”时其CAN就会开始工作,发送数据并等回传数据。
我是使用了逻辑分析仪测试CAN_H和CAN_L,端口发现是有数据的,不过解码部分就不行了,因为协议对不上。所以数据部分也没有对上。
后期的话就是可以用两块板相互通信,目前就是验证了下可以发送数据,具体也没太深入研究,算初探吧。还要就是我买了新的J-LINK11发现其在KEIL下还是无法进行仿真,下载完程序后依旧是需要手动复位才能运行程序,不过在官方的IDE MCUXpresso工具中是正常的,不知道哪位有办法解决。
|
|