CortexM0开发 —— LPC11C14的UART使用方法

发布者:明月昊天最新更新时间:2019-01-15 来源: eefocus关键字:CortexM0  LPC11C14  UART 手机看文章 扫描二维码
随时随地手机看文章

LPC1100系列微控制器UART  LPC1100系列Cortex-M0微控制器具有一个符合16C550工业标准的异步串行口(UART)。此口同时增加了调制解调器(Modem)接口,DSR、DCD和RI Modem信号是只用于LQFP48和PLCC44封装的管脚配置。 


 特性  


 16字节收发FIFO; 


 寄存器位置符合16C550工业标准;  


 接收器FIFO触发点可为1、4、8和14字节; 


 内置波特率发生器;  


  用于精确控制波特率的小数分频器,并拥有赖以实现软件流控制的自动波特率检测能力和机制;  


 支持软件或硬件流控制执行;  


 包含标准Modem接口信号(CTS、DCD、DTS、DTR、RI、RTS); 


 支持RS-458/EIA-485的9位模式和输出使能。



【实验步骤】:


先看一下板子上UART的原理图



PL-2303HX是一款UART-USB芯片,这里先不管其原理,我们只学习如何将数据从CPU发送到这个TXD RXD处。


一、LPC11C14 UART 寄存器描述



这里只贴出部分



具体寄存器分析,这里不再阐述,先看一下在头文件中我们这样定义

 

/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/  

/** @addtogroup LPC11xx_UART LPC11xx Universal Asynchronous Receiver/Transmitter  

  @{ 

*/  

typedef struct  

{  

  union {  

  __I  uint32_t  RBR;                   /*!< Offset: 0x000 Receiver Buffer  Register (R/ ) */  

  __O  uint32_t  THR;                   /*!< Offset: 0x000 Transmit Holding Register ( /W) */  

  __IO uint32_t  DLL;                   /*!< Offset: 0x000 Divisor Latch LSB (R/W) */  

  };  

  union {  

  __IO uint32_t  DLM;                   /*!< Offset: 0x004 Divisor Latch MSB (R/W) */  

  __IO uint32_t  IER;                   /*!< Offset: 0x000 Interrupt Enable Register (R/W) */  

  };  

  union {  

  __I  uint32_t  IIR;                   /*!< Offset: 0x008 Interrupt ID Register (R/ ) */  

  __O  uint32_t  FCR;                   /*!< Offset: 0x008 FIFO Control Register ( /W) */  

  };  

  __IO uint32_t  LCR;                   /*!< Offset: 0x00C Line Control Register (R/W) */  

  __IO uint32_t  MCR;                   /*!< Offset: 0x010 Modem control Register (R/W) */  

  __I  uint32_t  LSR;                   /*!< Offset: 0x014 Line Status Register (R/ ) */  

  __I  uint32_t  MSR;                   /*!< Offset: 0x018 Modem status Register (R/ ) */  

  __IO uint32_t  SCR;                   /*!< Offset: 0x01C Scratch Pad Register (R/W) */  

  __IO uint32_t  ACR;                   /*!< Offset: 0x020 Auto-baud Control Register (R/W) */  

       uint32_t  RESERVED0;  

  __IO uint32_t  FDR;                   /*!< Offset: 0x028 Fractional Divider Register (R/W) */  

       uint32_t  RESERVED1;  

  __IO uint32_t  TER;                   /*!< Offset: 0x030 Transmit Enable Register (R/W) */  

       uint32_t  RESERVED2[6];  

  __IO uint32_t  RS485CTRL;             /*!< Offset: 0x04C RS-485/EIA-485 Control Register (R/W) */  

  __IO uint32_t  ADRMATCH;              /*!< Offset: 0x050 RS-485/EIA-485 address match Register (R/W) */  

  __IO uint32_t  RS485DLY;              /*!< Offset: 0x054 RS-485/EIA-485 direction control delay Register (R/W) */  

  __I  uint32_t  FIFOLVL;               /*!< Offset: 0x058 FIFO Level Register (R) */  

} LPC_UART_TypeDef;  

/*@}*/ /* end of group LPC11xx_UART */  

相关宏定义(部分)



****************************************************************************/  

#ifndef __UART_H   

#define __UART_H  

  

#define RS485_ENABLED   0  

#define TX_INTERRUPT    0       /* 0 if TX uses polling, 1 interrupt driven. */  

#define MODEM_TEST      0  

  

#define IER_RBR         (0x01<<0)  

#define IER_THRE        (0x01<<1)  

#define IER_RLS         (0x01<<2)  

  

#define IIR_PEND        0x01  

#define IIR_RLS         0x03  

#define IIR_RDA         0x02  

#define IIR_CTI         0x06  

#define IIR_THRE        0x01  

  

#define LSR_RDR         (0x01<<0)  

#define LSR_OE          (0x01<<1)  

#define LSR_PE          (0x01<<2)  

#define LSR_FE          (0x01<<3)  

#define LSR_BI          (0x01<<4)  

#define LSR_THRE        (0x01<<5)  

#define LSR_TEMT        (0x01<<6)  

#define LSR_RXFE        (0x01<<7)  

  

#define UART0_RBUF_SIZE 64  


二、UART的初始化


[cpp] view plain copy  

/***************************************************************************** 

** Function name:       UARTInit 

** 

** Descriptions:        Initialize UART0 port, setup pin select, 

**                      clock, parity, stop bits, FIFO, etc. 

** 

** parameters:          UART baudrate 

** Returned value:      None 

**  

*****************************************************************************/  

void UARTInit(uint32_t baudrate)  

{  

  uint32_t Fdiv;  

  uint32_t regVal;  

  

  UARTTxEmpty = 1;  

  UARTCount = 0;  

    

  NVIC_DisableIRQ(UART_IRQn);  

  

  LPC_IOCON->PIO1_6 &= ~0x07;    /*  UART I/O config */  

  LPC_IOCON->PIO1_6 |= 0x01;     /* UART RXD */  

  LPC_IOCON->PIO1_7 &= ~0x07;      

  LPC_IOCON->PIO1_7 |= 0x01;     /* UART TXD */  

  

  /* Enable UART clock */  

  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);  

  LPC_SYSCON->UARTCLKDIV = 0x1;     /* divided by 1 */  

  

  LPC_UART->LCR = 0x83;             /* 8 bits, no Parity, 1 Stop bit */  

  regVal = LPC_SYSCON->UARTCLKDIV;  

  Fdiv = ((SystemAHBFrequency/regVal)/16)/baudrate ;    /*baud rate */  

  

  LPC_UART->DLM = Fdiv / 256;                              

  LPC_UART->DLL = Fdiv % 256;  

  LPC_UART->LCR = 0x03;      /* DLAB = 0 */  

  LPC_UART->FCR = 0x07;      /* Enable and reset TX and RX FIFO. */  

  

  /* Read to clear the line status. */  

  regVal = LPC_UART->LSR;  

  

  /* Ensure a clean start, no data in either TX or RX FIFO. */  

  while (( LPC_UART->LSR & (LSR_THRE|LSR_TEMT)) != (LSR_THRE|LSR_TEMT) );  

  while ( LPC_UART->LSR & LSR_RDR )  

  {  

    regVal = LPC_UART->RBR;  /* Dump data from RX FIFO */  

  }  

   

  /* Enable the UART Interrupt */  

  NVIC_EnableIRQ(UART_IRQn);  

  

#if TX_INTERRUPT  

  LPC_UART->IER = IER_RBR | IER_THRE | IER_RLS;  /* Enable UART interrupt */  

#else  

  LPC_UART->IER = IER_RBR | IER_RLS; /* Enable UART interrupt */  

#endif  

  return;  

}  


CortexM0 中UART与CPIO口复用,这里看到用到了PIO1_6 与PIO1_7



1、对IO口进行设置


以PIO1_7寄存器为例



可以看到低3位用于配置管脚功能 001为TXD,PIO1_6配置也相同


LPC_IOCON->PIO1_6 &= ~0x07;    /*  UART I/O config */  

LPC_IOCON->PIO1_6 |= 0x01;     /* UART RXD */  

LPC_IOCON->PIO1_7 &= ~0x07;    

LPC_IOCON->PIO1_7 |= 0x01;     /* UART TXD */  

2、时钟设置


/* Enable UART clock */  

  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);  

  LPC_SYSCON->UARTCLKDIV = 0x1;     /* divided by 1 */  

3、设置波特率、数据位

 

LPC_UART->LCR = 0x83;             /* 8 bits, no Parity, 1 Stop bit */  

regVal = LPC_SYSCON->UARTCLKDIV;  

Fdiv = ((SystemAHBFrequency/regVal)/16)/baudrate ;  /*baud rate */  

4、UART相应配置


LPC_UART->DLM = Fdiv / 256;                            

LPC_UART->DLL = Fdiv % 256;  

LPC_UART->LCR = 0x03;        /* DLAB = 0 */  

LPC_UART->FCR = 0x07;        /* Enable and reset TX and RX FIFO. */  

第4行 FCR为 FIFO控制寄存器。控制UART  FIFO的使用和模式 



5、使能中断等操作


  /* Read to clear the line status. */  

  regVal = LPC_UART->LSR;  

  

  /* Ensure a clean start, no data in either TX or RX FIFO. */  

  while (( LPC_UART->LSR & (LSR_THRE|LSR_TEMT)) != (LSR_THRE|LSR_TEMT) );  

  while ( LPC_UART->LSR & LSR_RDR )  

  {  

    regVal = LPC_UART->RBR;  /* Dump data from RX FIFO */  

  }  

   

  /* Enable the UART Interrupt */  

  NVIC_EnableIRQ(UART_IRQn);  

  

#if TX_INTERRUPT  

  LPC_UART->IER = IER_RBR | IER_THRE | IER_RLS;  /* Enable UART interrupt */  

#else  

  LPC_UART->IER = IER_RBR | IER_RLS; /* Enable UART interrupt */  

#endif  

LCR寄存器作用


三、发送数据


[cpp] view plain copy  

/***************************************************************************** 

** Function name:       UARTSend 

** 

** Descriptions:        Send a block of data to the UART 0 port based 

**                      on the data length 

** 

** parameters:          buffer pointer, and data length 

** Returned value:      None 

**  

*****************************************************************************/  

void UARTSend(uint8_t *BufferPtr, uint32_t Length)  

{  

    

  while ( Length != 0 )  

  {  

      /* THRE status, contain valid data */  

#if !TX_INTERRUPT  

      while ( !(LPC_UART->LSR & LSR_THRE) );  

      LPC_UART->THR = *BufferPtr;  

#else  

      /* Below flag is set inside the interrupt handler when THRE occurs. */  

      while ( !(UARTTxEmpty & 0x01) );  

      LPC_UART->THR = *BufferPtr;  

      UARTTxEmpty = 0;  /* not empty in the THR until it shifts out */  

#endif  

      BufferPtr++;  

      Length--;  

  }  

  return;  

}  



四、接收数据


       这里利用中断


/***************************************************************************** 

** Function name:       UART_IRQHandler 

** 

** Descriptions:        UART interrupt handler 

** 

** parameters:          None 

** Returned value:      None 

**  

*****************************************************************************/  

void UART_IRQHandler(void)  

{  

  uint8_t IIRValue, LSRValue;  

  uint8_t Dummy = Dummy;  

  

  IIRValue = LPC_UART->IIR;  

      

  IIRValue >>= 1;         /* skip pending bit in IIR */  

  IIRValue &= 0x07;         /* check bit 1~3, interrupt identification */  

  if (IIRValue == IIR_RLS)      /* Receive Line Status */  

  {  

    LSRValue = LPC_UART->LSR;  

    /* 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 */  

      UARTStatus = LSRValue;  

      Dummy = LPC_UART->RBR; /* 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 */  

      UARTBuffer[UARTCount++] = LPC_UART->RBR;  

      if (UARTCount >= UART0_RBUF_SIZE)  

      {  

        UARTCount = 0;      /* buffer overflow */  

      }   

    }  

  }  

  else if (IIRValue == IIR_RDA) /* Receive Data Available */  

  {  

    /* Receive Data Available */  

    UARTBuffer[UARTCount++] = LPC_UART->RBR;  

    if (UARTCount >= UART0_RBUF_SIZE)  

    {  

      UARTCount = 0;        /* buffer overflow */  

    }  

  }  

  else if (IIRValue == IIR_CTI) /* Character timeout indicator */  

  {  

    /* Character Time-out indicator */  

    UARTStatus |= 0x100;        /* Bit 9 as the CTI error */  

  }  

  else if (IIRValue == IIR_THRE)    /* THRE, transmit holding register empty */  

  {  

    /* THRE interrupt */  

    LSRValue = LPC_UART->LSR;        /* Check status in the LSR to see if 

                                valid data in U0THR or not */  

    if (LSRValue & LSR_THRE)  

    {  

      UARTTxEmpty = 1;  

    }  

    else  

    {  

      UARTTxEmpty = 0;  

    }  

  }  

  return;  

}  


下面学习一下UART中断



对于UART接口来说,有两种情况可以触发UART接收中断:接收字节数达到接收FIFO的触发点(RDA)、接收超时(CTI)。


(1) 接收字节数达到接收FIFO中的触发点(RDA)


     LPC1100系列Cortex-M0微控制器UART接口具有16字节的接收FIFO,接收触发点可以设置为1、4、8、14字节,当接收到的字节数达到接收触发点时,便会触发中断。


     通过UART FIFO控制寄存器U0FCR,将接收触发点设置为“8字节触发”。那么当UART接收8个字节时,便会触发RDA中断(注:在接收中断使能的前提下)。


下面看一下IIR



五、其他操作补充


[cpp] view plain copy  

/******************************************************************************* 

* Function Name  : UART0_PutChar 

* Description    : Send a char to uart0 channel. 

* Input          : c 

* Output         : None 

* Return         : None 

*******************************************************************************/  

void UART0_PutChar(char ch)  

{  

  while(!(LPC_UART->LSR & LSR_THRE));  

  LPC_UART->THR = ch;  

}  

  

/******************************************************************************* 

* Function Name  : uart0_sendstring 

* Description    : Send string to uart0 channel. 

* Input          : pString  --  string 

* Output         : None 

* Return         : None 

*******************************************************************************/  

void UART0_PutString(char *pString)  

{  

  while(*pString)  

  {  

    UART0_PutChar(*pString++);  

  }  

}  

  

/******************************************************************************* 

* Function Name  : UART0_printf 

* Description    : print format string. 

* Input          : fmt 

* Output         : None 

* Return         : None 

*******************************************************************************/  

void UART0_printf(char *fmt, ...)  

{  

  char      uart0_pString[101];  

  va_list   uart0_ap;  

  

  va_start(uart0_ap, fmt);  

  vsnprintf(uart0_pString, 100, fmt, uart0_ap);  

  UART0_PutString(uart0_pString);  

  va_end(uart0_ap);  

}  

  

/******************************************************************************* 

* Function Name  : UART0_GetChar 

* Description    : print format string. 

* Input          : fmt 

* Output         : None 

* Return         : None 

*******************************************************************************/  

uint8_t UART0_GetChar(uint8_t *ch)  

{  

  if(UART_op != UARTCount)  

  {  

    *ch = UARTBuffer[UART_op];  

    UART_op ++;  

    if(UART_op >= UART0_RBUF_SIZE)  

      UART_op = 0;  

  

    return 1;  

  }  

  

  return 0;  

}  



关键字:CortexM0  LPC11C14  UART 引用地址:CortexM0开发 —— LPC11C14的UART使用方法

上一篇:LPC11C14 启动代码分析
下一篇:LPC178x/7x的GPIO中断

推荐阅读最新更新时间:2024-03-16 16:22

系统时钟和UART的设置
系统时钟: 在开发版上,不同的器件运行在不同的时钟频率上,如CPU可能运行在400Mhz的频率上、SDRAM、DM9000等内存存储运行在100Mhz~133MHz上、 串口i2c等运行在50Mhz上,而在开发板上只有一个12Mhz的晶振,则我们需要设置两个部分 1、提高时钟频率12Mhz提高到400Mhz,有运用到PLL 2、对400Mhz时钟分频,分为400Mhz、100Mhz~133Mhz、50Mhz。 如图所示: 开发板上分布 怎么设置? 相关设置代码 #define S3C2410_MPLL_200MHZ ((0x5c 12)|(0x04 4)|(0x00)) #define S3C2440_MPL
[单片机]
系统时钟和<font color='red'>UART</font>的设置
关于嵌入式UART的功能简介和工作原理
如果用外部时钟,UART能产生更高的速度,每个UART通道能包涵2个64字节的FIFOS缓存,S3C2440 UART包涵可变成的波特率,红外发送,1或者2停止位5,6,7,8数据位和奇偶检测,每个UART包涵1个波特率生成器,发送器,接收器和1个控制单元,看下图: 波特率生成器通过PCLK,FCLK/n 或者UEXTCLK 提供时钟的,发送器和接收器包涵64字节FIFOS和数据移位器,数据被写道FIFO,然后在发送之前拷贝到发送移位器中,然后通过发送数据引脚(TxDn)发送出去,同时,通过接收数据引脚(RxDn)移动接收数据到移动器中,然后从移动器中拷贝数据到FIFO中。
[单片机]
关于嵌入式<font color='red'>UART</font>的功能简介和工作原理
51单片机uart通信协议
  51单片机   51单片机是对所有兼容Intel 8031指令系统的单片机的统称。该系列单片机的始祖是Intel的8004单片机,后来随着Flash rom技术的发展,8004单片机取得了长足的进展,成为应用最广泛的8位单片机之一,其代表型号是ATMEL公司的AT89系列,它广泛应用于工业测控系统之中。很多公司都有51系列的兼容机型推出,今后很长的一段时间内将占有大量市场。51单片机是基础入门的一个单片机,还是应用最广泛的一种。需要注意的是51系列的单片机一般不具备自编程能力。   同样的一段程序,在各个单片机厂家的硬件上运行的结果都是一样的,如ATMEL的89C51(已经停产)、89S51, PHILIPS,和WINBO
[单片机]
51单片机<font color='red'>uart</font>通信协议
STM32L0xx_HAL_Driver库的使用——UART
单片机型号:STM32L051C8T6 开发环境MDK5.12 库版本:STM32L0xx_HAL_Driver V1.1.0 主机环境:Windows XP 之前一直使用的STM32F030C8T6单片机来做开发,因需求更改更换了一个新型号STM32L051C8T6,主要是用到了其低功耗特性,本以为直接把代码拷贝一下就可以使用了,结果是太天真了,STM32F030C8T6使用的库是STM32F0_StdPeriph_Lib而STM32L051C8T6使用的库是STM32L0xx_HAL_Driver两者的差别还是很大的,而且官方也推荐使用后者,没办法,重新学习一下吧。。。参考其例程磕磕绊绊的勉强可以写一个工程了,
[单片机]
十六、S3C2440裸机—UART
16.1 介绍   UART(Universal Asynchronous Receiver Transmitter),通用异步收发器,用来传输穿行数据时   UART 之间以全双工方式传输数据,连线方法只有 3 根电线:TXD 用于发送数据,RXD 用于接收数据,GND用于给双方提供参考地。      串口数据线以 “位”为最小单位传输数据。帧(frame)由具有完整意义的、不可分割的若干位组成,它包含开始位、数据位、校验位和停止位。   UART 使用标准的 TTL/CMOS 逻辑电平(0~5V、0~3.3V、0~2.5V 或 0~1.8V)来表示数据,高电平表示1,低电平表示0。为了增强数据的抗干扰能力、提高传输长度,通常
[单片机]
十六、S3C2440裸机—<font color='red'>UART</font>
8051/2单片机常用的本地通讯方式 UART,RS485,I2C,SPI 之 UART串口通讯 1
一 ,说明 1. 串口UART, 波特率:9600 接设备的时候,一般只接GND RX TX,不会接Vcc,避免与目标设备上的供电冲突。 1.1 RS485标准( +2V ~ +6V:1 / -6V ~ -2V:0) 1.2 RS232标准( -15V ~ -3V:1 / +3V ~ +15V:0),需要MAX232进行电平反转后,才能与MCU进行通讯 1.3 TTL标准( 2.4V--5V:1 / 0V--0.5V:0 ) 二、演示 三、代码: /** * 8051/2 DEMO 3 * 常用的本地通讯方式 * 1. 串口UART, 波特率:9600 * 接设备的时候,一般只接GND RX TX,
[单片机]
8051/2单片机常用的本地通讯方式 <font color='red'>UART</font>,RS485,I2C,SPI 之 <font color='red'>UART</font>串口通讯 1
STM32单片机UART发送配置的步骤及方法
字符发送的过程描述:在UART的发送过程中先将数据输入到发送数据寄存器中(TDR)此时(TXE)被硬件置1,之后TDR寄存器将数据串行移入到发送移位寄存器中,将数据在TX端口发送,此时(TC)被硬件置1。发送与接收是逆过程。 UART发送配置步骤: 1.通过USART_CR1寄存器上置位UE来激活USART。 2.编程USART_CR1的M位来定义字长。 3.在USART_CR2中编程停止位的位数。 4.如果采用多缓冲器通信,配置USART_CR3中的DMA使能位(DMAT)。按多缓冲器通信中的描述配置DMA寄存器。 5.利用USART_BRR寄存器选择要求的波特率。 6. 设置USART_CR1中的TE位,发送一个空闲帧作为
[单片机]
STM32单片机<font color='red'>UART</font>发送配置的步骤及方法
利用FPGA实现UART的设计
引 言 随着计算机技术的发展和广泛应用,尤其是在工业控制领域的应用越来越广泛,计算机通信显的尤为重要。串行通信虽然使设备之间的连线大为减少,但随之带来串/并转换和位计数等问题,这使串行通信技术比并行通信技术更为复杂。串/并转换可用软件实现,也可用硬件实现。用软件实现串行传送大多采用循环移位指令将一个字节由高位到低位(或低位到高位)一位一位依次传送,这种方法虽然简单但速度慢,而且大量占用CPU的时间,影响系统的性能。更为方便的实现方法是用硬件,目前微处理器串行接口常用的LSI 芯片是UART(通用异步收发器)、USART(通用同步异步收发器)和ACIA(异步通信接口适配器)等。不论是哪一种芯片,它们的一种基本功能是实现串/并转换。
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved