STM32F10x uart的数据发送接收就三种基本方式,轮询、中断和DMA
以下是轮询的uart初始化以及发送接收的例子,发送和接收都用轮询的方式。
uint8_t TxBuffer[] = "Buffer Send from USARTy to USARTz using Flags";
uint8_t RxBuffer[TxBufferSize];
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f10x_xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f10x.c file
*/
/* System Clocks Configuration */
RCC_Configuration();
/* Configure the GPIO ports */
GPIO_Configuration();
/* USARTy and USARTz configuration ------------------------------------------------------*/
/* USARTy and USARTz configured as follow:
- BaudRate = 230400 baud
- Word Length = 8 Bits
- One Stop Bit
- Even parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 230400;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_Even;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* Configure USARTy */
USART_Init(USARTy, &USART_InitStructure);
/* Configure USARTz */
USART_Init(USARTz, &USART_InitStructure);
/* Enable the USARTy */
USART_Cmd(USARTy, ENABLE);
/* Enable the USARTz */
USART_Cmd(USARTz, ENABLE);
while(TxCounter < TxBufferSize)
{
/* Send one byte from USARTy to USARTz */
USART_SendData(USARTy, TxBuffer[TxCounter++]);
/*
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
{
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_DATA(Data));
USARTx->DR = (Data & (uint16_t)0x01FF); //往DR写发送的数据
}
*/
/* Loop until USARTy DR register is empty */
while(USART_GetFlagStatus(USARTy, USART_FLAG_TXE) == RESET)
{
}
//到这里表示数据发送完毕(USART_FLAG_TXE可以参考STM32F10x usart寄存器描述)
/* Loop until the USARTz Receive Data Register is not empty */
while(USART_GetFlagStatus(USARTz, USART_FLAG_RXNE) == RESET)
{
}
//到这里表示数据接收完毕(USART_FLAG_RXNE可以参考STM32F10x usart寄存器描述)
/* Store the received byte in RxBuffer */
RxBuffer[RxCounter++] = (USART_ReceiveData(USARTz) & 0x7F);
}
//后面只是看发送接收数据是否一致,这与测试条件有关,不再赘述。
/* Check the received data with the send ones */
TransferStatus = Buffercmp(TxBuffer, RxBuffer, TxBufferSize);
/* TransferStatus = PASSED, if the data transmitted from USARTy and
received by USARTz are the same */
/* TransferStatus = FAILED, if the data transmitted from USARTy and
received by USARTz are different */
while (1)
{
}
}
STM32F10x USART有很多类型的中断,每个中断类型都有一个使能标志位。
中断设定以及使用ringbuffer输入输出的流程如下
(1) 中断的初始化
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USARTy Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USARTy_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable USARTy Receive and Transmit interrupts */
USART_ITConfig(USARTy, USART_IT_RXNE, ENABLE);
USART_ITConfig(USARTy, USART_IT_TXE, ENABLE);
一般一个USART端口,输入输出都要设置一个中断位来触发输入输出中断,一般的输入输出只需要设置如下两个中断即可。
USART_IT_RXNE:Receive Data register not empty interrupt
USART_IT_TXE: Transmit Data Register empty interrupt
还有其他的中断位解释如下:
USART_IT_CTS: CTS change interrupt
USART_IT_LBD: LIN Break detection interrupt
USART_IT_TC: Transmission complete interrupt
USART_IT_IDLE: Idle line detection interrupt
USART_IT_PE: Parity Error interrupt
USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
设置完USART_IT_RXNE和USART_IT_TXE中断之后,读写都会触发中断。
这里我们一般不用USART_IT_TC中断,因为一般来说使用发送数据寄存器空中断(USART_IT_TXE)
发送的效率会高一些。
下面用一个使用ringbuffer,且使用中断方式的例子来熟悉一下中断读写。
(参考http://blog.csdn.net/liyuanbhu/article/details/8886407)
中断处理函数的框架如下,如果检测到错误就清除错误,收到数了就处理。发完当前数据了就发下一个。
void USART1_IRQHandler(void)
{
unsigned int data;
if(USART1->SR & 0x0F)
{
// See if we have some kind of error, Clear interrupt
data = USART1->DR;
}
else if(USART1->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag
{
data = USART1->DR;
// 对收到的数据进行处理,或者干些其他的事
}
else if(USART1->SR & USART_FLAG_TXE)
{
{ // 可以发送数据了,如果没有数据需要发送,就在这里关闭发送中断
USART1->DR = something; // Yes, Send character
}
}
}
下面给一个利用环形缓冲区的串口驱动程序。
#ifndef _COM_BUFFERED_H_
#define _COM_BUFFERED_H_
#define COM1 0
#define COM2 1
#define COM_RX_BUF_SIZE 64 /* Number of characters in Rx ring buffer */
#define COM_TX_BUF_SIZE 64 /* Number of characters in Tx ring buffer */
#define COM_NO_ERR 0 /* Function call was successful */
#define COM_BAD_CH 1 /* Invalid communications port channel */
#define COM_RX_EMPTY 2 /* Rx buffer is empty, no character available */
#define COM_TX_FULL 3 /* Tx buffer is full, could not deposit character */
#define COM_TX_EMPTY 4 /* If the Tx buffer is empty. */
/************************************************************
* function : COMGetCharB
* parameter: char port, port can be COM1 / COM2
* parameter: char* err is a pointer to where an error code will be placed:
* *err is set to COM_NO_ERR if a character is available
* *err is set to COM_RX_EMPTY if the Rx buffer is empty
* *err is set to COM_BAD_CH if you have specified an invalid channel
* return : char
* usage : This function is called by your application to obtain a character from the communications
* channel.
* changelog:
*************************************************************/
unsigned char COMGetCharB (unsigned char ch, unsigned char *err);
/************************************************************
* function : COMPutCharB
* parameter: char port, port can be COM1 / COM2
* return : COMM_NO_ERR if the function was successful (the buffer was not full)
* COMM_TX_FULL if the buffer was full
* COMM_BAD_CH if you have specified an incorrect channel
* usage : This function is called by your application to send a character on the communications
* channel. The character to send is first inserted into the Tx buffer and will be sent by
* the Tx ISR. If this is the first character placed into the buffer, the Tx ISR will be
* enabled. If the Tx buffer is full, the character will not be sent (i.e. it will be lost)
* changelog:
*************************************************************/
unsigned char COMPutCharB (unsigned char port, unsigned char c);
/************************************************************
* function : COMBufferInit
* parameter:
* return :
* usage : This function is called by your application to initialize the communications module. You
* must call this function before calling any other functions.
* changelog:
*************************************************************/
void COMBufferInit (void);
/************************************************************
* function : COMBufferIsEmpty
* parameter: char port, port can be COM1 / COM2
* return : char
* usage : This function is called by your application to see
* if any character is available from the communications channel.
* If at least one character is available, the function returns
* FALSE(0) otherwise, the function returns TRUE(1).
* changelog:
*************************************************************/
unsigned char COMBufferIsEmpty (unsigned char port);
/************************************************************
* function : COMBufferIsFull
* parameter: char port, port can be COM1 / COM2
* return : char
* usage : This function is called by your application to see if any more characters can be placed
* in the Tx buffer. In other words, this function check to see if the Tx buffer is full.
* If the buffer is full, the function returns TRUE otherwise, the function returns FALSE.
* changelog:
*************************************************************/
unsigned char COMBufferIsFull (unsigned char port);
#endif
/*
* file: com_buffered.c
* author: Li Yuan
* platform: STM32F107
* date: 2013-5-5
* version: 0.0.1
* description: UART Ring Buffer
**/
#include "stm32f10x_usart.h"
#include "com_buffered.h"
#define OS_ENTER_CRITICAL() __set_PRIMASK(1)
#define OS_EXIT_CRITICAL() __set_PRIMASK(0)
/**
* Enables Transmiter interrupt.
**/
static void COMEnableTxInt(unsigned char port)
{
static USART_TypeDef* map[2] = {USART1, USART2};
USART_ITConfig(map[port], USART_IT_TXE, ENABLE);
}
/*
*********************************************************************************************************
* DATA TYPES
*********************************************************************************************************
*/
typedef struct {
short RingBufRxCtr; /* Number of characters in the Rx ring buffer */
unsigned char *RingBufRxInPtr; /* Pointer to where next character will be inserted */
unsigned char *RingBufRxOutPtr; /* Pointer from where next character will be extracted */
unsigned char RingBufRx[COM_RX_BUF_SIZE]; /* Ring buffer character storage (Rx) */
short RingBufTxCtr; /* Number of characters in the Tx ring buffer */
unsigned char *RingBufTxInPtr; /* Pointer to where next character will be inserted */
unsigned char *RingBufTxOutPtr; /* Pointer from where next character will be extracted */
unsigned char RingBufTx[COM_TX_BUF_SIZE]; /* Ring buffer character storage (Tx) */
} COM_RING_BUF;
/*
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
*/
COM_RING_BUF COM1Buf;
COM_RING_BUF COM2Buf;
/************************************************************
* function : COMGetCharB
* parameter: char port, port can be COM1 / COM2
* parameter: char* err is a pointer to where an error code will be placed:
* *err is set to COM_NO_ERR if a character is available
* *err is set to COM_RX_EMPTY if the Rx buffer is empty
* *err is set to COM_BAD_CH if you have specified an invalid channel
* return : char
* usage : This function is called by your application to obtain a character from the communications
* channel.
* changelog:
*************************************************************/
unsigned char COMGetCharB (unsigned char port, unsigned char *err)
{
// unsigned char cpu_sr;
unsigned char c;
COM_RING_BUF *pbuf;
switch (port)
{ /* Obtain pointer to communications channel */
case COM1:
pbuf = &COM1Buf;
break;
case COM2:
pbuf = &COM2Buf;
break;
default:
*err = COM_BAD_CH;
return (0);
}
OS_ENTER_CRITICAL();
if (pbuf->RingBufRxCtr > 0) /* See if buffer is empty */
{
pbuf->RingBufRxCtr--; /* No, decrement character count */
c = *pbuf->RingBufRxOutPtr++; /* Get character from buffer */
if (pbuf->RingBufRxOutPtr == &pbuf->RingBufRx[COM_RX_BUF_SIZE])
{
pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0]; /* Wrap OUT pointer */
}
OS_EXIT_CRITICAL();
*err = COM_NO_ERR;
return (c);
} else {
OS_EXIT_CRITICAL();
*err = COM_RX_EMPTY;
c = 0; /* Buffer is empty, return 0 */
return (c);
}
}
/************************************************************
* function : COMPutCharB
* parameter: char port, port can be COM1 / COM2
* return : COMM_NO_ERR if the function was successful (the buffer was not full)
* COMM_TX_FULL if the buffer was full
* COMM_BAD_CH if you have specified an incorrect channel
* usage : This function is called by your application to send a character on the communications
* channel. The character to send is first inserted into the Tx buffer and will be sent by
* the Tx ISR. If this is the first character placed into the buffer, the Tx ISR will be
* enabled. If the Tx buffer is full, the character will not be sent (i.e. it will be lost)
* changelog:
* 1.first implimented by liyuan 2010.11.5
*************************************************************/
unsigned char COMPutCharB (unsigned char port, unsigned char c)
{
// unsigned char cpu_sr;
COM_RING_BUF *pbuf;
switch (port)
{ /* Obtain pointer to communications channel */
case COM1:
pbuf = &COM1Buf;
break;
case COM2:
pbuf = &COM2Buf;
break;
default:
return (COM_BAD_CH);
}
OS_ENTER_CRITICAL();
if (pbuf->RingBufTxCtr < COM_TX_BUF_SIZE) { /* See if buffer is full */
pbuf->RingBufTxCtr++; /* No, increment character count */
*pbuf->RingBufTxInPtr++ = c; /* Put character into buffer */
if (pbuf->RingBufTxInPtr == &pbuf->RingBufTx[COM_TX_BUF_SIZE]) { /* Wrap IN pointer */
pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];
}
if (pbuf->RingBufTxCtr == 1) { /* See if this is the first character */
COMEnableTxInt(port); /* Yes, Enable Tx interrupts */
OS_EXIT_CRITICAL();
} else {
OS_EXIT_CRITICAL();
}
return (COM_NO_ERR);
} else {
OS_EXIT_CRITICAL();
return (COM_TX_FULL);
}
}
/************************************************************
* function : COMBufferInit
* parameter:
* return :
* usage : This function is called by your application to initialize the communications module. You
* must call this function before calling any other functions.
* changelog:
*************************************************************/
void COMBufferInit (void)
{
COM_RING_BUF *pbuf;
pbuf = &COM1Buf; /* Initialize the ring buffer for COM0 */
pbuf->RingBufRxCtr = 0;
pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];
pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
pbuf->RingBufTxCtr = 0;
pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];
pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];
pbuf = &COM2Buf; /* Initialize the ring buffer for COM1 */
pbuf->RingBufRxCtr = 0;
pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];
pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
pbuf->RingBufTxCtr = 0;
pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];
pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];
}
/************************************************************
* function : COMBufferIsEmpty
* parameter: char port, port can be COM1 / COM2
* return : char
* usage : This function is called by your application to see
* if any character is available from the communications channel.
* If at least one character is available, the function returns
* FALSE(0) otherwise, the function returns TRUE(1).
* changelog:
*************************************************************/
unsigned char COMBufferIsEmpty (unsigned char port)
{
// unsigned char cpu_sr;
unsigned char empty;
COM_RING_BUF *pbuf;
switch (port)
{ /* Obtain pointer to communications channel */
case COM1:
pbuf = &COM1Buf;
break;
case COM2:
pbuf = &COM2Buf;
break;
default:
return (1);
}
OS_ENTER_CRITICAL();
if (pbuf->RingBufRxCtr > 0)
{ /* See if buffer is empty */
empty = 0; /* Buffer is NOT empty */
}
else
{
empty = 1; /* Buffer is empty */
}
OS_EXIT_CRITICAL();
return (empty);
}
/************************************************************
* function : COMBufferIsFull
* parameter: char port, port can be COM1 / COM2
* return : char
* usage : This function is called by your application to see if any more characters can be placed
* in the Tx buffer. In other words, this function check to see if the Tx buffer is full.
* If the buffer is full, the function returns TRUE otherwise, the function returns FALSE.
* changelog:
*************************************************************/
unsigned char COMBufferIsFull (unsigned char port)
{
// unsigned char cpu_sr;
char full;
COM_RING_BUF *pbuf;
switch (port)
{ /* Obtain pointer to communications channel */
case COM1:
pbuf = &COM1Buf;
break;
case COM2:
pbuf = &COM2Buf;
break;
default:
return (1);
}
OS_ENTER_CRITICAL();
if (pbuf->RingBufTxCtr < COM_TX_BUF_SIZE) { /* See if buffer is full */
full = 0; /* Buffer is NOT full */
} else {
full = 1; /* Buffer is full */
}
OS_EXIT_CRITICAL();
return (full);
}
// This function is called by the Rx ISR to insert a character into the receive ring buffer.
static void COMPutRxChar (unsigned char port, unsigned char c)
{
COM_RING_BUF *pbuf;
switch (port)
{ /* Obtain pointer to communications channel */
case COM1:
pbuf = &COM1Buf;
break;
case COM2:
pbuf = &COM2Buf;
break;
default:
return;
}
if (pbuf->RingBufRxCtr < COM_RX_BUF_SIZE) { /* See if buffer is full */
pbuf->RingBufRxCtr++; /* No, increment character count */
*pbuf->RingBufRxInPtr++ = c; /* Put character into buffer */
if (pbuf->RingBufRxInPtr == &pbuf->RingBufRx[COM_RX_BUF_SIZE]) { /* Wrap IN pointer */
pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];
}
}
}
// This function is called by the Tx ISR to extract the next character from the Tx buffer.
// The function returns FALSE if the buffer is empty after the character is extracted from
// the buffer. This is done to signal the Tx ISR to disable interrupts because this is the
// last character to send.
static unsigned char COMGetTxChar (unsigned char port, unsigned char *err)
{
unsigned char c;
COM_RING_BUF *pbuf;
switch (port)
{ /* Obtain pointer to communications channel */
case COM1:
pbuf = &COM1Buf;
break;
case COM2:
pbuf = &COM2Buf;
break;
default:
*err = COM_BAD_CH;
return (0);
}
if (pbuf->RingBufTxCtr > 0) { /* See if buffer is empty */
pbuf->RingBufTxCtr--; /* No, decrement character count */
c = *pbuf->RingBufTxOutPtr++; /* Get character from buffer */
if (pbuf->RingBufTxOutPtr == &pbuf->RingBufTx[COM_TX_BUF_SIZE])
{
pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0]; /* Wrap OUT pointer */
}
*err = COM_NO_ERR;
return (c); /* Characters are still available */
} else {
*err = COM_TX_EMPTY;
return (0); /* Buffer is empty */
}
}
void USART1_IRQHandler(void)
{
unsigned int data;
unsigned char err;
if(USART1->SR & 0x0F)
{
// See if we have some kind of error
// Clear interrupt (do nothing about it!)
data = USART1->DR;
}
else if(USART1->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag
{
data = USART1->DR;
COMPutRxChar(COM1, data); // Insert received character into buffer
}
else if(USART1->SR & USART_FLAG_TXE)
{
data = COMGetTxChar(COM1, &err); // Get next character to send.
if (err == COM_TX_EMPTY)
{ // Do we have anymore characters to send ?
// No, Disable Tx interrupts
//USART_ITConfig(USART1, USART_IT_TXE| USART_IT_TC, ENABLE);
USART1->CR1 &= ~USART_FLAG_TXE | USART_FLAG_TC;
}
else
{
USART1->DR = data; // Yes, Send character
}
}
}
void USART2_IRQHandler(void)
{
unsigned int data;
unsigned char err;
if(USART2->SR & 0x0F)
{
// See if we have some kind of error
// Clear interrupt (do nothing about it!)
data = USART2->DR;
}
else if(USART2->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag
{
data = USART2->DR;
COMPutRxChar(COM2, data); // Insert received character into buffer
}
else if(USART2->SR & USART_FLAG_TXE)
{
data = COMGetTxChar(COM2, &err); // Get next character to send.
if (err == COM_TX_EMPTY)
{ // Do we have anymore characters to send ?
// No, Disable Tx interrupts
//USART_ITConfig(USART2, USART_IT_TXE| USART_IT_TC, ENABLE);
USART2->CR1 &= ~USART_FLAG_TXE | USART_FLAG_TC;
}
else
{
USART2->DR = data; // Yes, Send character
}
}
}
下面给个例子主程序,来演示如何使用上面的串口驱动代码。
#include "misc.h"
#include "stm32f10x.h"
#include "com_buffered.h"
void UART_PutStrB (unsigned char port, uint8_t *str)
{
while (0 != *str)
{
COMPutCharB(port, *str);
str++;
}
}
void USART1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure );
USART_Cmd(USART1, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void USART2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure );
USART_Cmd(USART2, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
int main(void)
{
unsigned char c;
unsigned char err;
USART1_Init();
USART2_Init();
COMBufferInit();
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
UART_PutStrB(COM1, "Hello World!\n");
for(;;)
{
c = COMGetCharB(COM1, &err);
if(err == COM_NO_ERR)
{
COMPutCharB(COM1, c);
}
}
}
http://blog.csdn.net/hongzg1982/article/details/47280667