📄 uart.c
字号:
/*************************************************************************
*
* Used with ICCARM and AARM.
*
* (c) Copyright IAR Systems 2006
*
* File name : uart.c
* Description : UARTs module
*
* History :
* 1. Date : August 11, 2006
* Author : Stanimir Bonev
* Description : Create
*
* $Revision: 15135 $
**************************************************************************/
#define UART_GLOBAL
#include "uart.h"
pUartFifo_t pUart1RxFifo; // Pointer to a FIFO Buffer of the UART1 Receive
pUartFifo_t pUart1TxFifo; // Pointer to a FIFO Buffer of the UART1 Transmit
pUartFifo_t pUart2RxFifo; // Pointer to a FIFO Buffer of the UART2 Receive
pUartFifo_t pUart2TxFifo; // Pointer to a FIFO Buffer of the UART2 Transmit
pUartFifo_t pUart3RxFifo; // Pointer to a FIFO Buffer of the UART3 Receive
pUartFifo_t pUart3TxFifo; // Pointer to a FIFO Buffer of the UART3 Transmit
// Hold UART1 Evens (PE, BI, FE, OE)
UartLineEvents_t Uart1LineEvents;
// Hold UART2 Evens (PE, BI, FE, OE)
UartLineEvents_t Uart2LineEvents;
// Hold UART3 Evens (PE, BI, FE, OE)
UartLineEvents_t Uart3LineEvents;
/*************************************************************************
* Function Name: FifoPush
* Parameters: pUartFifo_t Fifo, Int8U Data
*
* Return: Boolean
*
* Description: Push a char in a FIFO. Return TRUE when push is successful
* or FALSE when the FIFO is full.
*
*************************************************************************/
static Boolean FifoPush(pUartFifo_t Fifo, Int8U Data)
{
Int32U IndxTmp;
// calculate next push index
IndxTmp = Fifo->PushIndx + 1;
IndxTmp = IndxTmp % UART_FIFO_SIZE;
// Check FIFO state
if (IndxTmp == Fifo->PopIndx)
{
// The FIFO is full
return(FALSE);
}
// Push the data
Fifo->Buffer[Fifo->PushIndx] = Data;
// Updating the push's index
Fifo->PushIndx = IndxTmp;
return(TRUE);
}
/*************************************************************************
* Function Name: FifoPop
* Parameters: pUartFifo_t Fifo, Int8U Data
*
* Return: Boolean
*
* Description: Pop a char from a FIFO. Return TRUE when pop is successful
* or FALSE when the FIFO is empty.
*
*************************************************************************/
static Boolean FifoPop(pUartFifo_t Fifo, pInt8U pData)
{
Int32U IndxTmp;
// Check FIFO state
if (Fifo->PushIndx == Fifo->PopIndx)
{
// The FIFO is empty
return(FALSE);
}
// Calculate the next pop index
IndxTmp = Fifo->PopIndx + 1;
IndxTmp = IndxTmp % UART_FIFO_SIZE;
// Pop the data
*pData = Fifo->Buffer[Fifo->PopIndx];
// Updating of the pop's index
Fifo->PopIndx = IndxTmp;
return(TRUE);
}
/*************************************************************************
* Function Name: Uart1Isr
* Parameters: none
*
* Return: none
*
* Description: UART 1 interrupt routine
*
*************************************************************************/
void Uart1Isr(void)
{
Int8U Data;
// Recognizing the interrupt event
if(USART_GetFlagStatus(USART1,USART_FLAG_ORE))
{
USART_ClearFlag(USART1,USART_FLAG_ORE);
// Overrun Error
Uart1LineEvents.bOE = TRUE;
}
if(USART_GetFlagStatus(USART1,USART_FLAG_FE))
{
USART_ClearFlag(USART1,USART_FLAG_FE);
// Framing Error
Uart1LineEvents.bFE = TRUE;
}
if(USART_GetFlagStatus(USART1,USART_FLAG_NE))
{
USART_ClearFlag(USART1,USART_FLAG_NE);
// Noise Error
Uart1LineEvents.bFE = TRUE;
}
if(USART_GetFlagStatus(USART1,USART_FLAG_PE))
{
USART_ClearFlag(USART1,USART_FLAG_PE);
// Parity Error
Uart1LineEvents.bPE = TRUE;
}
// Push a new data into the receiver buffer
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE))
{
// Push a new data into the receiver buffer
if(!FifoPush(pUart1RxFifo,USART_ReceiveData(USART1)))
{
// the FIFO is full
Uart1LineEvents.bOE = TRUE;
}
}
if( USART_GetFlagStatus(USART1,USART_FLAG_TXE)
&& (USART_GetITStatus (USART1,USART_IT_TXE) == SET))
{
if(FifoPop(pUart1TxFifo,&Data))
{
USART_SendData(USART1,Data);
}
else
{
USART_ITConfig(USART1,USART_IT_TXE ,DISABLE);
}
}
}
/*************************************************************************
* Function Name: Uart2Isr
* Parameters: none
*
* Return: none
*
* Description: UART 2 interrupt routine
*
*************************************************************************/
void Uart2Isr(void)
{
Int8U Data;
// Recognizing the interrupt event
if(USART_GetFlagStatus(USART2,USART_FLAG_ORE))
{
USART_ClearFlag(USART2,USART_FLAG_ORE);
// Overrun Error
Uart2LineEvents.bOE = TRUE;
}
if(USART_GetFlagStatus(USART2,USART_FLAG_FE))
{
USART_ClearFlag(USART2,USART_FLAG_FE);
// Framing Error
Uart2LineEvents.bFE = TRUE;
}
if(USART_GetFlagStatus(USART2,USART_FLAG_NE))
{
USART_ClearFlag(USART2,USART_FLAG_NE);
// Noise Error
Uart2LineEvents.bFE = TRUE;
}
if(USART_GetFlagStatus(USART2,USART_FLAG_PE))
{
USART_ClearFlag(USART2,USART_FLAG_PE);
// Parity Error
Uart2LineEvents.bPE = TRUE;
}
// Push a new data into the receiver buffer
if(USART_GetFlagStatus(USART2,USART_FLAG_RXNE))
{
// Push a new data into the receiver buffer
if(!FifoPush(pUart2RxFifo,USART_ReceiveData(USART2)))
{
// the FIFO is full
Uart2LineEvents.bOE = TRUE;
}
}
if( USART_GetFlagStatus(USART2,USART_FLAG_TXE)
&& (USART_GetITStatus (USART2,USART_IT_TXE) == SET))
{
if(FifoPop(pUart2TxFifo,&Data))
{
USART_SendData(USART2,Data);
}
else
{
USART_ITConfig(USART2,USART_IT_TXE ,DISABLE);
}
}
}
/*************************************************************************
* Function Name: Uart3Isr
* Parameters: none
*
* Return: none
*
* Description: UART 3 interrupt routine
*
*************************************************************************/
void Uart3Isr(void)
{
Int8U Data;
// Recognizing the interrupt event
if(USART_GetFlagStatus(USART3,USART_FLAG_ORE))
{
USART_ClearFlag(USART3,USART_FLAG_ORE);
// Overrun Error
Uart3LineEvents.bOE = TRUE;
}
if(USART_GetFlagStatus(USART3,USART_FLAG_FE))
{
USART_ClearFlag(USART3,USART_FLAG_FE);
// Framing Error
Uart3LineEvents.bFE = TRUE;
}
if(USART_GetFlagStatus(USART3,USART_FLAG_NE))
{
USART_ClearFlag(USART3,USART_FLAG_NE);
// Noise Error
Uart3LineEvents.bFE = TRUE;
}
if(USART_GetFlagStatus(USART3,USART_FLAG_PE))
{
USART_ClearFlag(USART3,USART_FLAG_PE);
// Parity Error
Uart3LineEvents.bPE = TRUE;
}
if(USART_GetFlagStatus(USART3,USART_FLAG_RXNE))
{
// Push a new data into the receiver buffer
if(!FifoPush(pUart3RxFifo,USART_ReceiveData(USART3)))
{
// the FIFO is full
Uart3LineEvents.bOE = TRUE;
}
}
if( USART_GetFlagStatus(USART3,USART_FLAG_TXE)
&& (USART_GetITStatus (USART3,USART_IT_TXE) == SET))
{
if(FifoPop(pUart3TxFifo,&Data))
{
USART_SendData(USART3,Data);
}
else
{
USART_ITConfig(USART3,USART_IT_TXE ,DISABLE);
}
}
}
/*************************************************************************
* Function Name: UartInit
* Parameters: Int32U IrqSlot
*
* Return: Boolean
*
* Description: Init UART
*
*************************************************************************/
Boolean UartInit(UartNum_t Uart,Int32U IrqSlot)
{
volatile Int8U Tmp;
USART_InitTypeDef UART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_StructInit(&UART_InitStructure);
UART_InitStructure.USART_Parity = USART_Parity_No;
switch(Uart)
{
case UART_1:
pUart1RxFifo = (pUartFifo_t)malloc(sizeof(UartFifo_t));
if(pUart1RxFifo == NULL)
{
return(FALSE);
}
pUart1TxFifo = (pUartFifo_t)malloc(sizeof(UartFifo_t));
if(pUart1TxFifo == NULL)
{
free(pUart1RxFifo);
return(FALSE);
}
// Init receive and transmit FIFOs
pUart1RxFifo->PopIndx = pUart1RxFifo->PushIndx = \
pUart1TxFifo->PopIndx = pUart1TxFifo->PushIndx = 0;
// Release reset and enable clock
USART_DeInit(USART1);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// GPIO Init
// Enable GPIO clock and release reset
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,
ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA,
DISABLE);
GPIO_PinRemapConfig(GPIO_Remap_USART1,DISABLE);
// Assign PA9 to UART1 (Tx)
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Assign PA10 to UART1 (Rx)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Init UART1
USART_Init(USART1,&UART_InitStructure);
// Enable and configure the priority of the UART1 Update IRQ Channel
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = UART1_INTR_PRI;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ClearFlag(USART1, USART_FLAG_CTS | USART_FLAG_LBD | USART_FLAG_TXE |
USART_FLAG_TC | USART_FLAG_RXNE | USART_FLAG_IDLE |
USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE |
USART_FLAG_PE);
// Enable UART1 interrupts
USART_ITConfig(USART1,USART_IT_PE ,ENABLE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -