搜索
bottom↓
回复: 1

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

[复制链接]

出0入0汤圆

发表于 2013-12-16 16:13:16 | 显示全部楼层 |阅读模式
各位高手,各位大侠 :

正在编译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.21  ver 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.21  ver 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[BUFSIZE], UART1Buffer[BUFSIZE], UART3Buffer[BUFSIZE];
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[UART0Count] = U0RBR;
      UART0Count++;
      if (UART0Count == BUFSIZE)
      {
        UART0Count = 0;                /* buffer overflow */
      }       
    }
  }
  else if (IIRValue == IIR_RDA)        /* Receive Data Available */
  {
    /* Receive Data Available */
    UART0Buffer[UART0Count] = 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[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;
    }
  }
}

/*****************************************************************************
** 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[UART3Count] = U3RBR;
      UART3Count++;
      if (UART3Count == BUFSIZE)
      {
        UART3Count = 0;                /* buffer overflow */
      }       
    }
  }
  else if (IIRValue == IIR_RDA)        /* Receive Data Available */
  {
    /* Receive Data Available */
    UART3Buffer[UART3Count] = 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[256];         
       
        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
******************************************************************************/

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2013-12-16 20:45:24 | 显示全部楼层
经过 Z31com 朋友和同事的启发 我去除了 Keil 编译选项 USE MicroLIB  搞定了 ,特此留下足迹。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 12:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表