TA的每日心情 | 擦汗 2018-8-4 22:53 |
---|
签到天数: 37 天 连续签到: 2 天 [LV.5]常住居民I
|
串口作为 MCU 的重要外部接口,同时也是软件开发重要的调试手段,其重要性不言而喻。RT1052 的串口资源相当丰富的,功能也相当强劲。正点原子号令者 RT1052 开发板所使用的 RT1052CVL5B 最多可提供 8 路串口(LPUART1~8),支持 4~32 倍过采样、支持 7~10 位字符长度、支持自动地址匹配模式、具有独立 FIFO,可编程空闲状态字符长度(1~128)、支持硬件流控、支持 IrDA 1.4 规范、具有 DMA 功能等。
我们将实现利用串口 1 不停的打印信息到电脑上,同时接收从串口发过来的数据,把发送过来的数据直接送回给电脑。号令者 RT1052 开发板板载了 1 个 USB串口和 2 个 RS232 串口。
硬件分析:
串口 1 之前还没有介绍过,本实验用到的串口 1 与 USB 串口并没有在 PCB 上连接在一起,需要通过跳线帽来连接一下。这里我们把 P4 的 RXD 和 TXD 用跳线帽与 P112(GPIO1_IO12)和 P113(GPIO1_IO13)连接起来。
软件分析:
设置 LPUART 波特率时钟
RT1052 所有串口的波特率时钟都是来自: UART_CLK_ROOT:一般选择 PLL3_SW_CLK/6 作为时钟源(时钟频率高,则可生成的波特率范围较宽),而 PLL3_SW_CLK 就是 PLL3 的时钟输出,一般为 480Mhz, PLL3 的设置我们在RT1052_Clock_Init 函数里面就设置好了。
UART_CLK_ROOT 的时钟源由 CSCDR1[UART_CLK_SEL]设置,分频系数( CSCDR1[UART_CLK_PODF]设置。
使能 LPUART1 时钟 ,先来看看串口 1 总的时钟
其中
lpuart1_ipg_clk 时钟,这是串口 1 的外设时钟,用于驱动串口 1 的正常运行(除波特率发生器以外的时钟,都由该时钟驱动),该时钟来自 IPG_CLK_ROOT,由 CCGR5[CG12]控制。
lpuart1_ipg_clk_s 时钟,这是串口 1 的访问时钟,必须开启该时钟,才可以访问串口 1 相关寄存器,该时钟来自 IPG_CLK_ROOT,由 CCGR5[CG12]控制。
lpuart1_lpuart_baud_clk 时钟,这是串口 1 波特率发生器的时钟源,来自:UART_CLK_ROOT,可以把它看作是 lpuart1_lpuart_baud_gateed_clk 时钟的上一级,它无需开关控制。
lpuart1_lpuart_baud_gateed_clk 时钟,这是串口 1 波特率发生器的时钟,该时钟同样是来自:UART_CLK_ROOT,串口 1 的波特率生成和这个时钟直接相关,由 CCGR5[CG12]控制。
要想正常使用串口 1,必须使能三个时钟: lpuart1_ipg_clk、 lpuart1_ipg_clk_s和 lpuart1_lpuart_baud_gateed_clk,这三个时钟都是由: CCGR5[CG12]位控制的,所以我们只需要设置 CCGR5 的第 24, 25 位为 1 即可。
数据发送与接收 通过一个 DATA 寄存器(实际上是操作 2 个 Buffer,当写 DATA 时,数据存入 Tx Buffer,当读 DATA 时,返回 Rx Buffer 数据)实现串口数据的发送和接收,串口 DATA 寄存器各位描述如图
串口初始化函数 LPUART_Init()
- status_t LPUART_Init( LPUART_Type *base,
- const lpuart_config_t *config,
- uint32_t srcClock_Hz);
复制代码
其中
base是可选择为: LPUART1~LPUART8。
config 是个 lpuart_config_t 类型的指针,lpuart_config_t 定义如下:- typedef struct _lpuart_config
- {
- uint32_t baudRate_Bps; //波特率
- lpuart_parity_mode_t parityMode; //奇偶校验
- lpuart_data_bits_t dataBitsCount; //数据长度
- bool isMsb; //是否为 MSB
- #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT)
- && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
- typedef struct _lpuart_config
- {
- uint32_t baudRate_Bps; //波特率
- lpuart_parity_mode_t parityMode; //奇偶校验
- lpuart_data_bits_t dataBitsCount; //数据长度
- bool isMsb; //是否为 MSB
- #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT)
- && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
复制代码 baudRate_Bps 用来设置串口波特率。
baudRate_Bps 用来设置串口波特率。FSL 库给我们提供了一个默认配置函数,使用此函数将串口先配置为默认值,然后在这个默认值的基础上在根据 实 际 情 况 做 修 改 。- void LPUART_GetDefaultConfig(lpuart_config_t *config)
- {
- assert(config);
- config->baudRate_Bps = 115200U; //波特率 115200
- config->parityMode = kLPUART_ParityDisabled; //关闭奇偶校验
- config->dataBitsCount = kLPUART_EightDataBits; //8 位数据位
- config->isMsb = false;
- #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) &&
- FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
- config->stopBitCount = kLPUART_OneStopBit; //1 位停止位
- #endif
- #if defined(FSL_FEATURE_LPUART_HAS_FIFO) &&FSL_FEATURE_LPUART_HAS_FIFO
- config->txFifoWatermark = 0;
- config->rxFifoWatermark = 0;
- #endif
- #if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) &&
- FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
- config->enableRxRTS = false; //关闭 RTS
- config->enableTxCTS = false; //关闭 CTS
- config->txCtsConfig = kLPUART_CtsSampleAtStart;
- config->txCtsSource = kLPUART_CtsSourcePin;
- #endif
- config->rxIdleType = kLPUART_IdleTypeStartBit;
- config->rxIdleConfig = kLPUART_IdleCharacter1;
- config->enableTx = false; //关闭发送
- config->enableRx = false; //关闭接收
- }
复制代码 可以看出函数 LPUART_GetDefaultConfig 其实就是对参数 config 中的成员变量做一个初始化,我们可以拿着这个经过初始化的参数 config 去调用函数 LPUART_Init 来实际配置串口。
串口中断相关函数
函 数LPUART_EnableInterrupts 就是用来使能指定的串口中断的,此函数原型如下:
- <span class="fontstyle2">LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask)</span>
复制代码 串口中断关闭函数为 LPUART_DisableInterrupts,此函数原型如下:
- <span class="fontstyle2">void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask)</span>
复制代码- //使能接收中断
- LPUART_EnableInterrupts(LPUART1,kLPUART_RxDataRegFullInterruptEnable);
- //关闭接收中断
- LPUART_DisableInterrupts(LPUART1,kLPUART_RxDataRegFullInterruptEnable);
复制代码
串口数据收发函数
FSL 库提供了两个用于串口数据收发的函数,先来看一下数据发送函数:
- void LPUART_WriteByte(LPUART_Type *base, uint8_t data)
复制代码
函数第一个参数 base 指定要操作哪个串口,第二个参数是要发送的数据,此函数其实向串口的 DATA 寄存器写一个字节的书进入。数据接收函数原型如下:
- uint8_t LPUART_ReadByte(LPUART_Type *base)
复制代码
参数 base 指定要操作的串口,函数返回值就是读取到的串口接收值,此函数就是读取串口 的 DATA 寄存器。
FSL 库给我们提供了多字节数据的串口收发函数:
- <span class="fontstyle0">void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length)
- status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length)</span>
复制代码
初始化uart
在初始化函数中:设置uart的 时钟,io复用,波特率,8,1,n,最后使能收发。。
我们先调用函数 CLOCK_EnableClock 来使能 LPUART1 的时钟,其实这行代码可以删除掉,因为函数 LPUART_Init 会使能 LPUART1 时钟的。开启 LPUART1 时钟以后设置串口的时钟源为 80Mhz。要使用串口肯定要将相应的 IO 初始化为串口功能, 这里将IOMUXC_GPIO_AD_B0_12 和 IOMUXC_GPIO_AD_B0_13 设置为 LPUART1 的发送和接收 IO。
设置好 IO 以后就是调用函数 LPUART_Init 初始化串口 1,前面已经讲过了此函数怎么使用。 因为我们要使用串口的中断接收,必须在 lpuart.h 里面设置 EN_LPUART1_RX 为 1(默认设置就是 1 的)。该函数才会配置中断使能,以及开启串口 1 的 NVIC 中断。这里我们把串口 1中断的抢占优先级设置为 5,子优先级为 0。
然后在main函数中通过函数 LPUART_WriteBlocking 将数据通过串口发送出去。
- LPUART_WriteBlocking(LPUART1,LPUART_RX_BUF,len);//发送接收到的数据
复制代码
测试效果
|
|