"); //-->
53.3 硬件原理图
53.3.1 RS232
UART3 通过跳线帽 J46 来设置成 TTL 电平的 RS232 信号。连接 J46 的 3-5 和 4-6 后,UART3 通过 TTL 电平输出。
53.3.2 RS485
RS485 通过 SP3485 芯片将串口信号转换为 RS485 信号,RE 是接收使能信号(低电平有效),OE 是发送使能信号(高电平有效)。在图中 RE 和 OE 经过一系列的电路,最终通过 RS485_1_TX 来控制,这样我们可以省掉一个 RS485 收发控制 IO,将 RS485 完全当作一个串口来使用,方便我们写驱动。
53.4 RS232 驱动
I.MX6U 的 UART 驱动 NXP 已经编写好了,所以不需要我们编写。我们需要做的就是在设备树中添加 UART3 对应的设备节点即可。
53.4.1 设备树添加 UART3 节点
打开 topeet_emmc_4_3.dts 文件,首先添加 UART3 对应的 pinctrl 子节点,在 iomuxc 中添加如下内容:
1 pinctrl_uart3: uart3grp {
2 fsl,pins = <
3 MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX 0X1b0b1
4 MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX 0X1b0b1
5 >;
6 };
然后检查一下 UART3_TX 和 UART3_RX 这两个引脚有没有被用作其他功能,如果有的话要将其屏蔽掉,保证这两个 IO 只用作 UART3。
添 加 完 pinctrl 子 节 点 后 , 添 加 uart3 节 点 , 仍 然 是 在 topeet_emmc_4_3.dts 文 件 中 , 在topeet_emmc_4_3.dts 文件中已经默认存在了 uart1 和 uart2 两个节点了,如图 53.4.1.1 所示:
因为没有用到 uart2,并且 uart2 的引脚节点中用到了 uart3 的 IO,所以需要将 uart2 注释或删掉。然后添加 uart3 节点,内容如下:
1 &uart3 {
2 pinctrl-names = "default";
3 pinctrl-0 = <&pinctrl_uart3>;
4 status = "okay";
5 };
添加完成后,重新编译设备树文件,然后使用新的设备树文件启动 Linux 系统。系统启动以后就会生成一个名为“/dev/ttymxc2”的设备文件,ttymxc2 就是 UART3 对应的设备文件,应用程序可以通过访问ttymxc2 来实现对 UART3 的操作。
53.5 RS232 驱动测试
53.5.1 编写应用测试程序
本实验例程路径:i.MX6UL 终结者光盘资料/06_Linux 驱动例程/19_uart
创建 uart_test.c 应用测试程序,具体内容如下:
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10
11 int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
12 {
13 struct termios newtio,oldtio;
14 if ( tcgetattr( fd,&oldtio) != 0) {
15 perror("SetupSerial 1");
16 return -1;
17 }
18 bzero( &newtio, sizeof( newtio ) );
19 newtio.c_cflag |= CLOCAL | CREAD;
20 newtio.c_cflag &= ~CSIZE;
21
22 switch( nBits )
23 {
24 case 7:
25 newtio.c_cflag |= CS7;
26 break;
27 case 8:
28 newtio.c_cflag |= CS8;
29 break;
30 }
31
32 switch( nEvent )
33 {
34 case 'O':
35 newtio.c_cflag |= PARENB;
36 newtio.c_cflag |= PARODD;
37 newtio.c_iflag |= (INPCK | ISTRIP);
38 break;
39 case 'E':
40 newtio.c_iflag |= (INPCK | ISTRIP);
41 newtio.c_cflag |= PARENB;
42 newtio.c_cflag &= ~PARODD;
43 break;
44 case 'N':
45 newtio.c_cflag &= ~PARENB;
46 break;
47 }
48
49 switch( nSpeed )
50 {
51 case 2400:
52 cfsetispeed(&newtio, B2400);
53 cfsetospeed(&newtio, B2400);
54 break;
55 case 4800:
56 cfsetispeed(&newtio, B4800);
57 cfsetospeed(&newtio, B4800);
58 break;
59 case 9600:
60 cfsetispeed(&newtio, B9600);
61 cfsetospeed(&newtio, B9600);
62 break;
63 case 115200:
64 cfsetispeed(&newtio, B115200);
65 cfsetospeed(&newtio, B115200);
66 break;
67 case 460800:
68 cfsetispeed(&newtio, B460800);
69 cfsetospeed(&newtio, B460800);
70 break;
71 default:
72 cfsetispeed(&newtio, B9600);
73 cfsetospeed(&newtio, B9600);
74 break;
75 }
76 if( nStop == 1 )
77 newtio.c_cflag &= ~CSTOPB;
78 else if ( nStop == 2 )
79 newtio.c_cflag |= CSTOPB;
80 newtio.c_cc[VTIME] = 0;
81 newtio.c_cc[VMIN] = 0;
82 tcflush(fd,TCIFLUSH);
83 if((tcsetattr(fd,TCSANOW,&newtio))!=0)
84 {
85 perror("com set error");
86 return -1;
87 }
88
89 // printf("set done!\n\r");
90 return 0;
91 }
92 int main(int argc , char **argv)
93 {
94 int fd,wr_static,ret,nread,count=0;
95 char *buffer = "hello world!\r\n";
96 char buff[8];
97 int i;
98
99 if(argc < 3)
100 printf("Usage ...");
101
102 printf("\r\n uart__test start\r\n");
103
104 char *uart = argv[1];
105
106 if((fd = open(uart, O_RDWR|O_NOCTTY|O_NDELAY))<0){
107 printf("open %s is failed",uart);
108 }
109 else {
110 printf("open %s is success\n",uart);
111 set_opt(fd, 115200, 8, 'N', 1);
112 }
113
114 if(atoi(argv[2]) == 0)
115 {
116 while(1){
117 if (ret == 0)
118 printf("write time out\n");
119 else{
120 ret = write(fd,buffer, strlen(buffer));
121 sleep(1);
122 }
123 }
124 }
125
126 else if(atoi(argv[2]) == 1)
127 {
128 memset(buff,0,8);
129 while(1){
130 while((nread = read(fd,buff,8))>0){
131 //count+=nread;
132 //printf("count = %d\r\n",count);
133 printf("read: ");
134 for(i = 0; buff != 0; i++)
135 printf("%c",buff);
136 printf("\r\n");
137 memset(buff,0,8);
138 }
139 }
140 }
141
142 close(fd);
143 return 0;
144 }
第 11~91 行,用于设置串口的波特率。
第 92 行,main 函数需要两个参数,第一个参数是串口的设备节点文件,比如/dev/ttymxc2,第二个参数选择读写数据,0:写数据,1:读数据。
第 111 行,当打开串口设备文件成功时,设置串口参数为:115200/8/N/1。用户可以根据实际情况修改。
第 114~124 行,当指令为写数据时执行。使用 sleep 函数延时,1s 发一次数据。
第 126~140 行,当指令为读数据时执行。
53.5.2 运行测试
首先使用下面的命令编译应用测试程序:
arm-linux-gnueabihf-gcc -o uart_test uart_test.c
编译成功,得到 uart_test 应用程序。
然后开始测试 RS232 功能,因为 RS232 是 TTL 电平所以需要 USB 转 TTL 电平设备,然后连接开发板上的 uart3 引脚,在电脑打开 USB 转 TTL 电平设备的终端,如图 53.5.2.1 所示:
选择正确的 port 端口,应用程序中默认波特率为 115200,所以设置波特率为 115200,然后连接设备。
拷贝编译好的 uart_test 应用测试程序到开发板中,执行下面命令进行写数据实现:
./uart_test /dev/ttymxc2 0 &
运行结果如图 53.5.2.2 所示:
使用下面的命令进行读数据:
./uart_test /dev/ttymxc2 1 &
运行结果如图 53.5.2.3 所示:
应用程序每次接受 8 个字节的数据,可以看出运行正常。
53.6 RS485 测试
其实 RS485 测试和 RS232 测试流程一样,只不过接口不一样,需要使用 USB 转 485 设备。应用测试程序也是一样的。在这里就不重复测试了,用户可以自己试验一下。

专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
传统模式和微服务模式下的集成测试和系统测试区别
三菱FX系列PLC教程 13 —— FX系列的(NOP、END)指令
ads1.2中如何控制程序代码的存放地址
555双缸洗衣机定时和洗涤方式选择器电路图
尼得科3家集团公司联合参展2025年上海国际半导体展览会
三菱FX系列PLC教程 15 —— FX系列的触点串联指令(AND、ANI)
CTM8250系列产品数据手册v1.1
makefile文件问题,谢谢
英飞凌推出新一代高功率密度功率模块
555影片放映自动保护停机电路图
三菱FX系列PLC教程 14 —— FX系列的并联电路块的串联连接指令(ANB)
555大型滚筒式洗衣机电控器电路图
LED动态显示序列发生器电路图
555对音频信号进行阵列显示的电路图
三菱FX系列PLC教程 16 —— FX系列的串联电路块的并联连接指令(ORB)
大联大诠鼎集团推出基于英诺赛科产品的2KW 48V双向AC/DC储能电源方案
自动驾驶中基于地图的视觉定位方法
尼得科全球电器恩布拉科品牌的最小型压缩机将亮相AWE展会
MPC850/860的汇编指令?
「Agent代理人」将是AI竞赛新的破局者?
s3c4510的定时器应该怎么设定?
三菱FX系列PLC教程 12 —— FX系列的基本指令(LD、LDI、OUT)
CTM8251系列产品数据手册v1.1
电感的分类及作用
村田中国将携创新升级技术亮相AWE 2025
Solidigm高密度方案解决数据中心存储难题
CTM系列隔离CAN收发器模块选型指南
CTM8250隔离CAN收发器的应用实例图
CTM8251隔离CAN收发器的应用实例图
[求助]我该选哪个型号的处理器合适?