TI LM3S同时使用两个以上串口的方法

ooakk   2012-7-18 20:21 楼主
TI LM3S同时使用两个以上的串口正确的方法
自己编写函数:
//*****************************************************************************
//
//! Changes UART printf output port.
//!
//! \param ulPortNum is the number of UART port to use for the serial console
//! (0-2)
//!
//! \return None.
//
//*****************************************************************************
void
UARTPrintfPortChange(unsigned long ulPortNum)
{
    //
    // Select the base address of the UART.
    //
    g_ulBase = g_ulUARTBase[ulPortNum];
}
把该函数放在需要修改的地方即可。

下面简单说明原理

g_ulBase为全局变量,用于选择UART。
TI固有函数
void UARTStdioInitExpClk(unsigned long ulPortNum, unsigned long ulBaud)
初始化串口时,有定义g_ulBase
    //
    // Select the base address of the UART.
    //
    g_ulBase = g_ulUARTBase[ulPortNum];
初始化之后,所有有关串口操作的函数都要根据g_ulBase来选定串口。
因此,修改g_ulBase即可修改串口。:rose:
其他不可取的方法有:初始化一个串口,使用后除能,然后再初始化另一个串口。这样效率低下,速度也打不到应用需求,也容易出现初始化错误。

回复评论 (7)

谢谢楼主分享 学习一下先
点赞  2012-7-19 09:34

回复 楼主 ooakk 的帖子

只改了 base address 还不行吧?管脚也要配置啊?
而且初始化一开始做完了之后,后续就不用管了。
点赞  2012-7-19 13:26
ULONG LM3S_UART_Init(ULONG ulBase, ULONG ulBaudRate)
{
    switch(ulBase)
    {
    case UART0_BASE:
        /*初始化UART0*/
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        GPIOPinConfigure(GPIO_PA1_U0TX);
        GPIOPinConfigure(GPIO_PA0_U0RX);
        //GPIODirModeSet(GPIO_PORTA_BASE, GPIO_PIN_0|GPIO_PIN_1, GPIO_DIR_MODE_HW);
        break;
    case UART1_BASE:
        /*初始化UART1*/
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
        GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7);
                GPIOPinConfigure(GPIO_PC6_U1RX);
                GPIOPinConfigure(GPIO_PC7_U1TX);
        GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7, GPIO_DIR_MODE_HW);
        break;
        case UART2_BASE:
                /*初始化UART2*/
                SysCtlPeripheralEnable(SYSCTL_PERIPH_UART2);
                GPIOPinTypeUART(GPIO_PORTG_BASE, GPIO_PIN_0 | GPIO_PIN_1);
                GPIOPinConfigure(GPIO_PG0_U2RX);
                GPIOPinConfigure(GPIO_PG1_U2TX);
                GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW);
                break;
    default:
        DRV_DBGASSERT(0);
        break;
    }

    UARTConfigSetExpClk(ulBase, SysCtlClockGet(), ulBaudRate,
                                           UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                                           UART_CONFIG_PAR_NONE);

    return SYS_NO_ERROR;
}
点赞  2012-7-19 15:36
一楼提到的方法项目背景为:
LM3S作为控制器,同时与DSP和FPGA分别通过两个串口进行通信。
正如 Study_Stellaris大佬说的那样,用到的两个串口都需要初始化,其代码为:
    //
    // Initiates connections to DPS or FPGA via UARTs.
    // UartPrintf function allows only one uart port work simultaneously,
    // RDK-IDM-L35 ARM board connects to DSP and  FPGA
    // through UART2 and UART0 respectively.
    // DSP is served as coefficient caculating, FPGA is served as processing
    // unit, and ARM is served as user interface and control unit.
    // Using function "UARTPrintfPortChange()" in file "commands.c" to
    // change UARTPrintf uart port.
    //

    //
    // Initiation UART0(for FPGA) and UART2(for DSP)
    //
    //
    // Enable UART
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Configure the UART pins appropriately.
    //
    GPIOPinTypeUART(GPIO_PORTG_BASE, GPIO_PIN_1 | GPIO_PIN_0);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_1 | GPIO_PIN_0);

    //
    // Initialize the UART as a console for text I/O.
    //
    UARTStdioInit(UART2DSP);
    UARTStdioInit(UART0FPGA);

一楼提到的串口切换函数
void UARTPrintfPortChange(unsigned long ulPortNum)
的具体应用代码举例如下:
//*****************************************************************************
//
// Handles paint requests for send out parameters via UART.
//
//*****************************************************************************
void
ParameterSubmit(tWidget *pWidget)
{
    unsigned long ulType,ulOrder,ulFl,ulFh,ulFs,ulWn,ulBeta;
    unsigned long ulParameterErr = 0;
//    char *pcFlagCoeffiRef = "coefficient";
//    unsigned char *pcFlagCoeffi;
    int iCount;
   
//-----------------------------------------------
// part1 check parameters
//-----------------------------------------------   
    ulType = g_sTypeIdx;
    ulOrder = g_ulParameter[0];
    ulFl = g_ulParameter[1];
    ulFh = g_ulParameter[2];
    ulBeta = g_ulParameter[3];
    ulFs = 200*1000000;
    ulWn = g_sWindowsIdx;
    //
    // Change UARTprintf prot for FPGA(default debug port)
    //
    UARTPrintfPortChange(UART0FPGA);
   
    UARTprintf("\n");
    UARTprintf("\n");
    UARTprintf("-------------------------------------------------------\n\n");
    UARTprintf("Check parameters.\n");
   
    if (ulType > 3)                                       ulParameterErr = typeErr;
    if (ulOrder < 1 || ulOrder > NUM_FILTERORDER)  ulParameterErr = orderErr;
    if (ulType > 1 && ulFh < ulFl)                    ulParameterErr = flErr;
    if (ulFl > BAND_WIDTH)                 ulParameterErr = flErr;
    if (ulFh > BAND_WIDTH)                 ulParameterErr = fhErr;
    if (ulFs < SAMPLINGRATE_MIN)         ulParameterErr = fsErr;
    if (ulWn > 6)                             ulParameterErr = wnErr;
    if (ulWn == 6 && ulBeta <3 && ulBeta > 10)         ulParameterErr = betaErr;
   
    if (ulParameterErr)
    {
    UARTprintf("Paramter error!\n");
    switch (ulParameterErr)
    {
      case typeErr:         UARTprintf("You chose invaild filter type.\n");                 break;
      case orderErr:         UARTprintf("You typed in invaild filter order.\n");                 break;
      case flErr:         UARTprintf("You typed in invaild filter lower cutoff frequency.\n");         break;
      case fhErr:         UARTprintf("You typed in invaild filter higher cutoff frequency.\n");         break;
      case fsErr:         UARTprintf("Check filter sampling frequency.\n");         break;
      case wnErr:         UARTprintf("You chose invaild filter window.\n");                 break;
      case betaErr:         UARTprintf("Beta of Kaiser window(3 < beta <10).\n");                 break;
      default: break;
    }

    //
    // Show error info
    //
    PushButtonTextSet(&g_sCanvas1, "PARAMETER ERROR!");
    WidgetPaint((tWidget *)&g_sCanvas1);
    return;
    }
    UARTprintf("Pass.\n");
//    g_ulNumofCoefficient = ulOrder;

//-----------------------------------------------
// part2 send filter parameters and get coefficients to and from DSP
//-----------------------------------------------

    //
    // Change UARTprintf prot for DSP
    //
    UARTPrintfPortChange(UART2DSP);
   
    //
    // Now,output filter parameters to DSP
    //

    UARTprintf("%d\n", ulType);
    UARTprintf("%d\n", ulOrder);
    UARTprintf("%d\n", ulFl);
    UARTprintf("%d\n", ulFh);
    UARTprintf("%d\n", ulFs);
    UARTprintf("%d\n", ulWn);
    UARTprintf("%d\n", ulBeta);
   

    //
    // Get coefficients from DSP, the format is defined by DSP
    //
    iCount = UARTgetc();
//    while(!strcmp(pcFlagCoeffiRef,pcFlagCoeffi))
//    {
//    }
    //
    // Here, we know that coefficient string is available so read it.
    //
    iCount = UARTgets(g_pcCoefficients,COEFFICIENT_BUFFER_LEN);
   
    if(iCount)
    {
    //
    // Change UARTprintf prot for FPGA
    //
      UARTPrintfPortChange(UART0FPGA);
    //
    // Here we do nothing about data check.
    // Prints coefficients to FPGA via UART.
    //
      UARTprintf("%s",g_pcCoefficients);
    }

    //
    // restart DSP to prapear to the next filter design
    //  
//      UARTprintf("restartFilterDesign\n");
   
    //
    // Change the button text to show that the update is done.
    //
    PushButtonTextSet(&g_sCanvas1, "Done !");
    WidgetPaint((tWidget *)&g_sCanvas1);
   
    //
    // Play the key click sound.
    //
    PLAYSOUND(g_bSoundEnable,g_pusAccessGranted, sizeof(g_pusAccessGranted) / 2);
}
点赞  2012-7-31 10:39
这个好像是分时复用吧!那么DSP和FPGA同时向芯片发数据呢?应该怎么处理?
点赞  2013-1-7 22:03
是否只能留到后来去读FIFO了呢?
点赞  2013-1-11 14:38

回复 楼主 ooakk 的帖子

使用两个以上串口,在主程序的开始就进行初始化,以后用哪个串口时,直接用就行了吧,也不用什么用完之后就除能之类的操作吧
点赞  2013-1-19 11:40
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复