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.

[参考译文] TMS570LS3137:CAN 中断问题

Guru**** 2560390 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1187718/tms570ls3137-issue-with-can-interruptions

器件型号:TMS570LS3137

您好!

我在试图使 CAN 中断工作时遇到了困难。

如果我通过 HAL 配置标准或扩展 CAN ID、中断工作正常。 但是、如果我想通过代码从标准 CAN 更改为扩展 CAN、或者从扩展 CAN 更改为标准 CAN、CAN 中断将停止工作。  我已经完成了两个函数、这些函数通过 接收 SCI (UART)的命令帮助我从一种格式更改为另一种格式。

使用逻辑分析仪、我已经验证了帧以相应的格式发送、但是中断不会被触发。

我在下面附上两个函数的代码。

//Set standard ID for some CAN interface
void standardId(canBASE_t *canREG)
{
    /** - Initialize message 1
    *     - Wait until IF1 is ready for use
    *     - Set message mask
    *     - Set message control word
    *     - Set message arbitration
    *     - Set IF1 control byte
    *     - Set IF1 message number
    */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG->IF1STAT & 0x80U) ==0x80U)
    {
    } /* Wait */


    canREG->IF1MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x000007FFU) << (uint32)18U);
    canREG->IF1ARB  = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)1U & (uint32)0x000007FFU) << (uint32)18U);
    canREG->IF1MCTL = 0x00001000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
    canREG->IF1CMD  = (uint8) 0xF8U;
    canREG->IF1NO   = 1U;
}

//Set extended ID for some CAN interface
void extendedId(canBASE_t *canREG)
{
    /** - Setup control register
    *     - Disable automatic wakeup on bus activity
    *     - Local power down mode disabled
    *     - Disable DMA request lines
    *     - Enable global Interrupt Line 0 and 1
    *     - Disable debug mode
    *     - Release from software reset
    *     - Enable/Disable parity or ECC
    *     - Enable/Disable auto bus on timer
    *     - Setup message completion before entering debug state
    *     - Setup normal operation mode
    *     - Request write access to the configuration registers
    *     - Setup automatic retransmission of messages
    *     - Disable error interrupts
    *     - Disable status interrupts
    *     - Enter initialization mode
    */
    canREG->CTL = (uint32)0x00000000U
              | (uint32)0x00000020U
              | (uint32)((uint32)0x00000005U << 10U)
              | 0x00020043U;

    /** - Initialize message 1
    *     - Wait until IF1 is ready for use
    *     - Set message mask
    *     - Set message control word
    *     - Set message arbitration
    *     - Set IF1 control byte
    *     - Set IF1 message number
    */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG->IF1STAT & 0x80U) ==0x80U)
    {
    } /* Wait */


    canREG->IF1MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
    canREG->IF1ARB  = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)1U & (uint32)0x1FFFFFFFU) << (uint32)0U);
    canREG->IF1MCTL = 0x00001000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
    canREG->IF1CMD  = (uint8) 0xF8U;
    canREG->IF1NO   = 1U;

    /** - Leave configuration and initialization mode  */
    canREG->CTL &= ~(uint32)(0x00000041U);
}

非常感谢、此致、

莱安德罗

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

    standardID()函数不启用 CAN 中断,CAN 模块仍处于初始化模式。

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

    请发布您的 main()函数。

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

    您好 QJ、

    我意识到我的错误是使用错误的注册表。 现在它可以正常工作(至少现在)。 无论如何,我将离开 main 和一个名为 sysinit()的函数,用于初始化接口。 谢谢你。

    main()函数:

    int main(void)
    {
    /* USER CODE BEGIN (3) */
        sysInit();  //System initialization.
        osInit();   //Operative System initialization.
    
        /* Run forever */
        while(1);
    
    /* USER CODE END */
    
        return 0;
    }

    sysinit()函数:

    /********************
     * sysInit function *
     ********************/
    void sysInit()
    {
        uint8_t generic = 0;
        sciInit();                                      //SCI initialization.
        canInit();                                      //CAN initialization.
        spiInit();                                      //SPI initialization.
    
        //Enable interrupts:
        _enable_interrupt_();                           //General interrupt flag.
        //Enable SCI interrupt:
        sciEnableNotification(scilinREG,SCI_RX_INT);    //Enable SCI interrupt by Rx.
        //Enable CAN interrupt:
        canEnableErrorNotification(canREG2);            //Enable canREG2 interrupt.
        canEnableErrorNotification(canREG3);            //Enable canREG3 interrupt.
    
        sciReceive(scilinREG,1, (unsigned char *)&generic);
    
        sciSend(scilinREG, 37, (unsigned char *)"Initializing system. Please wait...\r\n");
        gioInit();                                      //GIO module initialization.
        gioSetDirection(hetPORT1, 1 << 15);             //Enable N2HET1[15] as output. This is the output signal to the external watch-dog.
        gioSetDirection(spiPORT3, 0x11);                //to set the SPI3NCS[0] to output direction. The SPI3NCS[0] is the bit0 of SPIPC1 register.
                                                        //to set the SPI3NCS[4] to output direction. The SPI3NCS[4] is the bit4 of SPIPC1 register.
        gioSetDirection(mibspiPORT5, 0 <<9);
        gioSetDirection(mibspiPORT1, 0 <<1);
        gioSetBit(spiPORT3, 0, 1);                      //Disable External memories SPI communication
        gioSetBit(spiPORT3, 4, 1);                      //Disable External memories SPI communication
    
        sExtMem(0);                                     //Set external memory U22 in low power mode.
        sExtMem(4);                                     //Set external memory U23 in low power mode.
    
        sciSend(scilinREG, 27, (unsigned char *)"\t************************\r\n");
        sciSend(scilinREG, 27, (unsigned char *)"\tLabOSat-02 [OBC] OS V1.0\r\n");
        sciSend(scilinREG, 27, (unsigned char *)"\t************************\r\n");
        sciSend(scilinREG, 1, (unsigned char *)"\n");
        sciSend(scilinREG, 14, (unsigned char *)"Developers: \r\n");
        sciSend(scilinREG, 30, (unsigned char *)"\t Gagliardi Leandro Luciano \r\n");
        sciSend(scilinREG, 22, (unsigned char *)"\t Di Nardo Federico \r\n");
        sciSend(scilinREG, 1, (unsigned char *)"\n");
    }

    我将这两个函数合并为一个名为 sizeId()的函数。 现在还不错:)。

    void sizeId(canBASE_t *canREG, bool size)
    {
        /** - Setup control register
        *     - Disable automatic wakeup on bus activity
        *     - Local power down mode disabled
        *     - Disable DMA request lines
        *     - Enable global Interrupt Line 0 and 1
        *     - Disable debug mode
        *     - Release from software reset
        *     - Enable/Disable parity or ECC
        *     - Enable/Disable auto bus on timer
        *     - Setup message completion before entering debug state
        *     - Setup normal operation mode
        *     - Request write access to the configuration registers
        *     - Setup automatic retransmission of messages
        *     - Disable error interrupts
        *     - Disable status interrupts
        *     - Enter initialization mode
        */
        canREG->CTL = (uint32)0x00000000U
                  | (uint32)0x00000020U
                  | (uint32)((uint32)0x00000005U << 10U)
                  | 0x00020043U;
    
        /** - Initialize message 1
        *     - Wait until IF1 is ready for use
        *     - Set message mask
        *     - Set message control word
        *     - Set message arbitration
        *     - Set IF1 control byte
        *     - Set IF1 message number
        */
        /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
        while ((canREG->IF1STAT & 0x80U) ==0x80U)
        {
        } /* Wait */
    
        switch (size)
        {
        case false:
            if(canREG == canREG2)
            {
                canREG2->IF2MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x000007FFU) << (uint32)18U);
                canREG2->IF2ARB  = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)((uint32)((uint32)2U & (uint32)0x000007FFU) << (uint32)18U);
                canREG2->IF2MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
                canREG2->IF2CMD  = (uint8) 0xF8U;
                canREG2->IF2NO   = 2U;
            }else if (canREG == canREG3)
            {
                canREG3->IF1MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x000007FFU) << (uint32)18U);
                canREG3->IF1ARB  = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)1U & (uint32)0x000007FFU) << (uint32)18U);
                canREG3->IF1MCTL = 0x00001000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
                canREG3->IF1CMD  = (uint8) 0xF8U;
                canREG3->IF1NO   = 1U;
            }
            break;
        case true:
            if(canREG == canREG2)
            {
                canREG2->IF2MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
                canREG2->IF2ARB  = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x00000000U | (uint32)((uint32)((uint32)2U & (uint32)0x1FFFFFFFU) << (uint32)0U);
                canREG2->IF2MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
                canREG2->IF2CMD  = (uint8) 0xF8U;
                canREG2->IF2NO   = 2U;
            }else if (canREG == canREG3)
            {
                canREG3->IF1MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
                canREG3->IF1ARB  = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)1U & (uint32)0x1FFFFFFFU) << (uint32)0U);
                canREG3->IF1MCTL = 0x00001000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
                canREG3->IF1CMD  = (uint8) 0xF8U;
                canREG3->IF1NO   = 1U;
            }
    
            break;
        default:
            break;
        }
        /** - Leave configuration and initialization mode  */
        canREG->CTL &= ~(uint32)(0x00000041U);
    
        canEnableErrorNotification(canREG2);            //Enable canREG2 interrupt.
        canEnableErrorNotification(canREG3);            //Enable canREG3 interrupt.
    }

    此致、

    莱安德罗

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

    您好、Leandro、

    [引用 userid="430073" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1187718/tms570ls3137-issue-with-can-interruptions/4474804 #4474804"]我意识到我的错误是使用错误的注册表。

    很高兴听到您的代码正在工作。

    --

    谢谢、此致、

    Jagadish。