linux rs232驱动程序,迅为IMX6ULL开发板Linux RS232/485驱动实验(下)

53.3  硬件原理图

53.3.1 RS232

bfc0722c7ba84a74bb10a827e6975076.png

UART3 通过跳线帽 J46 来设置成 TTL 电平的 RS232 信号。连接 J46 的 3-5 和 4-6 后,UART3 通过 TTL 电平输出。

53.3.2 RS485

96b499d4bbe84a0d921e50ad0619f12a.png

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 所示:

a791fc4323fd2a0997ddf832dfc7b851.png

因为没有用到 uart2,并且 uart2 的引脚节点中用到了 uart3 的 IO,所以需要将 uart2 注释或删掉。然后添加 uart3 节点,内容如下:

1 &uart3 {

2 pinctrl-names = "default";

3 pinctrl-0 = ;

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 所示:

be3ff6b645b902684e3f368f737483e1.png

选择正确的 port 端口,应用程序中默认波特率为 115200,所以设置波特率为 115200,然后连接设备。

拷贝编译好的 uart_test 应用测试程序到开发板中,执行下面命令进行写数据实现:

./uart_test /dev/ttymxc2 0 &

运行结果如图 53.5.2.2 所示:

8a3b7ee1d9b04ef63034c3a6bf1f2b57.png

使用下面的命令进行读数据:

./uart_test /dev/ttymxc2 1 &

运行结果如图 53.5.2.3 所示:

7794dd6e956f833ea5fb1f1acd2bab28.png

应用程序每次接受 8 个字节的数据,可以看出运行正常。

53.6 RS485  测试

其实 RS485 测试和 RS232 测试流程一样,只不过接口不一样,需要使用 USB 转 485 设备。应用测试程序也是一样的。在这里就不重复测试了,用户可以自己试验一下。

0a777c7e8a53e5f65c16a2f746a761d5.png

927f6af69c42222f80919d486256d0db.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值