LPC 2368 Uart printf scanf 实现

    技术2022-05-11  13

    在IAR 的EWARM中提供了printf和scanf,但是需要自己提供hardware low level 层的getchar和putchar,才能实现,本例子在EWARM 5.10和LPC 2368调试通过,其code是根据EWARM 5.10中自带的例子程序更改得来的LPC23xx/KEIL-MCB2300/simple/UART,

    最主要的是实现

    int MyLowLevelPutchar(int x){   *ptr=(BYTE)x; UARTSend( 0, ptr, 1 );  return 1;}

    int MyLowLevelGetchar(){  while(ReceivedByte==-1); //not received  temp=ReceivedByte;  ReceivedByte=-1;  return temp;  }

    网上没找到相关资料,自己想了很长时间对将scanf的getchar实现想出来(putchar 较简单)

    下面是几个重要的code

    /*****************************************************************************

    uarttest.c

    /*****************************************************************************

    #include "LPC230x.h"                        /* LPC21xx definitions */#include "type.h"#include "irq.h"#include "target.h"#include "uart.h"

    #include    <stdio.h>

     

    extern volatile DWORD UART0Count;extern volatile BYTE UART0Buffer[BUFSIZE];extern volatile DWORD UART1Count;extern volatile BYTE UART1Buffer[BUFSIZE];

    /*******************************************************************************   Main Function  main()*****************************************************************************/int main (void){  TargetResetInit();

      UARTInit(0, 115200); /* baud rate setting */ 

        printf("Hello,World! This demo is modified by hammergo!/n");  printf("Welcome to arm programming world!/n");    int test=0;  printf("Please input test value:");  scanf("%d",&test);  if(test>0)  {    printf("test>0");  }else  {    printf("test<=0");  }

        while (1)   {    /* Loop forever */

      }  return 0;}

    /*******************************************************************************                            End Of File*****************************************************************************/

     

     

     

    /******************************************************************************   uart.c:  UART API file for NXP LPC23xx/24xx Family Microprocessors**   Copyright(C) 2006, NXP Semiconductor*   All rights reserved.**   History*   2006.07.12  ver 1.00    Prelimnary version, first Release*******************************************************************************/#include "LPC230x.h"                        /* LPC23xx/24xx definitions */#include "type.h"#include "target.h"#include "irq.h"#include "uart.h"

    #include <intrinsics.h>

    volatile DWORD UART0Status;volatile BYTE UART0TxEmpty = 1;volatile BYTE UART0Buffer[BUFSIZE];volatile DWORD UART0Count = 0;extern volatile int ReceivedByte;

    /******************************************************************************* Function name:   UART0Handler**** Descriptions:    UART0 interrupt handler**** parameters:      None** Returned value:    None** *****************************************************************************/__irq __nested __arm void UART0Handler (void){  BYTE IIRValue, LSRValue;  volatile BYTE Dummy;    __enable_interrupt();   /* handles nested interrupt */    IIRValue = U0IIR;  IIRValue >>= 1;     /* skip pending bit in IIR */  IIRValue &= 0x07;     /* check bit 1~3, interrupt identification */  if ( IIRValue == IIR_RLS )    /* Receive Line Status */  {    LSRValue = U0LSR;    /* Receive Line Status */    if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )    {      /* There are errors or break interrupt */      /* Read LSR will clear the interrupt */      UART0Status = LSRValue;      Dummy = U0RBR;    /* Dummy read on RX to clear interrupt, then bail out */      VICVectAddr = 0;  /* Acknowledge Interrupt */      return;    }    if ( LSRValue & LSR_RDR ) /* Receive Data Ready */          {//      /* If no error on RLS, normal ready, save into the data buffer. *///      /* Note: read RBR will clear the interrupt *///      UART0Buffer[UART0Count] = U0RBR;//      UART0Count++;//      if ( UART0Count == BUFSIZE )//      {//        UART0Count = 0; /* buffer overflow *///      }     if(ReceivedByte==-1)    ReceivedByte=U0RBR;          }  }  else if ( IIRValue == IIR_RDA ) /* Receive Data Available */  {//    /* Receive Data Available *///    UART0Buffer[UART0Count] = U0RBR;//    UART0Count++;//    if ( UART0Count == BUFSIZE )//    {//      UART0Count = 0; /* buffer overflow *///    }    if(ReceivedByte==-1)    ReceivedByte=U0RBR;      }  else if ( IIRValue == IIR_CTI ) /* Character timeout indicator */  {    /* Character Time-out indicator */    UART0Status |= 0x100; /* Bit 9 as the CTI error */  }  else if ( IIRValue == IIR_THRE )  /* THRE, transmit holding register empty */  {    /* THRE interrupt */    LSRValue = U0LSR; /* Check status in the LSR to see if valid data in U0THR or not */    if ( LSRValue & LSR_THRE )    {      UART0TxEmpty = 1;    }    else    {      UART0TxEmpty = 0;    }  }    VICVectAddr = 0;            /* Acknowledge Interrupt */  return;}

    /******************************************************************************* Function name:   UART1Handler**** Descriptions:    UART1 interrupt handler**** parameters:      None** Returned value:    None** *****************************************************************************/__irq __nested __arm void UART1Handler (void){  BYTE IIRValue, LSRValue;  volatile BYTE Dummy;    __enable_interrupt();   /* handles nested interrupt */  IIRValue = U1IIR;    IIRValue >>= 1;     /* skip pending bit in IIR */  IIRValue &= 0x07;     /* check bit 1~3, interrupt identification */  if ( IIRValue == IIR_RLS )    /* Receive Line Status */  {    LSRValue = U1LSR;    /* Receive Line Status */    if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )    {      /* There are errors or break interrupt */      /* Read LSR will clear the interrupt */      //UART1Status = LSRValue;      Dummy = U1RBR;    /* Dummy read on RX to clear       interrupt, then bail out */      VICVectAddr = 0;    /* Acknowledge Interrupt */      return;    }    if ( LSRValue & LSR_RDR ) /* Receive Data Ready */          {      /* If no error on RLS, normal ready, save into the data buffer. */      /* Note: read RBR will clear the interrupt */      // UART1Buffer[UART1Count] = U1RBR;      //UART1Count++;      //        if ( UART1Count == BUFSIZE )      //        {      //        UART1Count = 0;   /* buffer overflow */      //        }     }  }  else if ( IIRValue == IIR_RDA ) /* Receive Data Available */  {    /* Receive Data Available */    //UART1Buffer[UART1Count] = U1RBR;    // UART1Count++;    //    if ( UART1Count == BUFSIZE )    //    {    //        UART1Count = 0;   /* buffer overflow */    //    }  }  else if ( IIRValue == IIR_CTI ) /* Character timeout indicator */  {    /* Character Time-out indicator */    //UART1Status |= 0x100;   /* Bit 9 as the CTI error */  }  else if ( IIRValue == IIR_THRE )  /* THRE, transmit holding register empty */  {    /* THRE interrupt */    LSRValue = U1LSR;   /* Check status in the LSR to see if    valid data in U0THR or not */    if ( LSRValue & LSR_THRE )    {      //UART1TxEmpty = 1;    }    else    {      //UART1TxEmpty = 0;    }  }    VICVectAddr = 0;    /* Acknowledge Interrupt */}

    /******************************************************************************* Function name:   UARTInit**** Descriptions:    Initialize UART0 port, setup pin select,**            clock, parity, stop bits, FIFO, etc.**** parameters:      portNum(0 or 1) and UART baudrate** Returned value:    true or false, return false only if the **            interrupt handler can't be installed to the **            VIC table** *****************************************************************************/

    DWORD UARTInit( DWORD PortNum, DWORD baudrate ){  DWORD Fdiv;    if ( PortNum == 0 )  {    PINSEL0 = 0x00000050;       /* RxD0 and TxD0 */        U0LCR = 0x83;   /* 8 bits, no Parity, 1 Stop bit */    Fdiv = ( Fpclk / 16 ) / baudrate ;  /*baud rate */    U0DLM = Fdiv / 256;                 U0DLL = Fdiv % 256;    U0LCR = 0x03;   /* DLAB = 0 */    U0FCR = 0x07;   /* Enable and reset TX and RX FIFO. */        if ( install_irq( UART0_INT, (void *)UART0Handler, HIGHEST_PRIORITY ) == FALSE )    {      return (FALSE);    }        U0IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART0 interrupt */    return (TRUE);  }  else if ( PortNum == 1 )  {#if EA_BOARD_LPC24XX    PINSEL7 |= 0x0000000F;  /* P3.16 TXD1, P3.17 RXD1 */#else             /* Default is Keil MCB2300 board */                 PINSEL0 |= 0x40000000;  /* Enable TxD1 P0.15 */    PINSEL1 |= 0x00000001;  /* Enable RxD1 P0.16 */#endif    U1LCR = 0x83;   /* 8 bits, no Parity, 1 Stop bit */    Fdiv = ( Fpclk / 16 ) / baudrate ;  /*baud rate */    U1DLM = Fdiv / 256;                 U1DLL = Fdiv % 256;    U1LCR = 0x03;   /* DLAB = 0 */    U1FCR = 0x07;   /* Enable and reset TX and RX FIFO. */        if ( install_irq( UART1_INT, (void *)UART1Handler, HIGHEST_PRIORITY ) == FALSE )    {      return (FALSE);    }        U1IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART0 interrupt */    return (TRUE);  }  return( FALSE ); }

    /******************************************************************************* Function name:   UARTSend**** Descriptions:    Send a block of data to the UART 0 port based**            on the data length**** parameters:      portNum, buffer pointer, and data length** Returned value:    None** *****************************************************************************/void UARTSend( DWORD portNum, BYTE *BufferPtr, DWORD Length ){  if ( portNum == 0 )  {    while ( Length != 0 )    {      /* THRE status, contain valid data */      while ( !(UART0TxEmpty & 0x01) );       U0THR = *BufferPtr;      UART0TxEmpty = 0; /* not empty in the THR until it shifts out */      BufferPtr++;      Length--;    }  }  else  {    //    while ( Length != 0 )    //    {    //      /* THRE status, contain valid data */    //      while ( !(UART1TxEmpty & 0x01) );     //      U1THR = *BufferPtr;    //      UART1TxEmpty = 0; /* not empty in the THR until it shifts out */    //      BufferPtr++;    //      Length--;    //    }  }  return;}

    /********************************************************************************                            End Of File******************************************************************************/

     

     

    /***************************************************************************** *   irq.c: Interrupt handler C file for NXP LPC230x Family Microprocessors * *   Copyright(C) 2006, NXP Semiconductor *   All rights reserved. * *   History *   2006.07.13  ver 1.00    Prelimnary version, first Release *******************************************************************************/#include "LPC230x.h"   /* LPC23XX Peripheral Registers */#include "type.h"#include "irq.h"

    /* Initialize the interrupt controller *//******************************************************************************** Function name:  init_VIC**** Descriptions:  Initialize VIC interrupt controller.** parameters:   None** Returned value:  None** ******************************************************************************/void init_VIC(void) {    DWORD i = 0;    DWORD *vect_addr, *vect_cntl;        /* initialize VIC*/    VICIntEnClr = 0xffffffff;    VICVectAddr = 0;    VICIntSelect = 0;

        /* set all the vector and vector control register to 0 */    for ( i = 0; i < VIC_SIZE; i++ )    {  vect_addr = (DWORD *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + i*4);  vect_cntl = (DWORD *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + i*4);  *vect_addr = 0x0;   *vect_cntl = 0xF;    }    return;}

    /******************************************************************************** Function name:  install_irq**** Descriptions:  Install interrupt handler** parameters:   Interrupt number, interrupt handler address, **      interrupt priority** Returned value:  true or false, return false if IntNum is out of range** ******************************************************************************/DWORD install_irq( DWORD IntNumber, void *HandlerAddr, DWORD Priority ){    DWORD *vect_addr;    DWORD *vect_cntl;          VICIntEnClr = 1 << IntNumber; /* Disable Interrupt */    if ( IntNumber >= VIC_SIZE )    {  return ( FALSE );    }    else    {  /* find first un-assigned VIC address for the handler */  vect_addr = (DWORD *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + IntNumber*4);  vect_cntl = (DWORD *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + IntNumber*4);  *vect_addr = (DWORD)HandlerAddr; /* set interrupt vector */  *vect_cntl = Priority;  VICIntEnable = 1 << IntNumber; /* Enable Interrupt */  return( TRUE );    }}

    /********************************************************************************                            End Of File******************************************************************************/

     

     

    /******************* * * Copyright 1998-2003 IAR Systems.  All rights reserved. * * $Revision: 3162 $ * * This is a template implementation of the "__write" function used by * the standard library.  Replace it with a system-specific * implementation. * * The "__write" function should output "size" number of bytes from * "buffer" in some application-specific way.  It should return the * number of characters written, or _LLIO_ERROR on failure. * * If "buffer" is zero then __write should perform flushing of * internal buffers, if any.  In this case "handle" can be -1 to * indicate that all handles should be flushed. * * The template implementation below assumes that the application * provides the function "MyLowLevelPutchar".  It should return the * character written, or -1 on failure. * ********************/#include <yfuns.h>#include "type.h"#include "uart.h"

    _STD_BEGIN

    #pragma module_name = "?__write"BYTE ptr[1];int MyLowLevelPutchar(int x){   *ptr=(BYTE)x; UARTSend( 0, ptr, 1 );  return 1;}

    /* * If the __write implementation uses internal buffering, uncomment * the following line to ensure that we are called with "buffer" as 0 * (i.e. flush) when the application terminates. */

    size_t __write(int handle, const unsigned char * buffer, size_t size){  /* Remove the #if #endif pair to enable the implementation */

      size_t nChars = 0;

      if (buffer == 0)  {    /*     * This means that we should flush internal buffers.  Since we     * don't we just return.  (Remember, "handle" == -1 means that all     * handles should be flushed.)     */    return 0;  }

      /* This template only writes to "standard out" and "standard err",   * for all other file handles it returns failure. */  if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR)  {    return _LLIO_ERROR;  }

      for (/* Empty */; size != 0; --size)  {    if (MyLowLevelPutchar(*buffer++) < 0)    {      return _LLIO_ERROR;    }

        ++nChars;  }

      return nChars;

     

      /* Always return error code when implementation is disabled. */  return _LLIO_ERROR;

     

    }

    _STD_END

     

     

    /******************* * * Copyright 1998-2003 IAR Systems.  All rights reserved. * * $Revision: 3161 $ * * This is a template implementation of the "__read" function used by * the standard library.  Replace it with a system-specific * implementation. * * The "__read" function reads a number of bytes, at most "size" into * the memory area pointed to by "buffer".  It returns the number of * bytes read, 0 at the end of the file, or _LLIO_ERROR if failure * occurs. * * The template implementation below assumes that the application * provides the function "MyLowLevelGetchar".  It should return a * character value, or -1 on failure. * ********************/

    #include <yfuns.h>#include "type.h"

    #include "LPC230x.h"  

     

     

    _STD_BEGIN

    #pragma module_name = "?__read"

    volatile int ReceivedByte=-1;int temp=0;int MyLowLevelGetchar(){  while(ReceivedByte==-1); //not received  temp=ReceivedByte;  ReceivedByte=-1;  return temp;  }   

     

    size_t __read(int handle, unsigned char * buffer, size_t size){  /* Remove the #if #endif pair to enable the implementation */  

      int nChars = 0;

     

        /* This template only reads from "standard in", for all other file   * handles it returns failure. */  if (handle != _LLIO_STDIN)  {    return _LLIO_ERROR;  }

      for (/* Empty */; size > 0; --size)  {    int c = MyLowLevelGetchar();    if (c < 0)      break;

        *buffer++ = c;    ++nChars;  }

      return nChars;

     

      /* Always return error code when implementation is disabled. */  return _LLIO_ERROR;

    }

    _STD_END

     

    用串口调试助手测试结果

    Hello,World! This demo is modified by hammergo!Welcome to arm programming world!Please input test value:test>0

    Hello,World! This demo is modified by hammergo!Welcome to arm programming world!Please input test value:test<=0


    最新回复(0)