当前位置: 首页 > news >正文

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

简介

CAN 总线是嵌入式开发中广泛使用的工业现场总线协议,TI 的 C2000 系列 MCU 内置了 MCAN 模块。手动配置 MCAN 的寄存器、引脚复用、Message RAM 和中断过去需要频繁查阅手册,过程繁琐且容易出错。借助 CCSTHEIA 的 SysConfig 图形化工具,可以直观完成 MCAN 初始化配置并自动生成驱动代码,让开发者聚焦应用逻辑。本文以 TMS320F2800157 为例,逐步演示用 SysConfig 配置 MCAN 实现经典 CAN 收发,涵盖创建驱动空工程、SysConfig 界面操作、MCAN 参数配置(波特率、时钟、中断、Message RAM、过滤器、GPIO 和 PIE 中断),最后补全收发代码并编译。

CAN(Controller 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/eCAN,MCAN 在错误处理、过滤器和消息对象管理方面提供了更完善的硬件支持,配置灵活性也明显增强。

本文通过外接收发器和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进制的ID:7E0
    • 3.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 秒发送一帧 ID=0x7E0 的报文 // 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 //
http://www.jsqmd.com/news/1215549/

相关文章:

  • 帝舵中国官方售后服务中心|服务热线及详细地址权威信息通告(2026年7月更新) - 帝舵中国官方服务中心
  • 公司一堆印章借出去就没人管了?我用飞算 JavaAI 做了个印章管控系统
  • 3步掌握WindowResizer:打造完美桌面布局的终极指南
  • 【2026最新】555电影官网入口,稳定一键直达
  • 【Webhook触发器终极指南】:扣子平台98%开发者忽略的5个致命配置陷阱
  • 改稿速度拉满 2026 最新降AI率工具测评与推荐
  • 2026年蜘蛛池最新规则,新手入门必看
  • 几乎跪着刷完飞书的 Agent!真的太清晰了~
  • 新疆旅游报什么团好?2026本地人实测:4种团型优劣+避坑全攻略 - 旅行分享
  • 嘉兴南湖区老厂房改造想打井,前期需要做什么勘察?旧厂房打井勘察要点 - 瑞溪泉水利
  • 亲身到店探访杭州雷达官方售后服务中心|网点地址及24小时电话(2026年7月最新) - 亨得利钟表维修中心
  • AsrTools语音转文字工具:高效批量处理音频视频文件,智能生成SRT字幕
  • 积家香港官方售后服务网点通告:2026年7月最新地址+热线 - 积家官方售后服务中心
  • 安装读卡器驱动WIN10禁用数字签名
  • 1行命令唤醒沉睡的替换能力:Cursor 0.42+ 版本新增`@workspace:replace`语法全解
  • 上海静安黄金回收哪家靠谱?全域103实体门店,双资质检测绝不压低回收价 - 一日一测评
  • 9款AI写论文工具:一键生成开题报告、论文大纲、毕业论文与期刊论文
  • 完整指南:如何在3分钟内安装使用开源视频下载插件
  • LAMP 部署 Discuz 论坛
  • 当手工报表消失:企业报表自动化正在重构团队的数据能力
  • 从页面到智能体:前端转型AI应用,我先把后端这堵墙撞碎了
  • vue3 语法糖中withDefaults的用法
  • 从TypeError到TypeScript精准推导:Claude类型感知调试术,附12个可复用诊断Prompt
  • 2026 程序员AI提效:用AI把100页PDF浓缩成3分钟摘要(附3套提示词,建议收藏)
  • 电商、零售、餐饮业的报表自动化:三个行业,三种升级路径
  • 萧邦官方服务项目及价格查询|全新热线和维修门店地址权威信息声明(2026年7月最新) - 萧邦中国官方服务中心
  • w64devkit:Windows C/C++开发者的便携式瑞士军刀
  • 实体服装店急补货,如何判断哪个线上平台到货更快?
  • 干货合集:盘点2026年当红之选的的降AIGC平台
  • ChatGPT生成答案总被质疑不真实?揭秘LLM面试应答可信度校准公式(含Prompt工程验证数据)