This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28335:eCAN 的发送和接收中断问题

Guru**** 2587345 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1255864/tms320f28335-transmit-and-receive-interrupt-issues-with-ecan

器件型号:TMS320F28335

大家好、

客户有问题需要您的帮助:

主程序:
#include "eCAN.h"

//定义全局变量
Uint32 MessageSendCount = 0;
Uint32 MessageReceiveCount = 0;
Uint32 Rec_l;
Uint32 Rec_h;
Uint16 i = 0,j = 0,k = 0;
Uchar senddata[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};

__interrupt void ECAN0INTB_iSR(void);

void main(void)
{
    InitSysCtrl();
    DINT;
    IER = 0x0000;
    IFR = 0x0000;
    InitPieCtrl();
    InitPieVectTable();

    EALLOW;  // 写保护
    PieVectTable.ECAN0INTB = &ECAN0INTB_iSR;    //设置ECAN0INTB中断服务程序的入口地址为ECAN0INTB_iSR
    EDIS;    // 禁用写保护

    InitECan();
    //使能PIE中断
    PieCtrlRegs.PIEIER9.bit.INTx7 = 1;

    //使能CPU中断
    IER |= M_INT9;
    EINT;                         //开全局中断
    ERTM;                         //开实时中断

    for(;;)
    {
        //只使用接收的话,52行-65行注释掉即可
//        for(;k<20;)
//        {
            ECanbRegs.CANTRS.all = 0x00000001;     //1设置TRSn,发送该邮箱中的消息
            while(ECanbRegs.CANTA.all == 0){}      //等待TA被置位,邮箱消息发送成功则置位
            ECanbRegs.CANTA.all = 0x00000001;      //如果邮箱n的消息发送成功,则设置该寄存器的第n位
            MessageSendCount++;                    //设断点,观察
            ECanbMboxes.MBOX0.MDL.all = senddata[i];
            ECanbMboxes.MBOX0.MDH.all = senddata[i + 1];
            i = i + 2;
            if(i > 7)
            i = 0;
//            k++;
//        }
    }
}

__interrupt void ECAN0INTB_iSR(void)            //eCAN_B
{
    if(ECanbRegs.CANRMP.all != 0)               //判断是否有数据
    {
        while(ECanbRegs.CANRMP.all != 0x00010000);
        ECanbRegs.CANRMP.all = 0x00010000;      //复位RMP标志,同时也复位中断标志
        Rec_l = ECanbMboxes.MBOX16.MDL.all;     //接收到的数据在接收邮箱Mbox16
        Rec_h = ECanbMboxes.MBOX16.MDH.all;
        PieCtrlRegs.PIEACK.bit.ACK9 = 1;
        EINT;
    }
}



ecan.c

void InitECan(void)
{
    struct ECAN_REGS ECanbShadow;
    EALLOW;

    //配置GPIO引脚工作在eCAN功能
    GpioCtrlRegs.GPAPUD.bit.GPIO16 = 1;     //禁止上拉GPIO16(CANTXB)
    GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;     //使能上拉GPIO17(CANRXB)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3;
    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 2;    //配置GPIO16为CANTXB
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 2;    //配置GPIO17为CANRXB
    //配置eCAN的RX&TX分别为eCAN的接收和发送引脚

    ECanbShadow.CANTIOC.all = ECanbRegs.CANTIOC.all;
    ECanbShadow.CANTIOC.bit.TXFUNC = 1;
    ECanbRegs.CANTIOC.all = ECanbShadow.CANTIOC.all;
    ECanbShadow.CANRIOC.all = ECanbRegs.CANRIOC.all;
    ECanbShadow.CANRIOC.bit.RXFUNC = 1;
    ECanbRegs.CANRIOC.all = ECanbShadow.CANRIOC.all;
    ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;
    ECanbShadow.CANMC.bit.STM = 0;          //工作在正常模式
    ECanbShadow.CANMC.bit.SCB = 1;
    ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;

    //初始化所有主设备控制区域为0,MCF所有的位都初始化为0
    ECanbMboxes.MBOX0.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX1.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX2.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX3.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX4.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX5.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX6.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX7.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX8.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX9.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX10.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX11.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX12.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX13.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX14.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX15.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX16.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX17.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX18.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX19.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX20.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX21.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX22.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX23.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX24.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX25.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX26.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX27.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX28.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX29.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX30.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX31.MSGCTRL.all = 0x00000000;
    ECanbShadow.CANTA.all = ECanbRegs.CANTA.all;
    ECanbShadow.CANTA.all = 0xFFFFFFFF;
    ECanbRegs.CANTA.all = ECanbShadow.CANTA.all;
    ECanbShadow.CANRMP.all = ECanbRegs.CANRMP.all;
    ECanbShadow.CANRMP.all = 0xFFFFFFFF;
    ECanbRegs.CANRMP.all = ECanbShadow.CANRMP.all;
    ECanbShadow.CANGIF0.all = ECanbRegs.CANGIF0.all;
    ECanbShadow.CANGIF0.all = 0xFFFFFFFF;
    ECanbRegs.CANGIF0.all = ECanbShadow.CANGIF0.all;
    ECanbShadow.CANGIF1.all = ECanbRegs.CANGIF1.all;
    ECanbShadow.CANGIF1.all = 0xFFFFFFFF;
    ECanbRegs.CANGIF1.all = ECanbShadow.CANGIF1.all;
    /*为eCAN配置位时间参数*/
    ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;
    ECanbShadow.CANMC.bit.CCR = 1;             //设置CCR=1
    ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;

//    ECanbShadow.CANES.all = ECanbRegs.CANES.all;      //////////////////////

    do
    {ECanbShadow.CANES.all = ECanbRegs.CANES.all;
    }while(ECanbShadow.CANES.bit.CCE != 1);    //等待CCE位被清除
    ECanbShadow.CANBTC.all = ECanbRegs.CANBTC.all;
    ECanbShadow.CANBTC.bit.BRPREG = 9;         //数据传输速率
    //150/10 = 15
    ECanbShadow.CANBTC.bit.TSEG2REG = 2;
    ECanbShadow.CANBTC.bit.TSEG1REG = 10;
    ECanbRegs.CANBTC.all = ECanbShadow.CANBTC.all;
    ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;
    ECanbShadow.CANMC.bit.CCR = 0;             //设置CCR=0
    ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;
    do
    {ECanbShadow.CANES.all = ECanbRegs.CANES.all;
    }while(ECanbShadow.CANES.bit.CCE != 0);    //等待CCE位被置位
    ECanbShadow.CANME.all = ECanbRegs.CANME.all;
    ECanbShadow.CANME.all = 0;
    ECanbRegs.CANME.all = ECanbShadow.CANME.all;

    //接收邮箱的ID
    ECanbMboxes.MBOX0.MSGID.all = 0x80C80000;  //扩展帧         /////////////
    ECanbMboxes.MBOX16.MSGID.all = 0x80C20000;  //扩展帧

    //邮箱0为TX,16为RX
    ECanbShadow.CANMD.all = ECanbRegs.CANMD.all;
    ECanbShadow.CANMD.bit.MD0 = 0;              //邮箱0,发送    /////////////
    ECanbShadow.CANMD.bit.MD16 = 1;             //邮箱16,接收
    ECanbRegs.CANMD.all = ECanbShadow.CANMD.all;

    //数据长度为8个byte
    ECanbMboxes.MBOX0.MSGCTRL.bit.DLC = 8;      ////////////
    ECanbMboxes.MBOX16.MSGCTRL.bit.DLC = 8;

    //设置发送优先级 2009.3.15 Add
    ECanbMboxes.MBOX0.MSGCTRL.bit.TPL = 0;      ////////////
    ECanbMboxes.MBOX16.MSGCTRL.bit.TPL = 0;

    //没有远方应答帧被请求
    ECanbMboxes.MBOX0.MSGCTRL.bit.RTR = 0;      //////////////看手册弄懂
    ECanbMboxes.MBOX16.MSGCTRL.bit.RTR = 0;

    //向邮箱RAM区写数据
    ECanbMboxes.MBOX0.MDL.all = 0x00000000;                //0x01234567;     //////////////看手册弄懂
    ECanbMboxes.MBOX0.MDH.all = 0x00000000;                //0x89ABCDEF;
    //邮箱使能Mailbox0
    ECanbShadow.CANME.all = ECanbRegs.CANME.all;
    ECanbShadow.CANME.bit.ME0 = 1;              //////////////
    ECanbShadow.CANME.bit.ME16 = 1;
    ECanbRegs.CANME.all = ECanbShadow.CANME.all;
    ECanbRegs.CANMIM.all = 0xFFFFFFFF;          //邮箱中断使能(只需要测试发送的时候,注释掉该句即可)

    //邮箱中断将产生在ECAN0INT
    ECanbRegs.CANMIL.all = 0;
    ECanbRegs.CANGIF0.all = 0xFFFFFFFF;

    //ECAN0INT中断请求线被使能
    ECanbRegs.CANGIM.bit.I0EN = 1;
    EDIS;

}

 我现在是邮箱编号0、我的阵列将正常发送。 但是、我将 CAN 数据发送到 DSP、而我无法进入接收中断。 但是如果我注释掉0邮箱在主函数中发送的几句话、我将 CAN 数据发送到 DSP、我可以输入中断、并且值正确、我不知道为什么。

谢谢。此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Ben、

      请让客户研究 www.ti.com/lit/SPRA876中的中断示例。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Hareesh。

    我发现当 ECAN 正在发送数据时、不仅需要配置发送邮箱。  您还需要配置接收邮箱。  通过一个只有发送函数的代码更改了我的代码。  0号邮箱发送、16号邮箱接收。  当写入接收代码时、我仍然使用这两个邮箱。  它不应该配置一组发送和接收邮箱。  这样就不应该有冲突。  我想问题出在这里吗?

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我发现当 ECAN 发送数据时,不仅需要配置发送邮箱。  您还需要配置接收邮箱。  [/报价]

    这在正常应用中不正确。 我想您在使用 CAN 模块的自测模式。  

    不应该配置一组发送和接收邮箱。  [/报价]

    不会自动发生任何情况。 如果您需要接收邮箱来接收传输的数据、则需要手动配置它。

    我觉得问题已经解决了吗?
    [/quote]

    不、没有问题。 在自检模式中、如果您希望生成接收中断、您需要使用与发送邮箱相同的 MSGID 来配置接收邮箱。 执行此操作后、当接收到消息时、将生成中断。

    [/quote][/quote]