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 寄存器描述


这里只贴出部分

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

[cpp] view plaincopy
  1. /*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
  2. /** @addtogroup LPC11xx_UART LPC11xx Universal Asynchronous Receiver/Transmitter
  3. @{
  4. */
  5. typedef struct
  6. {
  7. union {
  8. __I  uint32_t  RBR;                   /*!< Offset: 0x000 Receiver Buffer  Register (R/ ) */
  9. __O  uint32_t  THR;                   /*!< Offset: 0x000 Transmit Holding Register ( /W) */
  10. __IO uint32_t  DLL;                   /*!< Offset: 0x000 Divisor Latch LSB (R/W) */
  11. };
  12. union {
  13. __IO uint32_t  DLM;                   /*!< Offset: 0x004 Divisor Latch MSB (R/W) */
  14. __IO uint32_t  IER;                   /*!< Offset: 0x000 Interrupt Enable Register (R/W) */
  15. };
  16. union {
  17. __I  uint32_t  IIR;                   /*!< Offset: 0x008 Interrupt ID Register (R/ ) */
  18. __O  uint32_t  FCR;                   /*!< Offset: 0x008 FIFO Control Register ( /W) */
  19. };
  20. __IO uint32_t  LCR;                   /*!< Offset: 0x00C Line Control Register (R/W) */
  21. __IO uint32_t  MCR;                   /*!< Offset: 0x010 Modem control Register (R/W) */
  22. __I  uint32_t  LSR;                   /*!< Offset: 0x014 Line Status Register (R/ ) */
  23. __I  uint32_t  MSR;                   /*!< Offset: 0x018 Modem status Register (R/ ) */
  24. __IO uint32_t  SCR;                   /*!< Offset: 0x01C Scratch Pad Register (R/W) */
  25. __IO uint32_t  ACR;                   /*!< Offset: 0x020 Auto-baud Control Register (R/W) */
  26. uint32_t  RESERVED0;
  27. __IO uint32_t  FDR;                   /*!< Offset: 0x028 Fractional Divider Register (R/W) */
  28. uint32_t  RESERVED1;
  29. __IO uint32_t  TER;                   /*!< Offset: 0x030 Transmit Enable Register (R/W) */
  30. uint32_t  RESERVED2[6];
  31. __IO uint32_t  RS485CTRL;             /*!< Offset: 0x04C RS-485/EIA-485 Control Register (R/W) */
  32. __IO uint32_t  ADRMATCH;              /*!< Offset: 0x050 RS-485/EIA-485 address match Register (R/W) */
  33. __IO uint32_t  RS485DLY;              /*!< Offset: 0x054 RS-485/EIA-485 direction control delay Register (R/W) */
  34. __I  uint32_t  FIFOLVL;               /*!< Offset: 0x058 FIFO Level Register (R) */
  35. } LPC_UART_TypeDef;
  36. /*@}*/ /* end of group LPC11xx_UART */

相关宏定义(部分)

[cpp] view plaincopy
  1. ****************************************************************************/
  2. #ifndef __UART_H
  3. #define __UART_H
  4. #define RS485_ENABLED   0
  5. #define TX_INTERRUPT    0       /* 0 if TX uses polling, 1 interrupt driven. */
  6. #define MODEM_TEST      0
  7. #define IER_RBR         (0x01<<0)
  8. #define IER_THRE        (0x01<<1)
  9. #define IER_RLS         (0x01<<2)
  10. #define IIR_PEND        0x01
  11. #define IIR_RLS         0x03
  12. #define IIR_RDA         0x02
  13. #define IIR_CTI         0x06
  14. #define IIR_THRE        0x01
  15. #define LSR_RDR         (0x01<<0)
  16. #define LSR_OE          (0x01<<1)
  17. #define LSR_PE          (0x01<<2)
  18. #define LSR_FE          (0x01<<3)
  19. #define LSR_BI          (0x01<<4)
  20. #define LSR_THRE        (0x01<<5)
  21. #define LSR_TEMT        (0x01<<6)
  22. #define LSR_RXFE        (0x01<<7)
  23. #define UART0_RBUF_SIZE 64

二、UART的初始化

[cpp] view plaincopy
  1. /*****************************************************************************
  2. ** Function name:       UARTInit
  3. **
  4. ** Descriptions:        Initialize UART0 port, setup pin select,
  5. **                      clock, parity, stop bits, FIFO, etc.
  6. **
  7. ** parameters:          UART baudrate
  8. ** Returned value:      None
  9. **
  10. *****************************************************************************/
  11. void UARTInit(uint32_t baudrate)
  12. {
  13. uint32_t Fdiv;
  14. uint32_t regVal;
  15. UARTTxEmpty = 1;
  16. UARTCount = 0;
  17. NVIC_DisableIRQ(UART_IRQn);
  18. LPC_IOCON->PIO1_6 &= ~0x07;    /*  UART I/O config */
  19. LPC_IOCON->PIO1_6 |= 0x01;     /* UART RXD */
  20. LPC_IOCON->PIO1_7 &= ~0x07;
  21. LPC_IOCON->PIO1_7 |= 0x01;     /* UART TXD */
  22. /* Enable UART clock */
  23. LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);
  24. LPC_SYSCON->UARTCLKDIV = 0x1;     /* divided by 1 */
  25. LPC_UART->LCR = 0x83;             /* 8 bits, no Parity, 1 Stop bit */
  26. regVal = LPC_SYSCON->UARTCLKDIV;
  27. Fdiv = ((SystemAHBFrequency/regVal)/16)/baudrate ;    /*baud rate */
  28. LPC_UART->DLM = Fdiv / 256;
  29. LPC_UART->DLL = Fdiv % 256;
  30. LPC_UART->LCR = 0x03;      /* DLAB = 0 */
  31. LPC_UART->FCR = 0x07;      /* Enable and reset TX and RX FIFO. */
  32. /* Read to clear the line status. */
  33. regVal = LPC_UART->LSR;
  34. /* Ensure a clean start, no data in either TX or RX FIFO. */
  35. while (( LPC_UART->LSR & (LSR_THRE|LSR_TEMT)) != (LSR_THRE|LSR_TEMT) );
  36. while ( LPC_UART->LSR & LSR_RDR )
  37. {
  38. regVal = LPC_UART->RBR;  /* Dump data from RX FIFO */
  39. }
  40. /* Enable the UART Interrupt */
  41. NVIC_EnableIRQ(UART_IRQn);
  42. #if TX_INTERRUPT
  43. LPC_UART->IER = IER_RBR | IER_THRE | IER_RLS;  /* Enable UART interrupt */
  44. #else
  45. LPC_UART->IER = IER_RBR | IER_RLS; /* Enable UART interrupt */
  46. #endif
  47. return;
  48. }

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

1、对IO口进行设置

以PIO1_7寄存器为例

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

[cpp] view plaincopy
  1. LPC_IOCON->PIO1_6 &= ~0x07;    /*  UART I/O config */
  2. LPC_IOCON->PIO1_6 |= 0x01;     /* UART RXD */
  3. LPC_IOCON->PIO1_7 &= ~0x07;
  4. LPC_IOCON->PIO1_7 |= 0x01;     /* UART TXD */

2、时钟设置

[cpp] view plaincopy
  1. /* Enable UART clock */
  2. LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);
  3. LPC_SYSCON->UARTCLKDIV = 0x1;     /* divided by 1 */

3、设置波特率、数据位

[cpp] view plaincopy
  1. LPC_UART->LCR = 0x83;             /* 8 bits, no Parity, 1 Stop bit */
  2. regVal = LPC_SYSCON->UARTCLKDIV;
  3. Fdiv = ((SystemAHBFrequency/regVal)/16)/baudrate ;  /*baud rate */

4、UART相应配置

[cpp] view plaincopy
  1. LPC_UART->DLM = Fdiv / 256;
  2. LPC_UART->DLL = Fdiv % 256;
  3. LPC_UART->LCR = 0x03;        /* DLAB = 0 */
  4. LPC_UART->FCR = 0x07;        /* Enable and reset TX and RX FIFO. */

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

5、使能中断等操作

[cpp] view plaincopy
  1. /* Read to clear the line status. */
  2. regVal = LPC_UART->LSR;
  3. /* Ensure a clean start, no data in either TX or RX FIFO. */
  4. while (( LPC_UART->LSR & (LSR_THRE|LSR_TEMT)) != (LSR_THRE|LSR_TEMT) );
  5. while ( LPC_UART->LSR & LSR_RDR )
  6. {
  7. regVal = LPC_UART->RBR;  /* Dump data from RX FIFO */
  8. }
  9. /* Enable the UART Interrupt */
  10. NVIC_EnableIRQ(UART_IRQn);
  11. #if TX_INTERRUPT
  12. LPC_UART->IER = IER_RBR | IER_THRE | IER_RLS;  /* Enable UART interrupt */
  13. #else
  14. LPC_UART->IER = IER_RBR | IER_RLS; /* Enable UART interrupt */
  15. #endif

LCR寄存器作用


三、发送数据

[cpp] view plaincopy
  1. /*****************************************************************************
  2. ** Function name:       UARTSend
  3. **
  4. ** Descriptions:        Send a block of data to the UART 0 port based
  5. **                      on the data length
  6. **
  7. ** parameters:          buffer pointer, and data length
  8. ** Returned value:      None
  9. **
  10. *****************************************************************************/
  11. void UARTSend(uint8_t *BufferPtr, uint32_t Length)
  12. {
  13. while ( Length != 0 )
  14. {
  15. /* THRE status, contain valid data */
  16. #if !TX_INTERRUPT
  17. while ( !(LPC_UART->LSR & LSR_THRE) );
  18. LPC_UART->THR = *BufferPtr;
  19. #else
  20. /* Below flag is set inside the interrupt handler when THRE occurs. */
  21. while ( !(UARTTxEmpty & 0x01) );
  22. LPC_UART->THR = *BufferPtr;
  23. UARTTxEmpty = 0;  /* not empty in the THR until it shifts out */
  24. #endif
  25. BufferPtr++;
  26. Length--;
  27. }
  28. return;
  29. }

四、接收数据

这里利用中断

[cpp] view plaincopy
  1. /*****************************************************************************
  2. ** Function name:       UART_IRQHandler
  3. **
  4. ** Descriptions:        UART interrupt handler
  5. **
  6. ** parameters:          None
  7. ** Returned value:      None
  8. **
  9. *****************************************************************************/
  10. void UART_IRQHandler(void)
  11. {
  12. uint8_t IIRValue, LSRValue;
  13. uint8_t Dummy = Dummy;
  14. IIRValue = LPC_UART->IIR;
  15. IIRValue >>= 1;         /* skip pending bit in IIR */
  16. IIRValue &= 0x07;         /* check bit 1~3, interrupt identification */
  17. if (IIRValue == IIR_RLS)      /* Receive Line Status */
  18. {
  19. LSRValue = LPC_UART->LSR;
  20. /* Receive Line Status */
  21. if (LSRValue & (LSR_OE | LSR_PE | LSR_FE | LSR_RXFE | LSR_BI))
  22. {
  23. /* There are errors or break interrupt */
  24. /* Read LSR will clear the interrupt */
  25. UARTStatus = LSRValue;
  26. Dummy = LPC_UART->RBR; /* Dummy read on RX to clear
  27. interrupt, then bail out */
  28. return;
  29. }
  30. if (LSRValue & LSR_RDR) /* Receive Data Ready */
  31. {
  32. /* If no error on RLS, normal ready, save into the data buffer. */
  33. /* Note: read RBR will clear the interrupt */
  34. UARTBuffer[UARTCount++] = LPC_UART->RBR;
  35. if (UARTCount >= UART0_RBUF_SIZE)
  36. {
  37. UARTCount = 0;      /* buffer overflow */
  38. }
  39. }
  40. }
  41. else if (IIRValue == IIR_RDA) /* Receive Data Available */
  42. {
  43. /* Receive Data Available */
  44. UARTBuffer[UARTCount++] = LPC_UART->RBR;
  45. if (UARTCount >= UART0_RBUF_SIZE)
  46. {
  47. UARTCount = 0;        /* buffer overflow */
  48. }
  49. }
  50. else if (IIRValue == IIR_CTI) /* Character timeout indicator */
  51. {
  52. /* Character Time-out indicator */
  53. UARTStatus |= 0x100;        /* Bit 9 as the CTI error */
  54. }
  55. else if (IIRValue == IIR_THRE)    /* THRE, transmit holding register empty */
  56. {
  57. /* THRE interrupt */
  58. LSRValue = LPC_UART->LSR;        /* Check status in the LSR to see if
  59. valid data in U0THR or not */
  60. if (LSRValue & LSR_THRE)
  61. {
  62. UARTTxEmpty = 1;
  63. }
  64. else
  65. {
  66. UARTTxEmpty = 0;
  67. }
  68. }
  69. return;
  70. }

下面学习一下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 plaincopy
  1. /*******************************************************************************
  2. * Function Name  : UART0_PutChar
  3. * Description    : Send a char to uart0 channel.
  4. * Input          : c
  5. * Output         : None
  6. * Return         : None
  7. *******************************************************************************/
  8. void UART0_PutChar(char ch)
  9. {
  10. while(!(LPC_UART->LSR & LSR_THRE));
  11. LPC_UART->THR = ch;
  12. }
  13. /*******************************************************************************
  14. * Function Name  : uart0_sendstring
  15. * Description    : Send string to uart0 channel.
  16. * Input          : pString  --  string
  17. * Output         : None
  18. * Return         : None
  19. *******************************************************************************/
  20. void UART0_PutString(char *pString)
  21. {
  22. while(*pString)
  23. {
  24. UART0_PutChar(*pString++);
  25. }
  26. }
  27. /*******************************************************************************
  28. * Function Name  : UART0_printf
  29. * Description    : print format string.
  30. * Input          : fmt
  31. * Output         : None
  32. * Return         : None
  33. *******************************************************************************/
  34. void UART0_printf(char *fmt, ...)
  35. {
  36. char      uart0_pString[101];
  37. va_list   uart0_ap;
  38. va_start(uart0_ap, fmt);
  39. vsnprintf(uart0_pString, 100, fmt, uart0_ap);
  40. UART0_PutString(uart0_pString);
  41. va_end(uart0_ap);
  42. }
  43. /*******************************************************************************
  44. * Function Name  : UART0_GetChar
  45. * Description    : print format string.
  46. * Input          : fmt
  47. * Output         : None
  48. * Return         : None
  49. *******************************************************************************/
  50. uint8_t UART0_GetChar(uint8_t *ch)
  51. {
  52. if(UART_op != UARTCount)
  53. {
  54. *ch = UARTBuffer[UART_op];
  55. UART_op ++;
  56. if(UART_op >= UART0_RBUF_SIZE)
  57. UART_op = 0;
  58. return 1;
  59. }
  60. return 0;
  61. }

CortexM0开发 —— LPC11C14的UART使用方法相关推荐

  1. python语言编程环境-python语言开发搭建电脑环境的方法

    python语言开发搭建电脑环境的方法 发布时间:2020-08-24 15:57:58 来源:亿速云 阅读:89 作者:小新 这篇文章主要介绍了python语言开发搭建电脑环境的方法,具有一定借鉴价 ...

  2. Oracle数据库中调用Java类开发存储过程、函数的方法

    Oracle数据库中调用Java类开发存储过程.函数的方法 时间:2014年12月24日  浏览:5538次 oracle数据库的开发非常灵活,不仅支持最基本的SQL,而且还提供了独有的PL/SQL, ...

  3. 用Delphi开发OPC客户端工具的方法研究

    用Delphi开发OPC客户端工具的方法研究[1]<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:o ...

  4. Android轮播图实现图片圆角,Android开发实现图片圆角的方法

    本文讲述了Android开发实现图片圆角的方法.分享给大家供大家参考,具体如下: Bitmap myCoolBitmap = ... ; // int w = myCoolBitmap.getWidt ...

  5. 在android开发中使用multdex的方法-IT蓝豹为你整理

    在android开发中使用multdex的方法-IT蓝豹为你整理 Android系统在安装应用时,往往需要优化Dex,而由于处理工具DexOpt对id数目的限制,导致其处理的数目不能超过65536个, ...

  6. java postdelayed_Android开发使用Handler的PostDelayed方法实现图片轮播功能

    本文实例讲述了Android开发使用Handler的PostDelayed方法实现图片轮播功能.分享给大家供大家参考,具体如下: 第一步:创建MainActivity类 public class Ba ...

  7. php面向对象项目,PHP的面向对象编程:开发大型PHP项目的方法(一)

    PHP(PHP培训 php教程 )的面向对象编程:开发大型PHP项目的方法(一) 作者:Luis Argerich 译者:limodou 这篇文章介绍了在PHP中的面向对象编程(OOP,Object ...

  8. struts2开发action 的三种方法以及通配符、路径匹配原则、常量

    struts2开发action 的三种方法 1.继承ActionSupport public class UserAction extends ActionSupport {// Action中业务处 ...

  9. 【VS开发】CString 转为 char *方法大全

    [VS开发]CString 转为 char *方法大全 标签(空格分隔): [VS开发] 方法1: CString strTemp; char szTemp[128];strTemp = _T(&qu ...

最新文章

  1. github上搭建个人博客
  2. c++申请内存空间_有没有想过:malloc分配的内存空间地址连续吗
  3. MySQL内连接方法_Mysql常用的几种join连接方式
  4. wpfdiagram 学习 教学_李倩、吴欣歆:新高考背景下高中语文教学的三个转变
  5. html乱码框框,springmvc+font-awesome开发出的页面显示方框乱码的解决方法
  6. php分享十七:http状态码
  7. H3C DHCP实验
  8. Python应用|TOPSIS综合评价法与案例分析
  9. flv怎么转换成html5,快速教你如何将FLV转换MP4格式
  10. Java web 几种实现在网页页面里播放视频的 插件及方法
  11. 浏览器被劫持怎么办,详细讲解浏览器DNS被劫持的解决方法
  12. 基于微信小程序的小程序记账本APP源码
  13. 指针数组下标JAVA_Java语言中可用下标和指针两种方式表示数组元素。
  14. EFS与NTFS联合应用解析
  15. 用 zCloud 解锁智能运维,“以小为美”的苏州银行成就数字化转型“大作为”...
  16. 光照模型-兰伯特光照模型
  17. Python-wxPython
  18. OC Extension OveralHeader(常用屏幕尺寸数据 宏定义) 常量
  19. Jzoj4210 我才不是萝莉控呢
  20. 深度解析Apollo无人车感知和定位技术

热门文章

  1. C2审核模式(c2 audit mode)
  2. 【翻译】Ext JS 4——Ajax和Rest代理处理服务器端一场和消息的方法
  3. 报告显示Q2 Android平板电脑全球市场份额达67%
  4. 小议程序员编写技术文档
  5. 献给那些离婚或准备离婚的人
  6. mysql 迁移到tidb_通过从MySQL迁移到TiDB来水平扩展Hive Metastore数据库
  7. 什么是数据仓库,何时以及为什么要考虑一个
  8. leetcode990. 等式方程的可满足性(并查集)
  9. phpstorm 调试_PhpStorm中的多用户调试
  10. 亚马逊 各国站点 链接_使用Amazon S3和HTTPS的简单站点托管