TMS320F28379D笔记5:CAN通信多邮箱配置

只是配置一下CAN多邮箱的过程记录

引脚更改:

相较于上篇代码,这里引脚已经改掉一个,在launchpad开发板也飞线接过去了:

关于CPU频率的问题:

之前文章解决方法,是把传值给除以2了


实际只要定义好了宏就行:在device.h文件:

cpp 复制代码
#define _LAUNCHXL_F28379D

1

#include "device_hal_can.h"

这里我加了开启中断接收与否的宏:

不开就要用轮询方式主动读取邮箱了:

cpp 复制代码
can轮询接收函数:
        CAN_readMessage(CANB_BASE, RX_MSG_OBJ2, rxData_Obj2);
        CAN_readMessage(CANB_BASE, RX_MSG_OBJ3, rxData_Obj3);
        CAN_readMessage(CANB_BASE, RX_MSG_OBJ4, rxData_Obj4);
        CAN_readMessage(CANB_BASE, RX_MSG_OBJ5, rxData_Obj5);
        CAN_readMessage(CANB_BASE, RX_MSG_OBJ6, rxData_Obj6);
cpp 复制代码
#include "device_hal_can.h"

uint16_t txMsgData[8];
uint16_t txMsgData2[8];


uint16_t rxData_Obj2[CAN_DATA_LEN];
uint16_t rxData_Obj3[CAN_DATA_LEN];
uint16_t rxData_Obj4[CAN_DATA_LEN];
uint16_t rxData_Obj5[CAN_DATA_LEN];
uint16_t rxData_Obj6[CAN_DATA_LEN];

static void Config_CAN_GPIO(void)
{
    GPIO_setPinConfig(GPIO_CFG_CANRXB);  // CANB RX
    GPIO_setPinConfig(GPIO_CFG_CANTXB);  // CANB TX

    GPIO_setControllerCore(PIN_CFG_CANTXB, GPIO_CORE_CPU1);
    GPIO_setPadConfig(PIN_CFG_CANTXB, GPIO_PIN_TYPE_STD);
    GPIO_setControllerCore(PIN_CFG_CANRXB, GPIO_CORE_CPU1);
    GPIO_setPadConfig(PIN_CFG_CANRXB, GPIO_PIN_TYPE_PULLUP);
}
void RPS_HAL_SetupCan(void)
{
    txMsgData[0] = 0x55;txMsgData[1] = 0xff;txMsgData[2] = 0x55;txMsgData[3] = 0xff;
    txMsgData[4] = 0x55;txMsgData[5] = 0xff;txMsgData[6] = 0x55;txMsgData[7] = 0xff;

    txMsgData2[0] = 0x12;txMsgData2[1] = 0x34;txMsgData2[2] = 0x56;txMsgData2[3] = 0x78;
    txMsgData2[4] = 0x21;txMsgData2[5] = 0x43;txMsgData2[6] = 0x65;txMsgData2[7] = 0x87;

    Config_CAN_GPIO();

    // Initialize the CAN controllers
    CAN_initModule(CANB_BASE);
    CAN_disableTestMode(CANB_BASE);

    // Set up the CAN bus bit rate to 1Mbps
    //    500k     20
    //    250k     20 / 16
    //    1000k    10
   // CAN_setBitRate(CANB_BASE,DEVICE_SYSCLK_FREQ/2,500000, 20); // CANB
    CAN_setBitRate(CANB_BASE,DEVICE_SYSCLK_FREQ_1,1000000, 10); // CANB
    //CAN_enableTestMode(CANB_BASE, CAN_TEST_EXL);
    // Initialize the transmit message object used for sending CAN messages.
    // Message Object Parameters:
    //      CAN Module: A
    //      Message Object ID Number: 1
    //      Message Identifier: 0x01
    //      Message Frame: Standard
    //      Message Type: Transmit
    //      Message ID Mask: 0x0
    //      Message Object Flags: None
    //      Message Data Length: 4 Bytes
    //
    CAN_setupMessageObject(CANB_BASE, TX_MSG_OBJ_ID, CAN_ID,
                           CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0,
                           CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH);
    // 配置接收邮箱 2
    // Message Data Length: "Don't care" for a Receive mailbox
    // 邮箱的 ID 过滤掩码是 0,不做任何过滤,接收所有 ID 的报文。
//    CAN_setupMessageObject(CANB_BASE, RX_MSG_OBJ_ID, CAN_ID,
//                           CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_RX, 0,
//                           CAN_MSG_OBJ_USE_ID_FILTER | CAN_MSG_OBJ_RX_INT_ENABLE, MSG_DATA_LENGTH);

       // 邮箱2:接收中断使能 / 掩码 0x7FF(严格全匹配)
       CAN_setupMessageObject(CANB_BASE, RX_MSG_OBJ2, CAN_RX_ID_OBJ2,
                              CAN_FRAME_STD, CAN_TYPE_RX, 0x7FF,
                              CAN_RX_COMMON_FLAGS, CAN_DATA_LEN);
       // 邮箱3:
       CAN_setupMessageObject(CANB_BASE, RX_MSG_OBJ3, CAN_RX_ID_OBJ3,
                              CAN_FRAME_STD, CAN_TYPE_RX, 0x7FF,
                              CAN_RX_COMMON_FLAGS, CAN_DATA_LEN);
       // 邮箱4:
       CAN_setupMessageObject(CANB_BASE, RX_MSG_OBJ4, CAN_RX_ID_OBJ4,
                              CAN_FRAME_STD, CAN_TYPE_RX, 0x7FF,
                              CAN_RX_COMMON_FLAGS, CAN_DATA_LEN);
       // 邮箱5:
       CAN_setupMessageObject(CANB_BASE, RX_MSG_OBJ5, CAN_RX_ID_OBJ5,
                              CAN_FRAME_STD, CAN_TYPE_RX, 0x7FF,
                              CAN_RX_COMMON_FLAGS, CAN_DATA_LEN);
       // 邮箱6:
       CAN_setupMessageObject(CANB_BASE, RX_MSG_OBJ6, CAN_RX_ID_OBJ6,
                              CAN_FRAME_STD, CAN_TYPE_RX, 0x7FF,
                              CAN_RX_COMMON_FLAGS, CAN_DATA_LEN);

       // CANB 中断配置 仅中断模式开启
   #if CAN_RX_USE_INT
       CAN_enableInterrupt(CANB_BASE, CAN_INT_IE0 | CAN_INT_ERROR |CAN_INT_STATUS);
       Interrupt_register(INT_CANB0, &canB_ISR);
       Interrupt_enable(INT_CANB0);
       CAN_enableGlobalInterrupt(CANB_BASE, CAN_GLOBAL_INT_CANINT0);
   #endif

       // Start CANB module operations
       CAN_startModule(CANB_BASE);
}

#if CAN_RX_USE_INT
// 接收中断函数
__interrupt void canB_ISR(void)
{
    uint32_t errReg;
    uint32_t status;

    status = CAN_getInterruptCause(CANB_BASE);
    if(status == CAN_INT_INT0ID_STATUS)
    {
        errReg = CAN_getStatus(CANB_BASE);
        if((errReg & 0x8000U) != 0U)
        {
            // 软复位CAN退出BUSOFF
            CAN_initModule(CANB_BASE);
            CAN_setBitRate(CANB_BASE, DEVICE_SYSCLK_FREQ_1,1000000, 10);
            CAN_startModule(CANB_BASE);
        }
    }
    else if(status == TX_MSG_OBJ_ID)
    {
        CAN_clearInterruptStatus(CANB_BASE, TX_MSG_OBJ_ID);
    }
    // 接收邮箱2
    else if(status == RX_MSG_OBJ2)
    {
        CAN_readMessage(CANB_BASE, RX_MSG_OBJ2, rxData_Obj2);
        CAN_clearInterruptStatus(CANB_BASE, RX_MSG_OBJ2);
    }
    // 接收邮箱3
    else if(status == RX_MSG_OBJ3)
    {
        CAN_readMessage(CANB_BASE, RX_MSG_OBJ3, rxData_Obj3);
        CAN_clearInterruptStatus(CANB_BASE, RX_MSG_OBJ3);
    }
    // 接收邮箱4
    else if(status == RX_MSG_OBJ4)
    {
        CAN_readMessage(CANB_BASE, RX_MSG_OBJ4, rxData_Obj4);
        CAN_clearInterruptStatus(CANB_BASE, RX_MSG_OBJ4);
    }
    // 接收邮箱5
    else if(status == RX_MSG_OBJ5)
    {
        CAN_readMessage(CANB_BASE, RX_MSG_OBJ5, rxData_Obj5);
        CAN_clearInterruptStatus(CANB_BASE, RX_MSG_OBJ5);
    }
    // 接收邮箱6
    else if(status == RX_MSG_OBJ6)
    {
        CAN_readMessage(CANB_BASE, RX_MSG_OBJ6, rxData_Obj6);
        CAN_clearInterruptStatus(CANB_BASE, RX_MSG_OBJ6);
    }
    CAN_clearGlobalInterruptStatus(CANB_BASE, CAN_GLOBAL_INT_CANINT0);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}
#endif
cpp 复制代码
#ifndef _DEVICE_HAL_CAN_H_
#define _DEVICE_HAL_CAN_H_


#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "c2000ware_libraries.h"
#include "device_hal_can.h"

#define CAN_RX_USE_INT    1           // 1=中断接收,0=轮询接收

#define DEVICE_SYSCLK_FREQ_1 DEVICE_SYSCLK_FREQ

#define PIN_CFG_CANRXB       17
#define GPIO_CFG_CANRXB      GPIO_17_CANRXB  // "pinConfig" for CANB RX
//#define GPIO_CFG_CANTXB      GPIO_12_CANTXB  // "pinConfig" for CANB TX
#define PIN_CFG_CANTXB       16
#define GPIO_CFG_CANTXB      GPIO_16_CANTXB  // "pinConfig" for CANB TX


#define CAN_DATA_LEN       8U         // 每个CAN报文最大8字节

#define CAN_ID             0x1        // 发ID 0x1
#define MSG_DATA_LENGTH     8
#define MSG_DATARX_LENGTH   0
#define TX_MSG_OBJ_ID       1         // 发送邮箱

// 接收邮箱标志 自动根据宏切换
#if CAN_RX_USE_INT
#define CAN_RX_COMMON_FLAGS  (CAN_MSG_OBJ_USE_ID_FILTER | CAN_MSG_OBJ_RX_INT_ENABLE)
#else
#define CAN_RX_COMMON_FLAGS  (CAN_MSG_OBJ_USE_ID_FILTER)
#endif

#define CAN_FRAME_STD        CAN_MSG_FRAME_STD
#define CAN_TYPE_RX          CAN_MSG_OBJ_TYPE_RX
// 接收邮箱编号
#define RX_MSG_OBJ1     1U
#define RX_MSG_OBJ2     2U
#define RX_MSG_OBJ3     3U
#define RX_MSG_OBJ4     4U
#define RX_MSG_OBJ5     5U
#define RX_MSG_OBJ6     6U
//对应邮箱的CAN-ID宏
#define CAN_RX_ID_OBJ1     0x01U
#define CAN_RX_ID_OBJ2     0x02U
#define CAN_RX_ID_OBJ3     0x03U
#define CAN_RX_ID_OBJ4     0x04U
#define CAN_RX_ID_OBJ5     0x05U
#define CAN_RX_ID_OBJ6     0x06U


extern uint16_t txMsgData[8];
extern uint16_t txMsgData2[8];

extern uint16_t rxData_Obj2[CAN_DATA_LEN];
extern uint16_t rxData_Obj3[CAN_DATA_LEN];
extern uint16_t rxData_Obj4[CAN_DATA_LEN];
extern uint16_t rxData_Obj5[CAN_DATA_LEN];
extern uint16_t rxData_Obj6[CAN_DATA_LEN];



void RPS_HAL_SetupCan(void);


#if CAN_RX_USE_INT
__interrupt void canB_ISR(void);
#endif

// 仅轮询模式使用,循环调用读取所有接收邮箱
void CANB_PollAllRxMailbox(void);








#endif

主函数调用初始化:

CAN发送:

cpp 复制代码
        CAN_sendMessage(CANB_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH, txMsgData);
        // Poll TxOk bit in CAN_ES register to check completion of transmission
        //while(((HWREGH(CANB_BASE + CAN_O_ES) & CAN_ES_TXOK)) !=  CAN_ES_TXOK){}
        delay_ms(10);
        CAN_sendMessage(CANB_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH, txMsgData2);
        // Poll TxOk bit in CAN_ES register to check completion of transmission
        //while(((HWREGH(CANB_BASE + CAN_O_ES) & CAN_ES_TXOK)) !=  CAN_ES_TXOK){}

测试结果:

打开DEBUG查看对应邮箱ID的接收buffer,看到能够对应上邮箱接收到信息:

相关推荐
ACP广源盛139246256737 小时前
硬件选型笔记:国产 PCIe Gen2.1 交换芯片 IX6024@ACP,工控与存量设备国产化改造方案评估
笔记·硬件架构·硬件工程·pcie·国产芯片
文人sec8 小时前
SQL基础入门笔记 | 从零基础到掌握核心查询语句
数据库·笔记·sql
摇滚侠10 小时前
《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 9 章 机器码与汇编语言 阅读笔记 9
java·开发语言·笔记
xier_ran10 小时前
【infra之路】AI 编译器学习笔记(六):重拾 C++——lambda 与 MLIR 中的回调
c++·笔记·学习
志尊宝10 小时前
Vue3 零基础每日笔记(078):首屏加载速度优化汇总——清单化方案
笔记
ZZHow102413 小时前
Ascend C算子开发(高级)笔记
c++·人工智能·笔记·深度学习·华为云
PC2005-cloud14 小时前
Mysql学习笔记:InnoDB Cluster 集群从零搭建实战,基于 Docker 实现高可用读写分离架构
笔记·学习·mysql
小陈phd14 小时前
深入理解agent学习笔记(七)——动态提示词与Skills
笔记·学习
我命由我1234514 小时前
田野笔记极简理解
经验分享·笔记·学习·职场和发展·求职招聘·职场发展·学习方法
小陈phd15 小时前
深入理解agent学习笔记(六)——提示工程-优化系统提示词
笔记·学习