yanjiesh 发表于 2013-12-16 16:13:16

请教 Printfa.o 文件的出处,各位大侠、高手 :)

各位高手,各位大侠 :

正在编译LPC1766的应用软件,其中使用了Uart0 模拟了 printf 函数,并在多处加以使用。但是编译时出错为:
.\Output\LPC1766.axf: Error: L6200E: Symbol printf multiply defined (by printfa.o and uart.o).

Search in files " printf " ,发现只在uart.h 中有声明,在 uart.c 中有定义,其他文件中 就是应用。求解。

以下是 uart.h 和 Uart.c的源代码:
/*****************************************************************************
*   uart.h:Header file for NXP LPC17xx Family Microprocessors
*
*   Copyright(C) 2008, NXP Semiconductor
*   All rights reserved.
*
*   History
*   2008.08.21ver 1.00    Prelimnary version, first Release
*
******************************************************************************/
#ifndef __UART_H
#define __UART_H

#define IER_RBR                0x01
#define IER_THRE        0x02
#define IER_RLS                0x04

#define IIR_PEND        0x01
#define IIR_RLS                0x03
#define IIR_RDA                0x02
#define IIR_CTI                0x06
#define IIR_THRE        0x01

#define LSR_RDR                0x01
#define LSR_OE                0x02
#define LSR_PE                0x04
#define LSR_FE                0x08
#define LSR_BI                0x10
#define LSR_THRE        0x20
#define LSR_TEMT        0x40
#define LSR_RXFE        0x80

#define BUFSIZE                0x40

uint32_t UARTInit(uint32_t portNum, uint32_t Baudrate);
void UART0_IRQHandler(void);
void UART1_IRQHandler(void);
void UART3_IRQHandler(void);
void UARTSend(uint32_t portNum, uint8_t *BufferPtr, uint32_t Length);
void UART0SendByte(uint8_t Data);
void putch(char data);
void puts(char *str);
extern void printf(char *fmt, ...);
int GetKey(uint8_t flag_getkey);

void UART0RecvByte(uint8_t *BufferPtr);
void UART0_gets(uint8_t *BufferPtr);

#define        next_line()        putch('\n')

#endif /* end __UART_H */
/*****************************************************************************
**                            End Of File
******************************************************************************/







/*****************************************************************************
*   uart.c:UART API file for NXP LPC17xx Family Microprocessors
*
*   Copyright(C) 2008, NXP Semiconductor
*   All rights reserved.
*
*   History
*   2008.08.21ver 1.00    Prelimnary version, first Release
*
******************************************************************************/
#include "LPC17xx.h"
#include "type.h"
#include "target.h"
#include "nvic.h"
#include "uart.h"

#include "stdarg.h"
#include "string.h"

volatile uint32_t UART0Status, UART1Status, UART3Status;
volatile uint8_t UART0TxEmpty = 1, UART1TxEmpty = 1, UART3TxEmpty = 1;
volatile uint8_t UART0Buffer, UART1Buffer, UART3Buffer;
volatile uint32_t UART0Count = 0, UART1Count = 0, UART3Count = 0;

/*****************************************************************************
** Function name:                UART0_IRQHandler
**
** Descriptions:                UART0 interrupt handler
**
** parameters:                        None
** Returned value:                None
**
*****************************************************************************/
void UART0_IRQHandler(void)
{
uint8_t IIRValue, LSRValue;
uint8_t Dummy = Dummy;

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 */
      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 = U0RBR;
      UART0Count++;
      if (UART0Count == BUFSIZE)
      {
      UART0Count = 0;                /* buffer overflow */
      }       
    }
}
else if (IIRValue == IIR_RDA)        /* Receive Data Available */
{
    /* Receive Data Available */
    UART0Buffer = U0RBR;
    UART0Count++;
    if (UART0Count == BUFSIZE)
    {
      UART0Count = 0;                /* buffer overflow */
    }
}
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;
    }
}
}

/*****************************************************************************
** Function name:                UART1_IRQHandler
**
** Descriptions:                UART1 interrupt handler
**
** parameters:                        None
** Returned value:                None
**
*****************************************************************************/
void UART1_IRQHandler(void)
{
uint8_t IIRValue, LSRValue;
uint8_t Dummy = Dummy;

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 */
      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 = U1RBR;
      UART1Count++;
      if (UART1Count == BUFSIZE)
      {
      UART1Count = 0;                /* buffer overflow */
      }       
    }
}
else if (IIRValue == IIR_RDA)        /* Receive Data Available */
{
    /* Receive Data Available */
    UART1Buffer = 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;
    }
}
}

/*****************************************************************************
** Function name:                UART0_IRQHandler
**
** Descriptions:                UART0 interrupt handler
**
** parameters:                        None
** Returned value:                None
**
*****************************************************************************/
void UART3_IRQHandler(void)
{
uint8_t IIRValue, LSRValue;
uint8_t Dummy = Dummy;

IIRValue = U3IIR;
   
IIRValue >>= 1;                        /* skip pending bit in IIR */
IIRValue &= 0x07;                        /* check bit 1~3, interrupt identification */
if (IIRValue == IIR_RLS)                /* Receive Line Status */
{
    LSRValue = U3LSR;
    /* 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 */
      UART3Status = LSRValue;
      Dummy = U3RBR;                /* Dummy read on RX to clear
                                                        interrupt, then bail out */
      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 */
      UART3Buffer = U3RBR;
      UART3Count++;
      if (UART3Count == BUFSIZE)
      {
      UART3Count = 0;                /* buffer overflow */
      }       
    }
}
else if (IIRValue == IIR_RDA)        /* Receive Data Available */
{
    /* Receive Data Available */
    UART3Buffer = U3RBR;
    UART3Count++;
    if (UART3Count == BUFSIZE)
    {
      UART3Count = 0;                /* buffer overflow */
    }
}
else if (IIRValue == IIR_CTI)        /* Character timeout indicator */
{
    /* Character Time-out indicator */
    UART3Status |= 0x100;                /* Bit 9 as the CTI error */
}
else if (IIRValue == IIR_THRE)        /* THRE, transmit holding register empty */
{
    /* THRE interrupt */
    LSRValue = U3LSR;                /* Check status in the LSR to see if
                                                        valid data in U0THR or not */
    if (LSRValue & LSR_THRE)
    {
      UART3TxEmpty = 1;
    }
    else
    {
      UART3TxEmpty = 0;
    }
}
}

/*****************************************************************************
** 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
**
*****************************************************************************/
uint32_t UARTInit(uint32_t PortNum, uint32_t baudrate)
{
uint32_t Fdiv;
NVIC_InitTypeDef NVIC_InitStructure;

UART0TxEmpty = 1;
UART1TxEmpty = 1;
UART3TxEmpty = 1;

UART0Count = 0;
UART1Count = 0;
UART3Count = 0;

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. */

    /* Enable the UART0 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = UART0_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    U0IER = IER_RBR | IER_THRE | IER_RLS;        /* Enable UART0 interrupt */
    return (TRUE);
}
else if ( PortNum == 1 )
{
#if 1
    PINSEL0 |= 0x40000000;       /* TxD1 */
    PINSEL1 |= 0x00000001;       /* RxD1 */
#endif
#if 0
    PINSEL4 |= 0x0000000A;       /* RxD1 and TxD1 */
#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. */

    /* Enable the UART1 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = UART1_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    U1IER = IER_RBR | IER_THRE | IER_RLS;        /* Enable UART1 interrupt */
    return (TRUE);
}
else if ( PortNum == 3 )
{
        PINSEL9 = 0x0F000000;
        PCONP |= (0x01 << 25);
    U3LCR = 0x83;                /* 8 bits, no Parity, 1 Stop bit */
    Fdiv = ( Fpclk / 16 ) / baudrate ;        /*baud rate */
    U3DLM = Fdiv / 256;                                                       
    U3DLL = Fdiv % 256;
    U3LCR = 0x03;                /* DLAB = 0 */
    U3FCR = 0x07;                /* Enable and reset TX and RX FIFO. */

    /* Enable the UART1 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = UART3_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    U3IER = IER_RBR | IER_THRE | IER_RLS;        /* Enable UART1 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(uint32_t portNum, uint8_t *BufferPtr, uint32_t 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 if( portNum == 1 )
{
    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--;
    }
}
else if( portNum == 3 )
{
      /* THRE status, contain valid data */
      while (!(UART3TxEmpty & 0x01));       
      U3THR = *BufferPtr;
      UART3TxEmpty = 0;        /* not empty in the THR until it shifts out */
      BufferPtr++;
      Length--;
}
return;
}


/*****************************************************************************
** Function name:                UARTSend
**
** Descriptions:                通过UART0根据数据长度送出一串数据
**
** parameters:                        buffer pointer
** Returned value:                None
**
*****************************************************************************/
void UART0Send(char *BufferPtr)
{          
        while(1)
        {
                if(*BufferPtr == '\0')        break;
                UART0SendByte(*BufferPtr++);
        }
}

/*****************************************************************************
** Function name:                UARTSendByte
**
** Descriptions:                通过UART输出一个BYTE的数据
** parameters:                        data
** Returned value:                None
**
*****************************************************************************/
void UART0SendByte(uint8_t Data)
{
        U0THR = Data;
        while((U0LSR &0x40) ==0);
}

/*****************************************************************************
** Function name:                putch
**
** Descriptions:                实现putch输出函数,打印出多个字符
** parameters:                        data
** Returned value:                None
**
*****************************************************************************/
void putch(char data)
{
        UART0Send(&data);
}

/*****************************************************************************
** Function name:                puts
**
** Descriptions:                实现puts输出函数,打印出单个字符
** parameters:                        *str
** Returned value:                None
**
*****************************************************************************/
void puts(char *str)
{       
        UART0Send(str);
}

/*****************************************************************************
** Function name:                printf
**
** Descriptions:                实现print功能函数
** parameters:                        *fmt, ...
** Returned value:                None
**
*****************************************************************************/
int vsprintf(char * /*s*/, const char * /*format*/, va_list /*arg*/);
       
void printf(char *fmt, ...)
{
        va_list ap;
        char string;       
       
        va_start(ap, fmt);
        vsprintf(string, fmt, ap);
       
        UART0Send(string);
        va_end(ap);
}

/*****************************************************************************
** Function name:                UART0Recv
**
** Descriptions:                从UART0接收一个字节数据
** parameters:                        buffer pointer, and data length
** Returned value:                None
**
*****************************************************************************/
void UART0RecvByte(uint8_t *BufferPtr)
{
    while((U0LSR & 0x01) == 0);         /* 等待接收数据到达RBR */
    *BufferPtr = U0RBR;

    return;
}

/*****************************************************************************
** Function name:                UART0_gets
**
** Descriptions:                查询方式从UART0接收数据
** parameters:                        buffer pointer
** Returned value:                None
**
*****************************************************************************/
void UART0_gets(uint8_t *BufferPtr)
{
    while( 1 )
    {                                                                  
      UART0RecvByte(BufferPtr);
      if(*BufferPtr == '\0')break;      // 接收到的数据是否为结束符

      BufferPtr ++;             // 未做边界检查,可能会有危险
    }

    return;
}
/******************************************************************************
**                            End Of File
******************************************************************************/

yanjiesh 发表于 2013-12-16 20:45:24

经过 Z31com 朋友和同事的启发 我去除了 Keil 编译选项 USE MicroLIB搞定了 ,特此留下足迹。{:smile:}
页: [1]
查看完整版本: 请教 Printfa.o 文件的出处,各位大侠、高手 :)