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.

[参考译文] TMS320F2.802万:使用SCI接收长度为1-20字节的消息

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1098295/tms320f28020-using-sci-for-receiving-messages-of-lengths-from-1-20-bytes

部件号:TMS320F2.802万
主题中讨论的其他部件:C2000WARE

大家好,

我正在寻找一些建议,以了解如何实施SCI模块来接收10到20字节的消息。  我承认需要分析例程来识别每条消息,但这似乎并不困难,因为每条消息都以回车符和换行符结束。  我只是在寻求将数据接收到数组中的帮助。

我从TIREX导入了Driverlib示例代码"example_F2802xSci_FFDLB.c",它正在与外部设备通信。  但是,该代码使用四级fifo,这对于接收不同长度的消息似乎并不是最佳的。  以下是供参考的代码:

//#############################################################################
//
//  File:   Example_F2802xSci_FFDLB.c
//
//  Title:  F2802x Device SCI FIFO Digital Loop Back Test.
//
//! \addtogroup example_list
//!  <h1>SCI FIFO Digital Loop Back</h1>
//!
//!   This test uses the loopback test mode of the SCI module to send
//!   characters starting with 0x00 through 0xFF.  The test will send
//!   a character and then check the receive buffer for a correct match.
//!
//!   Watch Variables:
//!   - LoopCount - Number of characters sent
//!   - ErrorCount - Number of errors detected
//!   - SendChar - Character sent
//!   - ReceivedChar - Character received
//
//#############################################################################
// $TI Release: F2802x Support Library v3.05.00.00 $
// $Release Date: 10-19-2021 $
// $Copyright:
// Copyright (C) 2009-2021 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################

//
// Included Files
//
#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
#include <stdio.h>
#include <file.h>

#include "common/include/adc.h"
#include "common/include/clk.h"
#include "common/include/flash.h"
#include "common/include/gpio.h"
#include "common/include/pie.h"
#include "common/include/pll.h"
#include "common/include/sci.h"
#include "common/include/wdog.h"

//
// Function Prototypes
//
void scia_init(void);
void scia_fifo_init(void);
void scia_xmit(int a);
void error(void);

//
// Globals
//
uint16_t LoopCount;
uint16_t ErrorCount;

ADC_Handle myAdc;
CLK_Handle myClk;
FLASH_Handle myFlash;
GPIO_Handle myGpio;
PIE_Handle myPie;
SCI_Handle mySci;

//
// Main
//
void main(void)
{
    uint16_t SendChar;
    uint16_t ReceivedChar;

    CPU_Handle myCpu;
    PLL_Handle myPll;
    WDOG_Handle myWDog;

    //
    // Initialize all the handles needed for this application
    //
    myAdc = ADC_init((void *)ADC_BASE_ADDR, sizeof(ADC_Obj));
    myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_Obj));
    myCpu = CPU_init((void *)NULL, sizeof(CPU_Obj));
    myFlash = FLASH_init((void *)FLASH_BASE_ADDR, sizeof(FLASH_Obj));
    myGpio = GPIO_init((void *)GPIO_BASE_ADDR, sizeof(GPIO_Obj));
    myPie = PIE_init((void *)PIE_BASE_ADDR, sizeof(PIE_Obj));
    myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj));
    mySci = SCI_init((void *)SCIA_BASE_ADDR, sizeof(SCI_Obj));
    myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj));

    //
    // Perform basic system initialization
    //
    WDOG_disable(myWDog);
    CLK_enableAdcClock(myClk);
    (*Device_cal)();

    //
    // Select the internal oscillator 1 as the clock source
    //
    CLK_setOscSrc(myClk, CLK_OscSrc_Internal);

    //
    // Setup the PLL for x10 /2 which will yield 50Mhz = 10Mhz * 10 / 2
    //
    PLL_setup(myPll, PLL_Multiplier_10, PLL_DivideSelect_ClkIn_by_2);

    //
    // Disable the PIE and all interrupts
    //
    PIE_disable(myPie);
    PIE_disableAllInts(myPie);
    CPU_disableGlobalInts(myCpu);
    CPU_clearIntFlags(myCpu);

    //
    // If running from flash copy RAM only functions to RAM
    //
#ifdef _FLASH
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
#endif

    //
    // Setup GPIO
    //
    GPIO_setPullUp(myGpio, GPIO_Number_28, GPIO_PullUp_Enable);
    GPIO_setPullUp(myGpio, GPIO_Number_29, GPIO_PullUp_Disable);
    GPIO_setQualification(myGpio, GPIO_Number_28, GPIO_Qual_ASync);
    GPIO_setMode(myGpio, GPIO_Number_28, GPIO_28_Mode_SCIRXDA);
    GPIO_setMode(myGpio, GPIO_Number_29, GPIO_29_Mode_SCITXDA);

    //
    // Setup a debug vector table and enable the PIE
    //
    PIE_setDebugIntVectorTable(myPie);
    PIE_enable(myPie);

    LoopCount = 0;
    ErrorCount = 0;

    scia_init();                // Initialize SCI for digital loop back
    scia_fifo_init();           // Initialize the SCI FIFO

    //
    // Send a character starting with 0
    //
    SendChar = 0;

    //
    // Send Characters forever starting with 0x00 and going through 0xFF.
    // After sending each, check the receive buffer for the correct value
    //
    for(;;)
    {
        SCI_putDataBlocking(mySci, SendChar);

        while(SCI_getRxFifoStatus(mySci) == SCI_FifoStatus_Empty)
        {
            
        }

        //
        // Check received character
        //
        ReceivedChar = SCI_getData(mySci);
        if(ReceivedChar != SendChar)
        {
            error();
        }

        //
        // Move to the next character and repeat the test
        //
        SendChar++;
        
        //
        // Limit the character to 8-bits
        //
        SendChar &= 0x00FF;
        LoopCount++;
    }
}

//
// Step 7. Insert all local Interrupt Service Routines (ISRs) and 
// functions here:
//

//
// error - 
//
void
error(void)
{
    ErrorCount++;
    __asm(" ESTOP0");       // Uncomment to stop the test here
    for (;;)
    {
        
    }

}

//
// scia_init - 
//
void
scia_init()
{
    CLK_enableSciaClock(myClk);

    //
    // 1 stop bit,  No loopback, No parity,8 char bits, async mode,
    // idle-line protocol
    //
    SCI_disableParity(mySci);
    SCI_setNumStopBits(mySci, SCI_NumStopBits_One);
    SCI_setCharLength(mySci, SCI_CharLength_8_Bits);

    //
    // enable TX, RX, internal SCICLK, Disable RX ERR, SLEEP, TXWAKE
    //
    SCI_enableTx(mySci);
    SCI_enableRx(mySci);
    SCI_enableTxInt(mySci);
    SCI_enableRxInt(mySci);

    SCI_enableLoopBack(mySci);

    //SCI BRR = LSPCLK/(SCI BAUDx8) - 1
#if (CPU_FRQ_50MHZ)
    SCI_setBaudRate(mySci, SCI_BaudRate_9_6_kBaud);
#elif (CPU_FRQ_40MHZ)
    SCI_setBaudRate(mySci, (SCI_BaudRate_e)129);
#endif

    SCI_enable(mySci);

    return;
}

//
// scia_fifo_init - Initialize the SCI FIFO
//
void
scia_fifo_init()
{
    SCI_enableFifoEnh(mySci);
    SCI_resetTxFifo(mySci);
    SCI_clearTxFifoInt(mySci);
    SCI_resetChannels(mySci);
    SCI_setTxFifoIntLevel(mySci, SCI_FifoLevel_Empty);

    SCI_resetRxFifo(mySci);
    SCI_clearRxFifoInt(mySci);
    SCI_setRxFifoIntLevel(mySci, SCI_FifoLevel_4_Words);

    return;
}

//
// End of File
//

下面是一个逻辑分析器图像,其中一条较长的消息是:

下面是一个简短的问题:

问题:

1.我不需要使用ISR,但我应该使用ISR吗?

2.我是否应该放弃fifo,转而采用流式传输方法?

3.您是否可以向我指出一个能够解决这些问题的TI应用说明?

4.您能告诉我一些示例代码吗?

提前感谢!
罗宾

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

    您好,Robin:

    1.</s>2.802万 我不需要使用ISR,但我应该使用它吗?[/QUOT]

    这取决于您在整个应用程序中所执行的操作。 如果您仅将此设备用于串行通信,则可以避免使用ISR。 如果CPU需要处理其他组件,我建议使用ISR。  

    2.</s>2.802万 我是否应该放弃fifo而选择流式传输方法?[/QUOT]

    由于您接收的消息介于10到20字节之间,我认为流式传输方法是更容易的选择。 我们的FIFO级别在此设备上最多只能达到4。  

    3.</s>2.802万 您能向我指出一个能够解决这些问题的TI应用说明吗?[/QUOT]

    遗憾的是,我们没有涵盖这些主题的任何应用手册。

    4.</s>2.802万 您能告诉我一些示例代码吗?[/QUOT]

    我们拥有的唯一示例代码是C2000Ware中的代码。

    此致,

    Marlyn

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

    感谢您的快速响应,Marlyn。

    要从fifo切换到流式传输方法,我执行了以下操作:

    1.注释掉fifo初始化调用:

    //
    // scia_fifo_init - Initialize the SCI FIFO
    //
    void scia_fifo_init()
    {
    //    SCI_enableFifoEnh(mySci);
    //    SCI_resetTxFifo(mySci);
    //    SCI_clearTxFifoInt(mySci);
    //    SCI_resetChannels(mySci);
    //    SCI_setTxFifoIntLevel(mySci, SCI_FifoLevel_Empty);
    
    //    SCI_resetRxFifo(mySci);
    //    SCI_clearRxFifoInt(mySci);
    //    SCI_setRxFifoIntLevel(mySci, SCI_FifoLevel_4_Words);
    
        return;
    }
    

    2.保持非fifo SCI初始化状态:

    void scia_init()
    {
        CLK_enableSciaClock(myClk);
    
        //
        // 1 stop bit,  No loopback, No parity,8 char bits, async mode,
        // idle-line protocol
        //
        SCI_disableParity(mySci);
        SCI_setNumStopBits(mySci, SCI_NumStopBits_One);
        SCI_setCharLength(mySci, SCI_CharLength_8_Bits);
    
        //
        // enable TX, RX, internal SCICLK, Disable RX ERR, SLEEP, TXWAKE
        //
        SCI_enableTx(mySci);
        SCI_enableRx(mySci);
        SCI_enableTxInt(mySci);
        SCI_enableRxInt(mySci);
    
    //    SCI_enableLoopBack(mySci);
    
        SCI_setBaudRate(mySci, (SCI_BaudRate_e)162);	//rdv 9615 BAUD
    
        SCI_enable(mySci);
    
        return;
    }
    

    3.更改等待从以下位置接收字节的代码位:

    	    while(SCI_getRxFifoStatus(mySci) == SCI_FifoStatus_Empty)
    	    {
                greenSwPressed = (GPIO_getData(myGpio, GRN_SW)) ? 0 : 1;
                redSwPressed   = (GPIO_getData(myGpio, RED_SW)) ? 0 : 1;
    
                if(redSwPressed & !redLED)
                {
                    GPIO_setHigh(myGpio, RED_LED);
                } else if(!redSwPressed & !redLED)
                {
                    GPIO_setLow(myGpio, RED_LED);
                }
    
                if(greenSwPressed & !greenLED)
                {
                    GPIO_setHigh(myGpio, GREEN_LED);
                } else if(!greenSwPressed & !greenLED)
                {
                    GPIO_setLow(myGpio, GREEN_LED);
                }
    
    	        if(i2cSelVar)
                {
    
                }
    
                if(detectVar)
                {
    
                }
    
    	        if(redLED & greenLED & blueLED)
    	        {
                    GPIO_setHigh(myGpio, I2C_SEL);
                    GPIO_setHigh(myGpio, DETECT);
    	            detectVar = GPIO_getData(myGpio, DETECT);
    	        } else
    	        {
                    GPIO_setLow(myGpio, I2C_SEL);
                    GPIO_setLow(myGpio, DETECT);
                    detectVar = GPIO_getData(myGpio, DETECT);
    	        }
            }
    

    4.为此:

    	    while(SCI_isRxDataReady(mySci) != true)
    	    {
                greenSwPressed = (GPIO_getData(myGpio, GRN_SW)) ? 0 : 1;
                redSwPressed   = (GPIO_getData(myGpio, RED_SW)) ? 0 : 1;
    
                if(redSwPressed & !redLED)
                {
                    GPIO_setHigh(myGpio, RED_LED);
                } else if(!redSwPressed & !redLED)
                {
                    GPIO_setLow(myGpio, RED_LED);
                }
    
                if(greenSwPressed & !greenLED)
                {
                    GPIO_setHigh(myGpio, GREEN_LED);
                } else if(!greenSwPressed & !greenLED)
                {
                    GPIO_setLow(myGpio, GREEN_LED);
                }
    
    	        if(i2cSelVar)
                {
    
                }
    
                if(detectVar)
                {
    
                }
    
    	        if(redLED & greenLED & blueLED)
    	        {
                    GPIO_setHigh(myGpio, I2C_SEL);
                    GPIO_setHigh(myGpio, DETECT);
    	            detectVar = GPIO_getData(myGpio, DETECT);
    	        } else
    	        {
                    GPIO_setLow(myGpio, I2C_SEL);
                    GPIO_setLow(myGpio, DETECT);
                    detectVar = GPIO_getData(myGpio, DETECT);
    	        }
            }
    

    5.收到SCIRXBUF中的字节后,以下是提取消息的代码:

     	   byteReceived = SCI_getData(mySci);
           if(byteReceived != 10 && byteReceived != 13)
           {
               receivedByteFlag = 1;
               message[rdvWordCount++] = (char)byteReceived;
               rdvWordCount &= 0x7F;    //rdv Limit buffer range to 0-127
           }
    

    它的效果很好。

    我可以选择使用ISR来实现接收功能。  没有它就能工作,但这似乎是一种更干净的方法。  我相信在这一过程中会有更多的改进,但这提供了我所需的功能。

    谢谢!
    罗宾