|
各位高手,各位大侠 :
正在编译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周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|