TQ2440(ARM)和SIM300(GPRS模块)串口通信

最近在做串口通信这快遇到了很大的麻烦。现在写一帖做总结。

先介绍一下我的环境,ARM板是TQ2440的,内核是linux-2.6.30.4,GPRS模块用的是SIM300,完全封装了PPP拨号和TCP/IP协议,是一块GPRS DTU。

遇到的第一个问题就是,ARM板可以和PC机通信,GPRS模块也可以和PC机通信,但是用ARM板和PC机就不能通信,而且可以写入串口,而却完全读不到串口。说明ARM板和GPRS模块是完全不通的。作为硬件菜鸟一枚,使用论坛和各种搜索后发现很多人都出现这种问题,很可能就是因为线的问题,然后硬着头皮把TQ2440(ARM板)和SIM300(GPRS模块)的串口电路原理图看了一下,果然。不截图了,直接写结果。

PC:2脚RXD,3脚TXD (公头)

TQ2440:2脚TXD,3脚RXD (公头)

SIM300:2脚TXD,3脚RXD (母头)

这样就可以解释为什么不能通信的原因了,我用的串口线都是直通的,PC和TQ2440以及PC和SIM300都可以通信,但是当TQ2440和SIM300通信时,TXD对的是TXD,而RXD对的是TXD,当然不通,方法就是使用交叉串口线。这个知识在最后附录里面(附录1)。

遇到的第二个问题就是,TQ2440实际有的通用异步手法装置(UART)是有三个的,也就是可以说有三个串口,但是却只有串口一给用RS232给引出来了,串口2,3都是TTL电平的作为扩展用,而更假的是这个串口一已经在天嵌公司提供的内核和文件系统里面被编译成了调试串口,也就是当做控制台用。那么我要用5线的和我的SIM300通信的话就不能用。这里有三个方法,两个软件的方法,一个硬件的方法。先说那两个软件方法。

法一:修改内核,并重新编译,把串口一不当做调试用,然后如果要调试时可以用两种方法,一个就是用telnet,另一个就是使用jlink。

Character devices —>
Serial drivers —>
S3C2410 serial port support
[ ] Console on S3C2410 serial port

把那个去掉就可以,这显然不适合我,因为我的网口到时候还是有其他用处。

法二:重新写串口的驱动程序,天嵌提供的驱动程序是开源的,我曾经试着尝试UART的进行串口切换驱动,但都是失败告终,目前也没有发现又成功的例子,所以只是理论上的方法。

第三个方法就是硬件方法,简单而粗暴,直接把TQ2440的TTL串口电平转换成RS232的串口接口,作为硬件菜鸟,是肯定不会自己买各种线和MAX232然后去接起来,使用的是天嵌公司自己生产的扩展板子。网址是:http://detail.china.alibaba.com/buyer/offerdetail/987340147.html

这里不得不吐槽一下,你特么的什么破玩意,搞个一个串口,其他的还得去买,而且这个串口又不是标准的RS232串口。最后在附录(附录2)中再贴上我的测试代码。

附录1:

串口线也分直通和交叉,直通一般用于延长PC与设备,将2、3、5分别连接2、3、5,因为PC上一般为公头,而设备上多为母头,所以正好它们是通用的,既可用于延长也可用于连接;交叉一般用于PC与PC对接,将2对3、3对2、5对5,一般两头都是母头!

而CPU 和终端则采用TTL 电平及正逻辑,TTL 电平用+5V 表示逻辑1,0V 表示逻辑0,它们与EIA采用的电平及负逻辑不兼容,需在接口电路中进行转换。EIA-RS-232C 标准没有定义连接器的物理特征.因此出现了DB-25、DB-15 和DB-9 各种类型的连接器,PC 机的COM1和COM2串行接口采用DB-9连接器。ELA-RS-232C 标准规定,当误码率小于4%时,允许导线长度15m 。实际应用中,当使用9600b /s、普通双绞屏蔽线时,传输距离可达30m ~35m 。PC 机的COM1和COM2两个串行接口采用的DB-9连接器是公( 针) 头,提供异步通信的 9 个引脚功能。分别为:①脚 (DCD) 数据载波检测,②脚 (RXD)接收数据,③脚(TXD) 发送数据,④脚 (DTR) 数据终端准备,⑤脚 (SG) 信号地,⑥脚 (DSR) 数据设备准备好,⑦脚(RaS)请求发送,⑧脚 (CTS) 清除发送,⑨脚 (RI) 振铃指示。DB-9 公 ( 针 ) 头排列顺序如下图上,DB-9母座排列顺序如下右下,针 ( 座 ) 朝向自己。在连接器上标有数字。EIA-RS-232C 标准中 , 有三个发送信号:TXD 、RTS 和DTR,每根线的典型输出电流为± 8mA/±12V 。通常由 RTS 和 DTR 供电的话,可提供约192mW 功率。

看一个开发板上的串口是标准串口还是非标准串口,根本还是要看原理图是怎么连的!

附录二:

1</pre>
2#include <stdio.h>
3
4#include <string.h>
5
6#include <sys/types.h>
7
8#include <error.h>
9
10#include <sys/stat.h>
11
12#include <fcntl.h>
13
14#include <termios.h>
15
16#include <stdlib.h>
17
18int fd;
19
20/*
21
22* 打开串口1
23
24*/
25
26int open_serial()
27
28{
29
30//O_RDWR:以读写的方式打开设备
31
32//O_NOCTTY:如果欲打开的文件为终端设备时,则不会将该终端当成当前进程控制终端
33
34//O_NDELAY:以不可阻断的方式打开文件,即无论有无数据读取或等待,都会立即返回进程之中
35
36//fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); //PC机测试
37
38fd = open("/dev/tq2440_serial1", O_RDWR | O_NOCTTY | O_NDELAY); //tq2440 Linux测试
39
40printf("\nfd = %d\n\n", fd);
41
42if(fd < 0) //打开失败
43
44{
45
46return -1;
47
48}
49
50//恢复串口为阻塞状态
51
52if(fcntl(fd, F_SETFL, 0) < 0) //F_SETFL:改变open设置的标志
53
54{
55
56close(fd);
57
58return -2;
59
60}
61
62//测试是否为终端设备
63
64if(0 == isatty(fd)) //isatty:检查设备类型
65
66{
67
68close(fd);
69
70return -3;
71
72}
73
74return fd;
75
76}
77
78/*
79
80* 设置串口,共9步
81
82* 数据位:8
83
84* 校验位:无
85
86* 波特率:115200
87
88* 停止位:1
89
90*/
91
92int set_serial()
93
94{
95
96struct termios newtio, oldtio;
97
98//1、保存原有串口配置
99
100if(tcgetattr(fd, &oldtio) != 0)
101
102{
103
104return -1;
105
106}
107
108//2、激活本地连接和接受使能
109
110newtio=oldtio;
111
112newtio.c_cflag |= CLOCAL | CREAD;
113
114//3、设置字符大小
115
116newtio.c_cflag &= ~CSIZE; //除去数据位中的位掩码
117
118newtio.c_cflag |= CS8; //设置数据位
119
120//4、设置奇偶校验位:无奇偶校验位
121
122newtio.c_cflag &= ~PARENB; //激活校验位使能标志
123
124//5、设置波特率
125
126cfsetispeed(&newtio, B115200);
127
128cfsetospeed(&newtio, B115200);
129
130//6、设置停止位:1
131
132newtio.c_cflag &= ~CSTOPB;
133
134//7、设置等待时间和最小接收字符
135
136newtio.c_cc[VTIME] = 0;
137
138newtio.c_cc[VMIN] = 0;
139
140//8、处理要写入的引用对象
141
142tcflush(fd, TCIFLUSH); //处理未接收字符串,TCIFLUSH:刷新收到的数据但不读
143
144//9、激活新配置
145
146if(tcsetattr(fd, TCSANOW, &newtio) != 0) //TCSANOW:改变的配置立即生效
147
148{
149
150return -2;
151
152}
153
154return 0;
155
156}
157
158int main()
159
160{
161
162char cmd[] = "ATD 18970952060;\r";
163
164open_serial();
165
166set_serial();
167
168printf("write: %d\n", write(fd, cmd, sizeof(cmd)));
169
170sleep(2);
171
172printf("read: %d\n", read(fd, cmd, sizeof(cmd)));
173
174return 0;
175
176}
177
178返回是:
179
180fd=3
181
182write:18
183
184read:18
Logo

更多推荐