F2800157开发板图形化配置 MCAN 报文收发笔记

F2800157开发板图形化配置 MCAN 报文收发笔记
简介CAN 总线是嵌入式开发中广泛使用的工业现场总线协议TI 的 C2000 系列 MCU 内置了 MCAN 模块。手动配置 MCAN 的寄存器、引脚复用、Message RAM 和中断过去需要频繁查阅手册过程繁琐且容易出错。借助 CCSTHEIA 的 SysConfig 图形化工具可以直观完成 MCAN 初始化配置并自动生成驱动代码让开发者聚焦应用逻辑。本文以 TMS320F2800157 为例逐步演示用 SysConfig 配置 MCAN 实现经典 CAN 收发涵盖创建驱动空工程、SysConfig 界面操作、MCAN 参数配置波特率、时钟、中断、Message RAM、过滤器、GPIO 和 PIE 中断最后补全收发代码并编译。CANController Area Network是 Bosch 提出的基于消息广播的串行通信协议通过两根差分线实现多主架构通信具备高可靠性和强实时性广泛应用于汽车电子和工业控制。经典 CAN 支持 11 位标准 ID 或 29 位扩展 ID数据帧最多 8 字节CAN FD 在此基础上将数据段速率提升至 8 Mbps、有效载荷扩展到 64 字节。MCAN 是 TI C2000 系列集成的 CAN 外设模块遵循 ISO 11898-1兼容 CAN 2.0A/B 与 CAN FD通过共享 Message RAM 灵活分配收发缓存。相比早期的 DCAN/eCANMCAN 在错误处理、过滤器和消息对象管理方面提供了更完善的硬件支持配置灵活性也明显增强。本文通过外接收发器和can卡完成总线的连通进行收发测试1. 创建工程我这里选用的是带有驱动的空工程直接导入就可以了后面的弹出一路点就可以2. 打开 SysConfig 界面我这选择对应的开发板型号然后出现第二张图的页面对一些功能进行配置3. 配置 MCAN 模块3.1 添加 MCAN 实例左边列表中找到MCAN并点击添加本实验采样的是标准的CAN所以取消默认的三个模式的勾选3.2 波特率配置这配置的波特率是500kbit同时需要配置时钟3.3 时钟配置在左边选择时钟树选择配置对应的时钟我这里选择预分频系数3将系统的120M转为40M的时钟信号配合上面的参数得到CAN信号的波特率3.4 中断配置使能中断并打开所有的中断源将MCAN挂在中断线1上并设置触发中断的条件这里设置的是DRX触发中断并将中断线1注册3.5 Message RAM 配置首先配置了接收的RX Buffer标准的can接收的数据最大字节为8个所以选择都是8然后是TX Buffer设置2个专用缓存区然后数据的大小也选择8个字节3.6 过滤器配置本文选择使用过滤器0然后下面就会多一个滤波器0的折叠配置这里因为本文使用的是RX Buffer所以滤波的范围是不允许的只能针对单一的ID进行接收这里我写的2016对应的16进制的ID7E03.7 GPIO 引脚配置这个地方对收发的引脚进行配置可以选择本文在实际的测试中发现GPIO21\20和GPIO12\13是可以正常使用的但是GPIO30\31和GPIO4\5无法收发暂时不知道是什么原因导致的3.8 PIE 中断配置最后配置中断PIE勾选即可然后中断处理函数的名称在这里可以INT_myMCAN0_1_ISR修改也可以就使用这个中断处理函数内的内容需要自己添加4. 生成代码并集成4.1 Rx Buffer 接收代码补全保存syscfg的配置后在主函数下面添加中断处理函数MCAN_RxBufElement g_rxMsg; volatile uint32_t g_txCount 0U; // 发送计数 __interrupt void INT_myMCAN0_1_ISR(void) { uint32_t intrStatus; MCAN_RxNewDataStatus newData; intrStatus MCAN_getIntrStatus(MCANA_DRIVER_BASE); MCAN_clearIntrStatus(MCANA_DRIVER_BASE, intrStatus); MCAN_clearInterrupt(MCANA_DRIVER_BASE, 0x2); if((MCAN_IR_DRX_MASK intrStatus) MCAN_IR_DRX_MASK) { MCAN_getNewDataStatus(MCANA_DRIVER_BASE, newData); if((newData.statusLow (1UL 0U)) ! 0U) { MCAN_readMsgRam(MCANA_DRIVER_BASE, MCAN_MEM_TYPE_BUF, 0U, 0, g_rxMsg); g_rxMsg.id g_rxMsg.id 18U; // 提取真实 CAN ID g_rxCount; } MCAN_clearNewDataStatus(MCANA_DRIVER_BASE, newData); } else { // // 非DRX中断TC发送完成、错误等仅记录不中断运行 // } Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9); }4.2 编译代码检查配置保存后编译代码配置的代码就会自动生成在主函数里其中图形化配置的代码基本在board.c中// // Initialize device clock and peripherals // Device_init(); // // Disable pin locks and enable internal pull-ups. // Device_initGPIO(); // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // Interrupt_initModule(); // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // Interrupt_initVectorTable(); // // PinMux and Peripheral Initialization // Board_init(); // // C2000Ware Library initialization // C2000Ware_libraries_init(); // // Enable Global Interrupt (INTM) and real time interrupt (DBGM) // EINT; ERTM;引脚配置代码中断初始化等等5.2 Tx Buffer 发送代码添加的新的发送代码volatile uint32_t g_txCount 0U; // 发送计数 volatile uint32_t g_rxCanId 0U; // 接收到的真实 CAN ID已移位 // // Tx Buffer 发送函数 // void App_MCANSend(uint32_t canId, const uint8_t *data, uint32_t len) { MCAN_TxBufElement txMsg; uint32_t i; memset(txMsg, 0, sizeof(txMsg)); txMsg.id canId 18U; // CAN ID 位于 bits[28:18] txMsg.dlc (len 8U) ? 8U : len; txMsg.rtr 0U; txMsg.xtd 0U; txMsg.fdf 0U; for(i 0U; i txMsg.dlc; i) { txMsg.data[i] data[i]; } MCAN_writeMsgRam(MCANA_DRIVER_BASE, MCAN_MEM_TYPE_BUF, 0U, txMsg); MCAN_txBufAddReq(MCANA_DRIVER_BASE, 0U); g_txCount; }5.3 保存并生成代码编写 main.c完整示例接收 发送//############################################################################# // // FILE: empty_driverlib_main.c // // TITLE: Empty Project // // Empty Project Example // // This example is an empty project setup for Driverlib development. // //############################################################################# // // // $Copyright: // Copyright (C) 2026 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# // // Included Files // #include driverlib.h #include device.h #include board.h #include c2000ware_libraries.h #include string.h MCAN_RxBufElement g_rxMsg; volatile uint32_t g_rxCount 0U; volatile uint32_t g_txCount 0U; // 发送计数 volatile uint32_t g_rxCanId 0U; // 接收到的真实 CAN ID已移位 // // Tx Buffer 发送函数 // void App_MCANSend(uint32_t canId, const uint8_t *data, uint32_t len) { MCAN_TxBufElement txMsg; uint32_t i; memset(txMsg, 0, sizeof(txMsg)); txMsg.id canId 18U; // CAN ID 位于 bits[28:18] txMsg.dlc (len 8U) ? 8U : len; txMsg.rtr 0U; txMsg.xtd 0U; txMsg.fdf 0U; for(i 0U; i txMsg.dlc; i) { txMsg.data[i] data[i]; } MCAN_writeMsgRam(MCANA_DRIVER_BASE, MCAN_MEM_TYPE_BUF, 0U, txMsg); MCAN_txBufAddReq(MCANA_DRIVER_BASE, 0U); g_txCount; } // // Main // void main(void) { // // Initialize device clock and peripherals // Device_init(); // // Disable pin locks and enable internal pull-ups. // Device_initGPIO(); // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // Interrupt_initModule(); // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // Interrupt_initVectorTable(); // // PinMux and Peripheral Initialization // Board_init(); // // C2000Ware Library initialization // C2000Ware_libraries_init(); // // Enable Global Interrupt (INTM) and real time interrupt (DBGM) // EINT; ERTM; uint8_t testData[8] {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; while(1) { // // 每 1 秒发送一帧 ID0x7E0 的报文 // App_MCANSend(0x710U, testData, 8U); DEVICE_DELAY_US(1000000); } } __interrupt void INT_myMCAN0_1_ISR(void) { uint32_t intrStatus; MCAN_RxNewDataStatus newData; intrStatus MCAN_getIntrStatus(MCANA_DRIVER_BASE); MCAN_clearIntrStatus(MCANA_DRIVER_BASE, intrStatus); MCAN_clearInterrupt(MCANA_DRIVER_BASE, 0x2); if((MCAN_IR_DRX_MASK intrStatus) MCAN_IR_DRX_MASK) { MCAN_getNewDataStatus(MCANA_DRIVER_BASE, newData); if((newData.statusLow (1UL 0U)) ! 0U) { MCAN_readMsgRam(MCANA_DRIVER_BASE, MCAN_MEM_TYPE_BUF, 0U, 0, g_rxMsg); g_rxMsg.id g_rxMsg.id 18U; // 提取真实 CAN ID g_rxCount; } MCAN_clearNewDataStatus(MCANA_DRIVER_BASE, newData); } else { // // 非DRX中断TC发送完成、错误等仅记录不中断运行 // } Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9); } // // End of File //