当前位置: 首页 > article >正文

开发板适配之UART

UART(Universal Asynchronous Receiver/Transmitter),通用异步收发器,是一个全双工的支持串行通信协议的接口。i.MX6ULL支持8路UART接口,在i.MX6ULL参考手册中Chapter53章节可以看到这8路UART接口以及其对应的引脚:

在上表中可以看到每一路UART接口都有对应的4个引脚:CTS、RTS、RX_DATA、TX_DATA,其中CTS和RTS主要用于数据流控,RX_DATA和TX_DATA是数据接收和发送引脚。数据流控就是对数据进行流量控制,数据在两个串口传输过程中,常常会出现丢失数据的情况,比如两个模块通过串口进行通信,模块A向模块B发送数据,如果模块B的数据缓冲区数据已满,此时模块A继续发送数据,则会出现数据丢失的情况。尤其当两个模块所属平台有较大差异,对数据处理速度不同时,这种现象较明显。流控就可解决此问题,当数据接收缓存已满,则接收端发送停止接收信号,发送端停止发送,直到可以接收数据时,则发送继续发送信号,数据继续传输,从而避免数据丢失。至于发送和接收模块的CTS和RTS信号的工作原理,我们这里不再深究。在传输数据量不大的情况下,一般不使用流控功能。ELF 1开发板上的串口都没有使用到流控引脚,所以在接下来的UART配置过程中,都不对流控引脚进行配置。

ELF 1开发板一共引出4路UART接口,分别是UART1、UART2、UART3、UART7,其中UART1用于调试,UART2、UART3用于连接RS485收发芯片,UART7连接TTL转RS232芯片。下面我们对这几个接口逐一进行配置。

硬件原理

UART1

从原理图中可以得到我们使用的UART1_RXD和UART1_TXD引脚对应的连接器引脚编号分别为27和28。

通过查表可以得到27和28的PAD NAME分别为UART1_RX_DATA和UART1_TX_DATA。

UART2

从原理图中可以得到我们使用的UART2_RXD和UART2_TXD引脚对应的连接器引脚编号分别为72和73。

通过查表可以得到72和73的PAD NAME分别为UART2_RX_DATA和UART2_TX_DATA。      

UART3

从原理图中可以得到我们使用的UART3_RXD和UART3_TXD引脚对应的连接器引脚编号分别为77和78.

通过查表可以得到77和78的PAD NAME分别为UART3_RX_DATA和UART3_TX_DATA。

UART7

从原理图中可以得到我们使用的UART7_RXD和UART7_TXD引脚对应的连接器引脚编号分别为114和115。

通过查表可以得到114和115的PAD NAME分别为LCD_DATA17和LCD_DATA16。

IOMUX配置

确定好引脚之后,我们就可以在设备树中添加相关引脚的IOMUX配置。

UART1,UART2

打开NXP BSP的arch/arm/boot/dts/imx6ull-elf1-emmc.dts文件,可以看到关于UART1和UART2的IOMUX配置信息,这是因为,i.MX6ULL EVK板也引出了UART1(UART1一般都是作为调试串口使用)和UART2。既然已经有了UART1和UART2的IOMUX配置,那我们就只需对比一下其配置的相应引脚跟ELF 1开发板使用的引脚是否一致即可。上一节中已经确定了我们使用的UART1和UART2对应的引脚PAD NAME,UART1:UART1_RX_DATA和UART1_TX_DATA,UART2:UART2_RX_DATA和UART2_TX_DATA,对比arch/arm/boot/dts/imx6ull-elf1-emmc.dts文件中已配置好的IOMUX信息,可以看到是一致的:

由上图可知,UART2的IOMUX节点uart2grp下配置了流控引脚RTS和CTS,我们板子没有引出流控引脚,所以,这里注释掉流控配置:

UART3

由上一节确定了我们使用的UART3收发引脚PAD NAME分别为UART3_RX_DATA和UART3_TX_DATA。在arch/arm/boot/dts/imx6ul-pinfunc.h文件中分别搜索UART3_RX_DATA和UART3_TX_DATA,找到其复用成UART功能的宏:

MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX

MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX

然后在arch/arm/boot/dts/imx6ull-elf1-emmc.dts文件建立UART3的IOMUX配置节点,并添加上这两条宏配置,其PAD寄存器的值参考了UART1和UART2:

pinctrl_uart3: uart3grp {

    fsl,pins = <                                

            MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX  0x1b0b1

            MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX  0x1b0b1

    >;

};

添加后效果如下:

UART7

同理,UART7的PAD NAME分别为LCD_DATA17和LCD_DATA16,在arch/arm/boot/dts/imx6ul-pinfunc.h文件中分别搜索LCD_DATA17和LCD_DATA16,找到其复用成UART功能的宏:

MX6UL_PAD_LCD_DATA17__UART7_DCE_RX

MX6UL_PAD_LCD_DATA16__UART7_DCE_TX

在arch/arm/boot/dts/imx6ull-elf1-emmc.dts文件建立UART7的IOMUX配置节点,并添加上这两条宏配置:

pinctrl_uart7: uart7grp {

               fsl,pins = <

                        MX6UL_PAD_LCD_DATA17__UART7_DCE_RX 0x1b0b1

                        MX6UL_PAD_LCD_DATA16__UART7_DCE_TX 0x1b0b1

                        >;

                };

添加后效果如下:

注意:LCD_DATA17和LCD_DATA16这两个引脚默认复用为了LCD的data17和data16功能,所以,需要注释掉这两个引脚的LCD复用,在pincrtl_lcdif_dat节点中:

添加设备节点

UART1-UART8的设备节点在arch/arm/boot/dts/imx6ull.dtsi设备树文件中已经存在,我们只需在arch/arm/boot/dts/imx6ull-elf1-emmc.dts将需要的UART使能即可,如已经使能的UART1:

&uart1 {

       pinctrl-names = “default”;

       pinctrl-0 = <&pinctrl_uart1>;

       status = “okay”;

}

使能UART功能主要是设置pinctrl-0属性和status属性,pinctrl-names属性设置pingctrl的name,不是必需的,pinctrl-0属性主要用于配置UART接口相关引脚的IOMUX,status属性主要是使能该串口功能。

UART2也已经配置好,我们只需将其中的流控功能去掉就可以了:

&uart2 {

       pinctrl-names = “default”;

       pinctrl-0 = <&pinctrl_uart2>;

/*      fsl,uart-has-rtscts;

*/

       /* for DTE mode,add below change */

       /* fsl,dte-mode; */

       /* pinctrl-0 = <&pinctrl_uart2dte>; */

       status = “okay”;

}

依照上述方法,依次添加UART3和UART7节点相关属性:

&uart3 {

        pinctrl-names = "default";

        pinctrl-0 = <&pinctrl_uart3>;

        status = "okay";

};



&uart7 {

        pinctrl-names = "default";

        pinctrl-0 = <&pinctrl_uart7>;

        status = "okay";

};

添加后效果如下:

编译测试

单独编译设备树:

. /opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi

elf@ubuntu:~/work/linux-imx-imx_4.1.15_2.0.0_ga$ make dtbs

使用scp将设备树拷贝到开发板:

elf@ubuntu:~/work/linux-imx-imx_4.1.15_2.0.0_ga$ scp arch/arm/boot/dts/imx6ull-elf\1-emmc.dtb root@172.16.0.175:/run/media/mmcblk1p1/

进行sync操作后重启开发板:

启动之后,可以看到在/dev目录下生成节点ttymxc0、ttymxc1、ttymxc2、ttymxc6,分别对应我们添加的UART1,UART2,UART3,UART7。

我们对UART2\UART3\UART7进行测试(UART1是调试串口,这里不测试),UART2和UART3分别对应板子上的RS485_1和RS485_2,我们将RS485_1和RS485_2进行收发互测,将两路RS485的A1-A2和B1-B2进行相连。UART7对应RS232,我们收发短接测试,将TX-RX收发互连。

串口

设备节点

接口

板子丝印

UART1

ttymxc0

调试串口, 连接到CH340E

DEBUG

UART2

ttymxc1

RS485_1

A1、B1

UART3

ttymxc2

RS485_2

A2、B2

UART7

ttymxc6

RS232

TX、RX

我们使用已经写好的测试程序进行简单测试,可以直接使用开发板文件系统/usr/bin/下的elf1_cmd_serialport进行测试。

测试RS485_1(UART2)和RS485_2(UART3)输入以下命令,注意空格:

root@ELF1:~# elf1_cmd_serialport ttymxc1 &

root@ELF1:~# elf1_cmd_serialport ttymxc2 -o -b 9600 -t aabbccddeeff 1

上图显示信息中/dev/ttymxc2 nwrite表示通过RS485_2(UART3)发送的具体数据,/dev/ttymxc1 nread表示通过RS485_1(UART2)接收到的数据。

测试RS232(UART7)使用命令:

root@ELF1:~# elf1_cmd_serialport ttymxc6 -o -b 9600 -t aabbccddeeff 1

 


http://www.kler.cn/a/536316.html

相关文章:

  • uniapp mqttjs 小程序开发
  • C++ 课程学习笔记:从对象生命周期看资源管理之道
  • oracle ORA-27054报错处理
  • VSCode中使用EmmyLua插件对Unity的tolua断点调试
  • js-对象-JSON
  • 【基于SprintBoot+Mybatis+Mysql】电脑商城项目之修改密码和个人资料
  • mybatisPlus介绍
  • Java 21 虚拟线程详解
  • 【C#】一维、二维、三维数组的使用
  • 测试中的第一性原理:回归本质的质量思维革命
  • 数据结构之顺序表和链表
  • s1:简单测试-时间规模化
  • Kotlin 使用虚拟线程并在低版本中自动切换到协程
  • zabbix v7.2.3容器运行Proxy代理服务器启用IPV6访问
  • 代码随想录算法【Day38】
  • SQL Server查询计划操作符(7.3)——查询计划相关操作符(6)
  • 第4节课:控制结构 - 条件语句、循环语句
  • 本地私有化部署 DeepSeek Dify ,告别“服务器繁忙,请稍后再试”
  • 小米官博宣布:首款AI眼镜即将发布
  • Java实现网络安全编程数字信封 网络安全 java
  • 深入解析:如何利用 Python 爬虫获取商品 SKU 详细信息
  • 深入理解 YUV Planar 和色度二次采样 —— 视频处理的核心技术
  • 第30节课:前端架构与设计模式—构建高效可维护的Web应用
  • 《金字塔原理》笔记
  • 【JS】element-ui 中 table的select事件
  • source 与 shell 之详解(Detailed Explanation of Source and Shell)