⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 NXP LPC系列AMR7的开发程序源码(LCD
💻 C
📖 第 1 页 / 共 2 页
字号:
    // Init receive and transmit FIFOs
    pUart1RxFifo->PopIndx = pUart1RxFifo->PushIndx = \
    pUart1TxFifo->PopIndx = pUart1TxFifo->PushIndx = 0;

    // Enable UART1
    PCONP_bit.PCUART1 = 1;
    // TX
    PINSEL0_bit.P0_15 = 1;
    // RX
    PINSEL1_bit.P0_16 = 1;

    U1LCR = 0x03; // Word Length =8, no parity , 1 stop
    U1MCR = 0;    // Word Length =8, no parity , 1 stop
    U1FCR = 0x7;  // Enable and Clear the UART1 FIFO, Set RX FIFO interrupt level - 1 char
    // Transmit enable
    U1TER_bit.TXEN = 1;
    Tmp = U1IER;  // Clear pending interrupts

    // enable RBR Interrupt, THRE Interrupt, RX Line Status Interrupt
    // Modem Status Interrupt, CTS Interrupt Enable
    U1IER = 0x07 | (UART1_MODEM_STAT_ENA?0x88:0);

    VIC_SetVectoredIRQ(Uart1Isr,IrqSlot,VIC_UART1);
    VICINTENABLE |= 1<<VIC_UART1;
    break;
  case UART_2:
    pUart2RxFifo = (pUartFifo_t)malloc(sizeof(UartFifo_t));
    if(pUart2RxFifo == NULL)
    {
      return(FALSE);
    }
    pUart2TxFifo = (pUartFifo_t)malloc(sizeof(UartFifo_t));
    if(pUart2TxFifo == NULL)
    {
      free(pUart2RxFifo);
      return(FALSE);
    }
    // Init receive and transmit FIFOs
    pUart2RxFifo->PopIndx = pUart2RxFifo->PushIndx = \
    pUart2TxFifo->PopIndx = pUart2TxFifo->PushIndx = 0;

    // Enable UART2
    PCONP_bit.PCUART2 = 1;
    // TX
    PINSEL0_bit.P0_10 = 1;
    // RX
    PINSEL0_bit.P0_11 = 1;

    U2LCR = 0x03; // Word Length =8, no parity , 1 stop
    U2FCR = 0x7;  // Enable and Clear the UART2 FIFO, Set RX FIFO interrupt level - 1 char
    // Transmit enable
    U2TER_bit.TXEN = 1;
    Tmp = U2IER;  // Clear pending interrupts
    // enable RBR Interrupt, THRE Interrupt, RX Line Status Interrupt
    U2IER = 0x07;

    VIC_SetVectoredIRQ(Uart2Isr,IrqSlot,VIC_UART2);
    VICINTENABLE |= 1<<VIC_UART2;
    break;
  case UART_3:
    pUart3RxFifo = (pUartFifo_t)malloc(sizeof(UartFifo_t));
    if(pUart3RxFifo == NULL)
    {
      return(FALSE);
    }
    pUart3TxFifo = (pUartFifo_t)malloc(sizeof(UartFifo_t));
    if(pUart3TxFifo == NULL)
    {
      free(pUart3RxFifo);
      return(FALSE);
    }
    // Init receive and transmit FIFOs
    pUart3RxFifo->PopIndx = pUart3RxFifo->PushIndx = \
    pUart3TxFifo->PopIndx = pUart3TxFifo->PushIndx = 0;

    // Enable UART3
    PCONP_bit.PCUART3 = 1;
    // TX
    PINSEL9_bit.P4_28 = 3;
    // RX
    PINSEL9_bit.P4_29 = 3;

    U3LCR = 0x03; // Word Length =8, no parity , 1 stop
    U3FCR = 0x7;  // Enable and Clear the UART3 FIFO, Set RX FIFO interrupt level - 1 char
    // Enable/Disable IrDA mode
    if(UartMode == IRDA)
    {
      U3ICR_bit.FIXPULSEEN = 0;
      U3ICR_bit.IRDAINV = 1;
      U3ICR_bit.IRDAEN = 1;
    }
    else
    {
      U3ICR_bit.IRDAEN = 0;
    }
    // Transmit enable
    U3TER_bit.TXEN = 1;
    Tmp = U3IER;  // Clear pending interrupts
    // enable RBR Interrupt, THRE Interrupt, RX Line Status Interrupt
    U3IER = 0x07;

    VIC_SetVectoredIRQ(Uart3Isr,IrqSlot,VIC_UART3);
    VICINTENABLE |= 1<<VIC_UART3;
    break;
  }
  return(TRUE);
}

/*************************************************************************
 * Function Name: UartCalcDivider
 * Parameters:  Int32U Freq, Int32U Baud
 *              pInt32U pDiv, pInt32U pAddDiv, pInt32U pMul
 *
 * Return: None
 *
 * Description: Calculate the coefficients of the UART baudrate generator
 *
 *************************************************************************/
static
void UartCalcDivider(Int32U Freq, Int32U Baud,
                     pInt32U pDiv, pInt32U pAddDiv, pInt32U pMul)
{
Int32U Temp, Error = (Int32U)-1;
Int32U K1, K2, K3, Baudrate;
Int32U DivTemp, MulTemp, AddDivTemp;

  //
  for(MulTemp = 1; MulTemp < 16; ++MulTemp)
  {
    K1 = Freq*MulTemp;
    for(AddDivTemp = 1; AddDivTemp < 16; ++AddDivTemp)
    {
      K3 = (MulTemp + AddDivTemp)<<4;
      K2 =  K3 * Baud;
      DivTemp = K1/K2;
      // if DIVADDVAL>0, UnDL must be UnDL >= 0x0002 or the UART will
      // not operate at the desired baud-rate!
      if(DivTemp < 2)
      {
        continue;
      }
      Baudrate = DivTemp * K3;
      Baudrate = K1/Baudrate;
      Temp = (Baudrate > Baud)? \
                 (Baudrate - Baud): \
                 (Baud - Baudrate);
      if (Temp < Error)
      {
        Error = Temp;
        *pDiv = DivTemp;
        *pMul = MulTemp;
        *pAddDiv = AddDivTemp;
        if(Error == 0)
        {
          return;
        }
      }
    }
  }
}

/*************************************************************************
 * Function Name: UartSetLineCoding
 * Parameters:  UartNum_t Uart,UartLineCoding_t pUartCoding
 *
 * Return: None
 *
 * Description: Init UART Baud rate, Word width, Stop bits, Parity type
 *
 *************************************************************************/
void UartSetLineCoding(UartNum_t Uart,UartLineCoding_t UartCoding)
{
Int32U Mul, Div, AddDiv, Freq;

  // Check parameters
  if ((UartCoding.dwDTERate == 0) || (UartCoding.dwDTERate > UART_MAX_BAUD_RATE))
  {
    return;
  }
  switch (Uart)
  {
  case UART_0:
    Freq = SYS_GetFpclk(UART0_PCLK_OFFSET);
    UartCalcDivider(Freq,UartCoding.dwDTERate,&Div,&AddDiv,&Mul);
    U0LCR_bit.WLS = UartCoding.bDataBits;
    U0LCR_bit.SBS = UartCoding.bStopBitsFormat;
    U0LCR_bit.PE  =(UartCoding.bParityType == UART_NO_PARITY)?0:1;
    U0LCR_bit.PS  = UartCoding.bParityType;
    U0LCR_bit.DLAB = 1;
    U0DLL = Div & 0xFF;
    U0DLM = (Div >> 8) & 0xFF;
    U0FDR = AddDiv + (Mul << 4);
    U0LCR_bit.DLAB = 0;
    break;
  case UART_1:
    Freq = SYS_GetFpclk(UART1_PCLK_OFFSET);
    UartCalcDivider(Freq,UartCoding.dwDTERate,&Div,&AddDiv,&Mul);
    U1LCR_bit.WLS = UartCoding.bDataBits;
    U1LCR_bit.SBS = UartCoding.bStopBitsFormat;
    U1LCR_bit.PE  =(UartCoding.bParityType == UART_NO_PARITY)?0:1;
    U1LCR_bit.PS  = UartCoding.bParityType;
    U1LCR_bit.DLAB = 1;
    U1DLL = Div & 0xFF;
    U1DLM = (Div >> 8) & 0xFF;
    U1FDR = AddDiv + (Mul << 4);
    U1LCR_bit.DLAB = 0;
    break;
  case UART_2:
    Freq = SYS_GetFpclk(UART2_PCLK_OFFSET);
    UartCalcDivider(Freq,UartCoding.dwDTERate,&Div,&AddDiv,&Mul);
    U2LCR_bit.WLS = UartCoding.bDataBits;
    U2LCR_bit.SBS = UartCoding.bStopBitsFormat;
    U2LCR_bit.PE  =(UartCoding.bParityType == UART_NO_PARITY)?0:1;
    U2LCR_bit.PS  = UartCoding.bParityType;
    U2LCR_bit.DLAB = 1;
    U2DLL = Div & 0xFF;
    U2DLM = (Div >> 8) & 0xFF;
    U2FDR = AddDiv + (Mul << 4);
    U2LCR_bit.DLAB = 0;
    break;
  case UART_3:
    Freq = SYS_GetFpclk(UART3_PCLK_OFFSET);
    UartCalcDivider(Freq,UartCoding.dwDTERate,&Div,&AddDiv,&Mul);
    U3LCR_bit.WLS = UartCoding.bDataBits;
    U3LCR_bit.SBS = UartCoding.bStopBitsFormat;
    U3LCR_bit.PE  =(UartCoding.bParityType == UART_NO_PARITY)?0:1;
    U3LCR_bit.PS  = UartCoding.bParityType;
    U3LCR_bit.DLAB = 1;
    U3DLL = Div & 0xFF;
    U3DLM = (Div >> 8) & 0xFF;
    U3FDR = AddDiv + (Mul << 4);
    U3LCR_bit.DLAB = 0;
    break;
  }
}

/*************************************************************************
 * Function Name: UartRead
 * Parameters:  UartNum_t Uart, pInt8U pBuffer, Int32U BufferSize
 *
 * Return: Int32U
 *
 * Description: Read received data from UART.
 *              Return number of readied characters
 *
 *************************************************************************/
Int32U UartRead(UartNum_t Uart, pInt8U pBuffer, Int32U BufferSize)
{
Int32U Count;
pUartFifo_t pUartFifo;
  switch (Uart)
  {
  case UART_0:
    pUartFifo= pUart0RxFifo;
    break;
  case UART_1:
    pUartFifo= pUart1RxFifo;
    break;
  case UART_2:
    pUartFifo= pUart2RxFifo;
    break;
  case UART_3:
    pUartFifo= pUart3RxFifo;
    break;
  default:
    return(0);
  }

  for (Count = 0; Count < BufferSize; ++Count)
  {
    if(!FifoPop(pUartFifo,pBuffer+Count))
    {
      break;
    }
  }
  return(Count);
}

/*************************************************************************
 * Function Name: UartWrite
 * Parameters:  UartNum_t Uart, pInt8U pBuffer, Int32U BufferSize
 *
 * Return: Int32U
 *
 * Description: Write a data to UART. Return number of successful
 *  transmitted bytes
 *
 *************************************************************************/
Int32U UartWrite(UartNum_t Uart, pInt8U pBuffer, Int32U BufferSize)
{
Int32U Count = 0;
pUartFifo_t pUartFifo;
Int32U save;

  switch (Uart)
  {
  case UART_0:
    pUartFifo= pUart0TxFifo;
    break;
  case UART_1:
    pUartFifo= pUart1TxFifo;
    break;
  case UART_2:
    pUartFifo= pUart2TxFifo;
    break;
  case UART_3:
    pUartFifo= pUart3TxFifo;
    break;
  default:
    return(0);
  }

  if(BufferSize != 0)
  {
    volatile pInt8U pUartTxReg;
    save = __get_interrupt_state();
    __disable_interrupt();
    if((pUartFifo->PushIndx == pUartFifo->PopIndx))
    {
      // The Tx FIFO is empty
      switch (Uart)
      {
      case UART_0:
        pUartTxReg = (pInt8U)&U0THR;
        if(U0LSR_bit.THRE)
        {
          *pUartTxReg = *pBuffer;
          ++Count;
        }
        break;
      case UART_1:
        pUartTxReg = (pInt8U)&U1THR;
        if(U1LSR_bit.THRE)
        {
          *pUartTxReg = *pBuffer;
          ++Count;
        }
        break;
      case UART_2:
        pUartTxReg = (pInt8U)&U2THR;
        if(U2LSR_bit.THRE)
        {
          *pUartTxReg = *pBuffer;
          ++Count;
        }
        break;
      case UART_3:
        pUartTxReg = (pInt8U)&U3THR;
        if(U3LSR_bit.THRE)
        {
          *pUartTxReg = *pBuffer;
          ++Count;
        }
        break;
      }
    }
    for ( ; Count < BufferSize; ++Count)
    {
      if(!FifoPush(pUartFifo,*(pBuffer+Count)))
      {
        break;
      }
    }
    __set_interrupt_state(save);
  }
  return(Count);
}

/*************************************************************************
 * Function Name: UartGetUartEvents
 * Parameters:  UartNum_t Uart
 *
 * Return: UartLineEvents_t
 *
 * Description: Get Uart Line events (PE,OE, FE, BI)
 *
 *************************************************************************/
UartLineEvents_t UartGetUartLineEvents (UartNum_t Uart)

{
UartLineEvents_t  LineEvents;
  LineEvents.Data = 0;

  switch (Uart)
  {
  case UART_0:
    AtomicExchange(LineEvents.Data,&Uart0LineEvents.Data);
    break;
  case UART_1:
    AtomicExchange(LineEvents.Data,&Uart1LineEvents.Data);
    break;
  case UART_2:
    AtomicExchange(LineEvents.Data,&Uart2LineEvents.Data);
    break;
  case UART_3:
    AtomicExchange(LineEvents.Data,&Uart3LineEvents.Data);
    break;
  default:
    LineEvents.Data = 0;
  }
  return(LineEvents);
}

/*************************************************************************
 * Function Name: UartSetUartLineState
 * Parameters:  UartNum_t Uart UartNum_t Uart, Boolean Break
 *
 * Return: none
 *
 * Description: Set Uart Break Event
 *
 *************************************************************************/
void UartSetUartLineState (UartNum_t Uart, Boolean Break)
{
  switch (Uart)
  {
  case UART_0:
    U0LCR_bit.BC  = Break;
    break;
  case UART_1:
    U1LCR_bit.BC  = Break;
    break;
  case UART_2:
    U2LCR_bit.BC  = Break;
    break;
  case UART_3:
    U3LCR_bit.BC  = Break;
  }
}

#if UART1_MODEM_STAT_ENA > 0
/*************************************************************************
 * Function Name: Uart1SetModemLineState
 * Parameters:  UartModemLineState_t UartModemLineState
 *
 * Return: none
 *
 * Description: Init UART1 Modem lines state (RTS, DTR)
 *
 *************************************************************************/
void Uart1SetModemLineState(UartModemLineState_t UartModemLineState)
{
  U1MCR_bit.DTR = UartModemLineState.bDTR;
  U1MCR_bit.RTS = UartModemLineState.bRTS;
}

/*************************************************************************
 * Function Name: Uart1GetUartModemEvents
 * Parameters:  none
 *
 * Return: UartModemEvents_t
 *
 * Description: Get Uart1 Modem lines events (DCD,DSR,CTS,RI)
 *
 *************************************************************************/
UartModemEvents_t Uart1GetUartModemEvents (void)
{
UartModemEvents_t  ModemEvents;
  ModemEvents.Data = 0;
  ModemEvents.Data = AtomicExchange(ModemEvents.Data,(pInt32U)&Uart1ModemEvents);
  return(ModemEvents);
}
#endif // UART1_MODEM_STAT_ENA > 0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -