Skip to content

LV050-imx6ull的uart配置

一、硬件原理分析

1. 原理图

我使用的是正点原子的 ALPHA 开发板,原理图如下:

image-20260115094727154

可以看到,我们需要使用的是串口 1,也就是 UART1。

2. 开发板连接

我们还需要用 USB 串口线将串口 1 和电脑连接起来,并且还需要设置 JP5 跳线帽,将串口 1 的 RXD、 TXD 两个引脚分别与 P116、 P117 连接一起,如图所示:

image-20230729132141751

二、寄存器配置

1. 配置并使能 UART1 时钟

1.1 配置 UART 模块的时钟(寄存器: CCM_CSCDR1)

配置并使能 UART1 时钟,参考资料:《i.MX 6ULL Applications ProcessorReference Manual》参考手册的《 Chapter 18: ClockController Module (CCM)》。 (下图来自参考手册的 Figure 18-3. Clock Tree - Part 2 )

image-20260115095344111

根据上图,我们需要配置 CCM_CSCDR1 [UART_CLK_SEL] 和 CCM_CSCDR1 [UART_CLK_PODF] 两个位:

image-20260115095454150

由上图 CCM_CSCDR1 寄存器,我们可以了解到 CCM_CSCDR1 [UART_CLK_SEL] 默认值(图中 Reset 对应的值)为 0; CCM_CSCDR1 [UART_CLK_PODF] 默认值为 0。我们一般选择 pll3_80m 作为 UART 的时钟源, UART_CLK_PODF 分频系数选 1 分频(不分频),最后得到 UART 的时钟频率为 80MHz。

image-20260115095544294

正好默认值都为 0 满足我们的时钟需求,所以后续的编程实验,串口时钟这部分可以不设置,用默认值就可以了。

1.2 使能 UART 模块的时钟(寄存器: CCM_CCGR5)

image-20260115095706134

由上图 CCM_CCGR5 寄存器,我们可以了解到 CCM_CCGR5 [CG12] 的默认值为 11。我们知道 11 表示该模块全程使能,使用默认值,无需设置。

2. 复用相关 GPIO 为 UART1 功能

2.1 配置 UART1_TX 复用功能

可以参考《i.MX 6ULL Applications ProcessorReference Manual》参考手册的 32.6.17 SW_MUX_CTL_PAD_UART1_TX_DATA SW MUX Control Register (IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA) 用到的寄存器为 IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA。

image-20260115095809174

由上图我们得知 IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA [MUX_MODE] 的默认值为 0101,因此我们需要将其改为 0,用于 UART_TX 功能。

2.2 配置 UART1_RX 复用功能

可以参考《i.MX 6ULL Applications ProcessorReference Manual》参考手册的 32.6.18 SW_MUX_CTL_PAD_UART1_RX_DATA SW MUX Control Register (IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA) 用到的寄存器为 IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA。

image-20260115095848661

由上图我们得知 IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA [MUX_MODE] 的默认值为 0101,因此我们需要将其改为 0,用于 UART_RX 功能。

2.3 选择引脚

IMX6ULL 中,可能会有多个引脚都可以驱动某个模块,还需要进一步选择。比如下图(参考手册 32.3.3 Daisy chain - multi pads driving same module input pin)中: A、 B、 C 三个引脚都可以设置为工作于 Module X,它们都可以驱动 Module X。但是使用哪一个引脚呢?还需要设置“ Daisy Chain select”,

image-20260115100002702

对 于 UART1_RX 引 脚 , 我们除 设置 IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA 让它工作于 ALT0 之外,还需要设置寄存器 IOMUXC_UART1_RX_DATA_SELECT_INPUT,可以参考《i.MX 6ULL Applications ProcessorReference Manual》参考手册的 32.6.360 UART1_RX_DATA_SELECT_INPUT DAISY Register(IOMUXC_UART1_RX_DATA_SELECT_INPUT)

image-20260115100148043

在上图中,引脚 GPIO1_IO02 设置为 ALT8 模式时,它也可以用作 UART1 的 RX 输入引脚;引脚 UART1_RX 设置为 ALT0 模式时,它也可以用作 UART1 的 RX 输入引脚。UART1_RX 为何可以选择那么多引脚?

image-20230729135201594

UART1 的发送引脚有 2 个选择: GPIO1_IO02、 UART1_TX,假设选择了 UART1_TX 作为发送引脚。UART1 的接收引脚有 2 个选择: GPIO1_IO03、 UART1_RX,假设选择了 UART1_RX 作为接收引脚。

但是 UART1 的模块还可能通过 daisy 引脚再次选择: GPIO1_IO02、GPIO1_IO03、 UART1_TX、 UART1_RX 中的某一个。比如上图中,选择 UART1_TX 时,这就构成了回环,可以用于测试: IMX6ULL 发出去的数据直接返回给自己;选择 UART_RX 是,就可以接收外面设备比如 PC 机的数据。

2.4 配置 UART1_TX 硬件参数

寄存器: IOMUXC_SW_PAD_CTL_PAD_UART1_TX_DATA。经过比对,我们使用默认值( 0x10b0)即可,无需配置。

2.5 配置 UART1_RX 硬件参数

寄存器: IOMUXC_SW_PAD_CTL_PAD_UART1_RX_DATA。经过比对,我们使用默认值( 0x10b0)即可,无需配置。

3. 设置 UART1 传输格式,波特率

3.1 配置寄存器 UART1_UCR2(0x2020084)

设置 UART1 传输格式 :

c
UART1->UCR2 |= (1<<14) |(1<<5) |(1<<2)|(1<<1);

bit[14]: 1,忽略 RTS 引脚

bit[8] : 0,关闭奇偶校验 默认为 0,无需设置

bit[6] : 0,停止位 1 位 默认为 0,无需设置

bit[5] : 1,数据长度 8 位

bit[2] : 1,发送数据使能

bit[1]: 1,接收数据使能

3.2 配置寄存器 UART1_UCR3(0x2020088)

c
UART1->UCR3 |= (1<<2);

3.3 寄存器 UART1_UFCR(0x2020090)

UART1_UFCR [9-7]: UART 的时钟源分频系数,我们选择 101(即十进制的 5),表示不分频。

c
UART1->UFCR = 5 << 7; /* Uart 的时钟 clk: 80MHz */

3.4 寄存器 UART1_UBIR(0x20200A4)和 UART1_UBMR(0x20200A8)

通过设置 UART1_UBIR 与 UART1_UBMR,最终确定波特率。

image-20260115100235095

(1)设置 115200 的波特率即 BaudRate = 115200;

(2)UART1 的时钟频率前面内容已确定 80Mhz 即 Ref Freq = 80000000;

(3)IMX6ULL 波特率计算公式得 115200 = 80000000 /(16*(UBMR +1)/(UBIR+1));

(4)选取一组满足上式的参数: UBMR、 UBIR 即可;

(5)UART1_UBIR = 71 ; UART1_UBMR = 3124

c
UART1->UBIR = 71;
UART1->UBMR = 3124;

4. 使能 UART1

使能 UART1, 需要配置的是 UART1_UCR1(0x2020080)寄存器。配置 UART1_UCR1[0]: 1 表示使能 UART, 0 表示关闭 UART。

三、实现串口的收发

这里就具体直接看 gitee 仓库吧:02_UART · sumumm/imx6ull-bare-demo。里边有几点修改需要说明一下,主要是对 Makefile 文件的修改:

(1)makefile 添加了数学库:Makefile 文件在链接的时候加入了数学库, 因为在 bsp_uart.c 中有个函数 uart_setbaudrate,在此函数中使用到了除法运算,因此在链接的时候需要将编译器的数学库也链接进来。一般的交叉工具链里都提示有基本的数学运算,它们位于 libgcc.a 中。我们需要把 libgcc.a 也链接进程序里,所以就需要修改 Makefile。

(2)makefile 编译选项:加入了选项“-fno-builtin”,否则编译的时候提示“putc”、“puts”这两个函数与内建函数冲突,错误信息如下所示:

shell
warning: conflicting types for built-in function ‘putc’
warning: conflicting types for built-in function ‘puts’

在编译的时候加入选项“-fno-builtin”表示不使用内建函数,这样我们就可以自己实现 putc 和 puts 这样的函数了。