28335 CAN 接受邮箱中断配置,解决进不了中断函数的问题

上一篇将到了如何配置28335的发送寄存器,本篇讲如何配置CAN接受中断。

上一篇的链接:

28335 CAN 通讯寄存器配置标准步骤流程_追火青木的博客-CSDN博客

CAN接受中断配置,不可以盲目信任从网上copy过来的code,因为开发板硬件环境可能不同。举个例子,copy过来的code如果是ECanaRegs,但你的硬件CAN输出只是连接了一个对CAN输出GPIO,而该GPIO对应的是CANB,那无论你怎么配置都是错误的。

另外,需要注意的是,28335的CAN中断必须按照28335的手册进行配置,而不能随意配置。这点对于没有硬件编程经验的人可能会踩坑。举例如下,28335的中断分为32个中断源,其中留给用的专断有12个,每个又分为8组,因此共有96组外设级中断可供用户配置使能。但问题是虽然看似这么多,但其实芯片出厂时已经给你固定了96个能配置成什么样子。从28335手册中截图如下:

从上面手册可知,如果你自己的板子电路只使用了CANB,那接受中断就只能使用TNT9.7、或者INT9.8,配置为别的都会是错误的。关键代码如下:

 PieVectTable.ECAN1INTB = &Ecana_isr1;//把中断入口函数写入中断向量表ECAN1INTB对应的中断上

 PieCtrlRegs.PIEIER9.bit.INTx8 = 1; //CANB的中断1 

上面红色字体都是关键点,需要格外注意,避免踩坑。

附配置接受CAN中断的代码:

static void CANB_RX_Config(void)
{
    struct ECAN_REGS ECan_Reg_Shadow;
    ECan_Reg_Shadow.CANME.all = ECanbRegs.CANME.all;
    ECan_Reg_Shadow.CANME.bit.ME1 = 0;//不使能邮箱1
    ECan_Reg_Shadow.CANME.bit.ME31 = 0;//不使能邮箱31
    ECanbRegs.CANME.all = ECan_Reg_Shadow.CANME.all;
    /*----------以下代码是配置接受邮箱的相关代码------------*/
    //邮箱1相关配置
    ECanbMboxes.MBOX1.MSGCTRL.bit.DLC = 8;//配置数据长度,应该是没意义的;
    ECanbMboxes.MBOX1.MSGID.all = 0x0123C;//设置接收消息的有效ID
    ECanbMboxes.MBOX1.MSGID.bit.AME =1;//屏蔽使能位,
    ECanbMboxes.MBOX1.MSGID.bit.IDE = CAN_ID_EXT;
    /*
        LAM[28:0]
        这些位启用一个进入消息的任意标识符位的屏蔽。
        1 针对接受到的标识符的相应位, 接受一个 0 或 1( 无关) 。
        0 接收到的标识符位值必须与 MSGID 寄存器的相应标识符位相匹配。
    */

    ECanbLAMRegs.LAM1.all = 0x000000F;//
     /*
        LAMI 本地接受屏蔽标识符扩展位
        1 可以接收标准和扩展帧。 在扩展帧的情况下, 标识符的所有 29 位被存储在邮箱中, 本地接受屏蔽寄
        存器的所有 29 位被过滤器使用。 在一个标准帧的情况下, 只有标识符的头 11 个位( 28 至 18 位)
        和本地接受屏蔽被使用。
        0 存储在邮箱中的标识符扩展位决定了哪些消息应该被接收到
    */
    ECanbLAMRegs.LAM1.bit.LAMI = 1;
    //邮箱31相关配置
    ECanbMboxes.MBOX31.MSGCTRL.bit.DLC = 8;//配置数据长度,应该是没意义的;
    ECanbMboxes.MBOX31.MSGID.all = 0x07909ABC;//设置接收消息的有效ID
    ECanbMboxes.MBOX31.MSGID.bit.AME =1;//屏蔽使能位,
    ECanbMboxes.MBOX31.MSGID.bit.IDE = CAN_ID_EXT;
    /*
        LAM[28:0]
        这些位启用一个进入消息的任意标识符位的屏蔽。
        1 针对接受到的标识符的相应位, 接受一个 0 或 1( 无关) 。
        0 接收到的标识符位值必须与 MSGID 寄存器的相应标识符位相匹配。
    */

    ECanbLAMRegs.LAM31.all = 0x0000000;//
     /*
        LAMI 本地接受屏蔽标识符扩展位
        1 可以接收标准和扩展帧。 在扩展帧的情况下, 标识符的所有 29 位被存储在邮箱中, 本地接受屏蔽寄
        存器的所有 29 位被过滤器使用。 在一个标准帧的情况下, 只有标识符的头 11 个位( 28 至 18 位)
        和本地接受屏蔽被使用。
        0 存储在邮箱中的标识符扩展位决定了哪些消息应该被接收到
    */
    ECanbLAMRegs.LAM31.bit.LAMI = 1;
    ECanbRegs.CANRMP.all      = 0xFFFFFFFF;
    ECan_Reg_Shadow.CANMD.all     = ECanbRegs.CANMD.all;
    ECan_Reg_Shadow.CANMD.bit.MD1 = 1;
    ECan_Reg_Shadow.CANMD.bit.MD31 = 1;
    ECanbRegs.CANMD.all       = ECan_Reg_Shadow.CANMD.all;

    ECan_Reg_Shadow.CANME.all       = ECanbRegs.CANME.all;
    ECan_Reg_Shadow.CANME.bit.ME1   = 1;//使能邮箱1
    ECan_Reg_Shadow.CANME.bit.ME31  = 1;//使能邮箱1
    ECanbRegs.CANME.all         = ECan_Reg_Shadow.CANME.all;
}

void CAN_Rx_IT_Concig(void)
{
    EALLOW;
    ECanbRegs.CANMIM.bit.MIM31 = 1;//使能中断邮箱31的中断;
    ECanbRegs.CANMIL.bit.MIL31 = 1;//将中断31连接至中断1;
    ECanbRegs.CANGIM.bit.I1EN = 1;//使能中断1;
    EDIS;
}

  //配置中断
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    PieCtrlRegs.PIEIER9.bit.INTx8 = 1; //CANB的中断1
    IER |= M_INT9;
    IER |= M_INT1;
    EINT;
    // Enable Global interrupt INTM
    ERTM;

__interrupt void Ecana_isr1(void)
{
    DINT;
    if(ECanbRegs.CANGIF1.bit.GMIF1 == 1)
    {
        if(ECanbRegs.CANRMP.bit.RMP31 == 1)
        {
            can_rx_msg.rx_update = UPDATE;
            can_rx_msg.MBox_num = ECanbRegs.CANGIF1.bit.MIV1;
            can_rx_msg.DLC = ECanbMboxes.MBOX31.MSGCTRL.bit.DLC;
            can_rx_msg.IDE = ECanbMboxes.MBOX31.MSGID.bit.IDE;
            if(can_rx_msg.IDE == CAN_ID_EXT)
            {
                can_rx_msg.ExtId = ECanbMboxes.MBOX31.MSGID.all&0x1FFFFFFF;
                can_rx_msg.SAE_J1939_ID.id = can_rx_msg.ExtId;
            }
            else if(can_rx_msg.IDE == CAN_ID_STD)
            {
                can_rx_msg.StdId = ECanbMboxes.MBOX31.MSGID.bit.STDMSGID;
            }
           can_rx_msg.CAN_Rx_msg_data.msg_Byte.byte0 = ECanbMboxes.MBOX31.MDL.byte.BYTE0;
           can_rx_msg.CAN_Rx_msg_data.msg_Byte.byte1 = ECanbMboxes.MBOX31.MDL.byte.BYTE1;
           can_rx_msg.CAN_Rx_msg_data.msg_Byte.byte2 = ECanbMboxes.MBOX31.MDL.byte.BYTE2;
           can_rx_msg.CAN_Rx_msg_data.msg_Byte.byte3 = ECanbMboxes.MBOX31.MDL.byte.BYTE3;
           can_rx_msg.CAN_Rx_msg_data.msg_Byte.byte4 = ECanbMboxes.MBOX31.MDH.byte.BYTE4;
           can_rx_msg.CAN_Rx_msg_data.msg_Byte.byte5 = ECanbMboxes.MBOX31.MDH.byte.BYTE5;
           can_rx_msg.CAN_Rx_msg_data.msg_Byte.byte6 = ECanbMboxes.MBOX31.MDH.byte.BYTE6;
           can_rx_msg.CAN_Rx_msg_data.msg_Byte.byte7 = ECanbMboxes.MBOX31.MDH.byte.BYTE7;
           ECanbRegs.CANRMP.bit.RMP31 = 1;
        }
    }
    PieCtrlRegs.PIEACK.bit.ACK9 = 1;
    //ECanbRegs.CANGIF1.bit.GMIF1 = 1;
    EINT;

}
 

以上代码实测可用,希望能帮到后来者。

  • 9
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值