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的初始化
- /*****************************************************************************
- ** 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寄存器作用
三、发送数据
- /*****************************************************************************
- ** 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
五、其他操作补充
- /*******************************************************************************
- * 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使用方法相关推荐
- python语言编程环境-python语言开发搭建电脑环境的方法
python语言开发搭建电脑环境的方法 发布时间:2020-08-24 15:57:58 来源:亿速云 阅读:89 作者:小新 这篇文章主要介绍了python语言开发搭建电脑环境的方法,具有一定借鉴价 ...
- Oracle数据库中调用Java类开发存储过程、函数的方法
Oracle数据库中调用Java类开发存储过程.函数的方法 时间:2014年12月24日 浏览:5538次 oracle数据库的开发非常灵活,不仅支持最基本的SQL,而且还提供了独有的PL/SQL, ...
- 用Delphi开发OPC客户端工具的方法研究
用Delphi开发OPC客户端工具的方法研究[1]<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:o ...
- Android轮播图实现图片圆角,Android开发实现图片圆角的方法
本文讲述了Android开发实现图片圆角的方法.分享给大家供大家参考,具体如下: Bitmap myCoolBitmap = ... ; // int w = myCoolBitmap.getWidt ...
- 在android开发中使用multdex的方法-IT蓝豹为你整理
在android开发中使用multdex的方法-IT蓝豹为你整理 Android系统在安装应用时,往往需要优化Dex,而由于处理工具DexOpt对id数目的限制,导致其处理的数目不能超过65536个, ...
- java postdelayed_Android开发使用Handler的PostDelayed方法实现图片轮播功能
本文实例讲述了Android开发使用Handler的PostDelayed方法实现图片轮播功能.分享给大家供大家参考,具体如下: 第一步:创建MainActivity类 public class Ba ...
- php面向对象项目,PHP的面向对象编程:开发大型PHP项目的方法(一)
PHP(PHP培训 php教程 )的面向对象编程:开发大型PHP项目的方法(一) 作者:Luis Argerich 译者:limodou 这篇文章介绍了在PHP中的面向对象编程(OOP,Object ...
- struts2开发action 的三种方法以及通配符、路径匹配原则、常量
struts2开发action 的三种方法 1.继承ActionSupport public class UserAction extends ActionSupport {// Action中业务处 ...
- 【VS开发】CString 转为 char *方法大全
[VS开发]CString 转为 char *方法大全 标签(空格分隔): [VS开发] 方法1: CString strTemp; char szTemp[128];strTemp = _T(&qu ...
最新文章
- github上搭建个人博客
- c++申请内存空间_有没有想过:malloc分配的内存空间地址连续吗
- MySQL内连接方法_Mysql常用的几种join连接方式
- wpfdiagram 学习 教学_李倩、吴欣歆:新高考背景下高中语文教学的三个转变
- html乱码框框,springmvc+font-awesome开发出的页面显示方框乱码的解决方法
- php分享十七:http状态码
- H3C DHCP实验
- Python应用|TOPSIS综合评价法与案例分析
- flv怎么转换成html5,快速教你如何将FLV转换MP4格式
- Java web 几种实现在网页页面里播放视频的 插件及方法
- 浏览器被劫持怎么办,详细讲解浏览器DNS被劫持的解决方法
- 基于微信小程序的小程序记账本APP源码
- 指针数组下标JAVA_Java语言中可用下标和指针两种方式表示数组元素。
- EFS与NTFS联合应用解析
- 用 zCloud 解锁智能运维,“以小为美”的苏州银行成就数字化转型“大作为”...
- 光照模型-兰伯特光照模型
- Python-wxPython
- OC Extension OveralHeader(常用屏幕尺寸数据 宏定义) 常量
- Jzoj4210 我才不是萝莉控呢
- 深度解析Apollo无人车感知和定位技术
热门文章
- C2审核模式(c2 audit mode)
- 【翻译】Ext JS 4——Ajax和Rest代理处理服务器端一场和消息的方法
- 报告显示Q2 Android平板电脑全球市场份额达67%
- 小议程序员编写技术文档
- 献给那些离婚或准备离婚的人
- mysql 迁移到tidb_通过从MySQL迁移到TiDB来水平扩展Hive Metastore数据库
- 什么是数据仓库,何时以及为什么要考虑一个
- leetcode990. 等式方程的可满足性(并查集)
- phpstorm 调试_PhpStorm中的多用户调试
- 亚马逊 各国站点 链接_使用Amazon S3和HTTPS的简单站点托管