上一篇将到了如何配置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;
} ?
以上代码实测可用,希望能帮到后来者。
|