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,看到能够对应上邮箱接收到信息:

相关推荐
aaaameliaaa3 小时前
进制练习题【找出只出现一次的数字、交换两个变量(不创建临时变量)、统计二进制中1的个数、打印整数二进制的奇数位和偶数位、求两个数二进制中不同位的个数】
c语言·数据结构·笔记·算法
RainCity4 小时前
Java Swing 自定义组件库分享(十三)
java·笔记·后端
llllliznc7 小时前
LLM 学习笔记 Day 5:Agent 核心组件——Planner、Memory 与 Reflection
笔记·学习
risc1234567 小时前
“解决了什么痛点”与“为什么有这个东西”的关系?
笔记
hj2862517 小时前
Docker 容器化技术标准化笔记
java·笔记·docker
hyhsandy18037 小时前
STM32F103 TIM学习笔记
笔记·stm32·学习
栈溢出了7 小时前
Redis 消息队列笔记:List 与 Pub/Sub
redis·笔记·list
鹰影478 小时前
一款AI笔记助手和远程同步的markdown笔记idea-note
人工智能·笔记·rust·typescript·react
ljt27249606618 小时前
RAG检索增强生成
笔记