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.

TMS320F280049: 两个同款芯片之间利用SCI通信时通信不正常

Part Number: TMS320F280049


根据图示进行通信时,MCU2的所有SCI相关引脚都有数据信号,但MCU1的SCI-A的TX引脚经常没有数据发送,重新上电几次后MCU1的SCI-A又可以重新通信

每次开机都要连续重新上电几次才能正常根据图示通信,两款芯片均为TMS320F280049芯片

  • 两块板子的硬件都相同吗?有没有互换一下位置测试一下?或者说,硬件上能确保MCU1能运行正常吗?

  • 两块板子硬件相同,当我用XDS110调试器,调试MCU2时,MCU2的所有SCI都正常,而MCU1的SCI-A的发送端没有任何数据,其余SCI的数据正常

    当我用XDS110调试器调试MCU1时,MCU1的所有SCI都正常,而MCU2的SCI-A的发送端没有任何数据,其余SCI的数据正常

    当其中一个不正常时,重复上电又都能正常通信

    MCU的代码都是从电脑接收到SCI-A的数据时将数据从SCI-B发送给另一个MCU,另一个MCU在SCI-B接收到数据时将数据从SCI-A发送到电脑

  • 以下是SCI-A的初始化

    void HAL_setupSCI(void)
    {
        //
        // GPIO28 is the SCI Rx pin.
        //
        GPIO_setPinConfig(DEVICE_GPIO_CFG_SCIRXDA);
        GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCIRXDA, GPIO_DIR_MODE_IN);
        GPIO_setPadConfig(DEVICE_GPIO_PIN_SCIRXDA, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCIRXDA, GPIO_QUAL_ASYNC);
    
        //
        // GPIO29 is the SCI Tx pin.
        //
        GPIO_setPinConfig(DEVICE_GPIO_CFG_SCITXDA);
        GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCITXDA, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(DEVICE_GPIO_PIN_SCITXDA, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCITXDA, GPIO_QUAL_ASYNC);
    
        //
        // Map the ISR to the wake interrupt.
        //
        Interrupt_register(INT_SCIA_TX, &sciaTxISR);
        Interrupt_register(INT_SCIA_RX, &sciaRxISR);
    
        //
        // Initialize SCIA and its FIFO.
        //
        SCI_performSoftwareReset(SCIA_BASE);
    
        //
        // 50000000 is the LSPCLK or the Clock used for the SCI Module
        // 57600 is the Baudrate desired of the SCI module
        // 1 stop bit,  No parity, 8 char bits,
        //
        SCI_setConfig(SCIA_BASE, LSPCLK_FREQ_H, 19200,
                (SCI_CONFIG_WLEN_8 |
                        SCI_CONFIG_STOP_ONE |
                        SCI_CONFIG_PAR_NONE));
    
        
        //
        //No loopback
        //
        SCI_disableLoopback(SCIA_BASE);
    
        SCI_resetChannels(SCIA_BASE);
        SCI_resetRxFIFO(SCIA_BASE);
        SCI_resetTxFIFO(SCIA_BASE);
        SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_TXFF | SCI_INT_RXFF);
        SCI_enableFIFO(SCIA_BASE);
        SCI_enableModule(SCIA_BASE);
        SCI_performSoftwareReset(SCIA_BASE);
    
        //
        // Set the transmit FIFO level to 0 and the receive FIFO level to 2.
        // Enable the TXFF and RXFF interrupts.
        //
        SCI_setFIFOInterruptLevel(SCIA_BASE, SCI_FIFO_TX0, SCI_FIFO_RX1);
        SCI_enableInterrupt(SCIA_BASE, SCI_INT_TXFF | SCI_INT_RXFF);
    
        //
        // Clear the SCI interrupts before enabling them.
        //
        SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_TXFF | SCI_INT_RXFF);
    
        //
        // Enable the interrupts in the PIE: Group 9 interrupts 1 & 2.
        //
        Interrupt_enable(INT_SCIA_RX);
        Interrupt_enable(INT_SCIA_TX);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }

    以下是SCI-A的中断服务函数

    发送中断:

    interrupt void sciaTxISR(void)
    {
        //
        // Disable the TXRDY interrupt.
        //
        SCI_disableInterrupt(SCIA_BASE, SCI_INT_TXFF);
    
        while (SciTxPointEnd != SciTxPointHead) {
            SCI_writeCharBlockingFIFO(SCIA_BASE,(uint16_t)SciTxBuf[SciTxPointEnd]);
            SciTxPointEnd ++ ;
            if (SciTxPointEnd == TxLen)
                SciTxPointEnd = 0;
        }
        SciTxPointEnd = SciTxPointHead = 0;
        memset(SciTxBuf,0,TxLen);
        //
        // Acknowledge the PIE interrupt.
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }

    接收中断:

    interrupt void sciaRxISR(void)
    {
        //
        // Read characters from the FIFO.
        //
        //每次中断接收到数据SciRxPointHead就相当于指针在数组上后移一位
        //如果SciRxPointHead已经指到数组最后一位,那么又重头开始指
        SciRxBuf[SciRxPointHead] = SCI_readCharBlockingFIFO(SCIA_BASE);
        SciRxPointHead ++;
        if (SciRxPointHead == RxLen)
            SciRxPointHead = 0;
    
        //
        // Clear the SCI RXFF interrupt and acknowledge the PIE interrupt.
        //
        SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    
    }

    以下是SCI-B的初始化代码

    void HAL_setupSCIB(void)
    {
        //
        // GPIO13 is the SCI Rx pin.
        //
        GPIO_setPinConfig(DEVICE_GPIO_CFG_SCIRXDB);
        GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCIRXDB, GPIO_DIR_MODE_IN);
        GPIO_setPadConfig(DEVICE_GPIO_PIN_SCIRXDB, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCIRXDB, GPIO_QUAL_ASYNC);
    
        //
        // GPIO12 is the SCI Tx pin.
        //
        GPIO_setPinConfig(DEVICE_GPIO_CFG_SCITXDB);
        GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCITXDB, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(DEVICE_GPIO_PIN_SCITXDB, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCITXDB, GPIO_QUAL_ASYNC);
    
        //
        // Map the ISR to the wake interrupt.
        //
        Interrupt_register(INT_SCIB_TX, &scibTxISR);
        Interrupt_register(INT_SCIB_RX, &scibRxISR);
    
        //
        // Initialize SCIB and its FIFO.
        //
        SCI_performSoftwareReset(SCIB_BASE);
    
        //
        // 50000000 is the LSPCLK or the Clock used for the SCI Module
        // 57600 is the Baudrate desired of the SCI module
        // 1 stop bit,  No parity, 8 char bits,
        //
        SCI_setConfig(SCIB_BASE, LSPCLK_FREQ_H, 19200,
                (SCI_CONFIG_WLEN_8 |
                        SCI_CONFIG_STOP_ONE |
                        SCI_CONFIG_PAR_NONE));
    
        //
        //No loopback
        //
        SCI_disableLoopback(SCIB_BASE);
    
        SCI_resetChannels(SCIB_BASE);
        SCI_resetRxFIFO(SCIB_BASE);
        SCI_resetTxFIFO(SCIB_BASE);
        SCI_clearInterruptStatus(SCIB_BASE, SCI_INT_TXFF | SCI_INT_RXFF);
        SCI_enableFIFO(SCIB_BASE);
        SCI_enableModule(SCIB_BASE);
        SCI_performSoftwareReset(SCIB_BASE);
    
        //
        // Set the transmit FIFO level to 0 and the receive FIFO level to 2.
        // Enable the TXFF and RXFF interrupts.
        //
        SCI_setFIFOInterruptLevel(SCIB_BASE, SCI_FIFO_TX0, SCI_FIFO_RX1);
        SCI_enableInterrupt(SCIB_BASE, SCI_INT_TXFF | SCI_INT_RXFF);
    
        //
        // Clear the SCI interrupts before enabling them.
        //
        SCI_clearInterruptStatus(SCIB_BASE, SCI_INT_TXFF | SCI_INT_RXFF);
    
        //
        // Enable the interrupts in the PIE: Group 9 interrupts 3 & 4.
        //
        Interrupt_enable(INT_SCIB_RX);
        Interrupt_enable(INT_SCIB_TX);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    

    以下是SCI-B的中断服务函数

    发送中断:

    interrupt void scibTxISR(void)
    {
        //
        // Disable the TXRDY interrupt.
        //
        SCI_disableInterrupt(SCIB_BASE, SCI_INT_TXFF);
    
        while (ScibTxPointEnd != ScibTxPointHead) {
            SCI_writeCharBlockingFIFO(SCIB_BASE,(uint16_t)ScibTxBuf[ScibTxPointEnd]);
            ScibTxPointEnd ++ ;
            if (ScibTxPointEnd == TxLen)
                ScibTxPointEnd = 0;
        }
        ScibTxPointEnd = ScibTxPointHead = 0;
        memset(ScibTxBuf,0,TxLen);
        //
        // Acknowledge the PIE interrupt.
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }

    接收中断:

    interrupt void scibRxISR(void)
    {
        //
        // Read characters from the FIFO.
        //
        //
        //
        ScibRxBuf[ScibRxPointHead] = SCI_readCharBlockingFIFO(SCIB_BASE);
        ScibRxPointHead ++;
        if (ScibRxPointHead == RxLen)
            ScibRxPointHead = 0;
    
        //
        // Clear the SCI RXFF interrupt and acknowledge the PIE interrupt.
        //
        SCI_clearInterruptStatus(SCIB_BASE, SCI_INT_RXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }

    循环事件中的测试代码:

    void SCI_Receive_Debug(void)
    {
        //SCIA的接收
        while(SciRxPointHead != SciRxPointEnd){
            //正在接收数据
            ReceiveCMD[SciDataRxLen] = SciRxBuf[SciRxPointEnd];//记录接收内容
            SciDataRxLen ++;//记录接收长度
            SciRxPointEnd ++;
            if (SciRxPointEnd == RxLen){
                SciRxPointEnd = 0;
            }
            if(SciDataRxLen == RxLen){
                SciDataRxLen = 0;
            }
        }
        if(ReceiveCMD[0] != 0x00)//无论A接收到什么,都从B重新发出
        {
           SendMessageToSCIB(SCIB_BASE,ReceiveCMD);
           memset(ReceiveCMD,0,RxLen);
           SciDataRxLen = 0;
        }
        //SCIB的接收
        while(ScibRxPointHead != ScibRxPointEnd)
        {
            //正在接收数据
            ReceiveCMDB[SciDataRxLen] = ScibRxBuf[ScibRxPointEnd];//记录接收内容
            SciDataRxLen ++;//记录接收长度
            ScibRxPointEnd ++;
            if (ScibRxPointEnd == RxLen){
                ScibRxPointEnd = 0;
            }
            if(SciDataRxLen == RxLen){
                SciDataRxLen = 0;
            }
        }
        if(ReceiveCMDB[0] != 0x00)//无论B接收到什么,都从A重新发出
        {
           SendMessageToSCI(SCIA_BASE,ReceiveCMDB);
           memset(ReceiveCMDB,0,RxLen);
           SciDataRxLen = 0;
        }
    }

  • 你好,这边看了一下你的程序,应该没有什么问题,“重启能运行”这点也基本说明程序可以运行。但是这个现象确实没有什么根据,我这边建议你在英文E2E论坛上咨询一下这个问题,英文论坛的工程师可能有其他建议可以参考。

    e2e.ti.com/.../c2000-microcontrollers-forum

  • 我去问问吧,先谢谢了

  • 已经找到问题在哪了,两个芯片通信时IO配置有问题,输出IO应配置为开漏输出,输入IO应配置为内部上拉输入