转自:http://mywutuobang.blog.sohu.com/260073467.html
一. 修改内核支持3G模块,一般内核需要枚举相关的通讯模块,其接口为串口,其数据接口和通讯接口枚举成不同的设备,如果出现问题,详见以下步骤:
3G 出现问题,通常应先检查系统是否识别到了 modem 设备,可用如下命令确认:
ls /dev/ttyU*
或者
ls /dev/ttyA*
如果在/dev 下没有找到 ttyU* 或者 ttyA* 设备,此时可通过观察内核 LOG 来定位问题:
1. USB 设备枚举失败或者系统根本就没有发现 USB 设备,此时应检查硬件电路
2. USB 枚举成功,但没有注册到 ttyUSB 或者 ttyACM 设备,此时应检查你的内核:
a). 你的内核没有开启 usb serial 功能
b). 你的内核代码中的 usb serial 相应驱动中没有添加该设备的 VID/PID,请修改
kernel/drivers/usb/serial/option.c,在数组 static struct usb_device_id option_ids[] 的末
尾添加上新设备的 VID/PID
3. USB 枚举成功,且相关配置且 ID 都已添加,但还是不出来 ttyUSB 或者 ttyACM 设备,此时
可观察系统是否有对它执行 usb mode switch,可通过 logcat:
# logcat –s Vold vold &
观察是否有调用了 usb_modeswitch 程序,如果没有执行,则检查如下:
a). 检查一些必要的文件是否存在:
ls /system/bin/usb_modeswitch
ls /etc/usb_modeswitch.sh
ls /etc/usb_modeswitch.d/[VID_PID] #[VID_PID]应替换成你的 modem 的
VID/PID,如: 12d1_1001
如果是缺少了 usb_modeswitch、usb_modeswitch.sh 等文件,则可能是你的 福州瑞芯微电子有限公司 福州瑞芯微电子有限公司 福州瑞芯微电子有限公司 福州瑞芯微电子有限公司
gingerbread/device/rockchip/sdkDemo/BoardConfig.mk 中的配置存在问题,请确认
BOARD_RADIO_DATAONLY := true
如果是缺少了/etc/usb_modeswitch.d/[VID_PID],请告知我!
b). VOLD 中关于 usb_modeswitch 这部分的代码没有被编译,你可查看 Vold 的 log 中是
否有“Start Misc devices Manager…”的字样,如果没有这串字符,请检查你的
gingerbread/system/vold/下的内容。
通常,3G 问题中,不出来 ttyUSB 或者 ttyACM 设备,主要就是上述的那些情况 。
二.如果是开发短信功能,需要获取3G模块供应商的AT指令集,大部分的3G模块的指令集一致。
1、先执行AT命令,若返回OK,则说明三级模块与单片机的串口连接好了;
2、接着执行AT+CFUN=1, 启动初始化SIM模块命令,该命令不管有没有插卡都会返回OK;
3、接下来执行AT+CREG=1,初始化网络,允许网络注册主动提供结果代码(将<mode>设为了1);理论上可以通过查询AT+CREG?命令来判断是否注册成功,根据返回的指令判断是否注册到网络,返回命令的格式为::+CREG:<mode>,<stat> [,<lac>,<ci>],若<stat>为1(注:由于注册网络需要一段时间,所以初始返回值可能为2,即处于未注册,终端正在搜寻基站,因此需要延时一段时间,供硬件反应),则表示注册到本地网络。具体原因参见命令解释,但是由于不插上SIM卡也可以有返回指令,所以检测不便,另外硬件需要一段反应时间,从而使得测出来的结果不准确,为此应该使用以下命令。
4、接下来执行AT+COPS?如果返回0,则表示插入了SIM卡,但是此时SIM卡不一定注册成功,需要延时一段时间,然后再判断AT+COPS?返回结果,若返回+COPS: 0,0,"中国联通",0,则还需要判断AT+CREG?判断格式是否为+CREG:1.1(主要看第二个参数);若返回+CMEERROR:10,则SIM卡注册失败,有可能SIM卡未插入插槽中,此时应该检测是否将SIM卡插好,确信卡是插好的。因为硬件连接传输有可能延迟,应该多试几次。
通过以上分析,为了简化判断程序,可以只判断AT+COPS?是否能够返回0,这样就表示硬件连接上有没有问题了。
在以上步骤成功后,先执行AT+CMGF=1,设定发送短消息的格式,1代表TEXT,0代表PDU格式。返回OK,则执行成功。接着输入AT+CMGS=”13988888888”回车(对应的16进制为0x0D),后面的号码表示发送短消息的目的地号码。若成功,则会返回一个>符号,提示输入信息,接着输入想要发送的信息即可,最后在发送的末尾加上CTRL+Z(对应的16进制为0X1A),则短消息发送成功。
经常涉及的指令:
1、AT+CFUN=1(全功能命令,立即执行)
此命令可以开启simcom模块的大部分功能,一般在初始化模块的时候都要写上;AT+CFUN=0的功能与+CPOF相同。(AT+CPOF,关机)
2、AT+CREG 网络注册和漫游
AT+CREG=<mode>,命令响应(Response):+CREG:<mode>,<stat> [,<lac>,<ci>]
参数说明:
<mode>
0: 禁止网络注册主动提供结果代码(默认设置)
1: 允许网络注册主动提供结果代码:+CREG:<stat>
2: 启用网络注册和位置信息非请求结果码+CREG:<stat>[,<lac>,<ci>]
<stat>
0:未注册,终端当前并未在搜寻新的运营商
1:已注册本地网络
2:未注册,终端正在搜寻基站
4:未知代码
5:已注册,处于漫游状态
<lac> 位置区编号
<ci>小区ID
注意:当设置AT+CREG成功时调制解调器回复OK.之后将网络注册状态通过响应返回。当网络注册状态发生改变时,调制解调器将状态通过响应反映上来。
LAC及CI也可以从+CCED命令查询出来。
3、AT+COPS(运营商选择)
AT+COPS=? 返回网络上支持的运营商描述列表,可能的返回结果如下:
+COPS: (2,"中国联通","CUCC","46001",0),(3,"中国移动","CMCC","46000"),,(0-4),(0-2)
读指令:AT+COPS? 返回当前选择的模式和网络运营商,格式为:+COPS:<mode>[,<format>[,<oper>]]OK
可能的返回结果:+COPS: 0,0,"中国联通",0
写指令:AT+COPS=<mode>[,<format>[,<oper>]] 强制选择和注册GSM网络运营商,返回:OK
参数:
<stat> 0 不知道
1 可用的运营商
2 当前运营商
3 禁用的运营商
<oper> 运营商
<mode> 0 自动模式 <oper>被忽略
1 手动选择
2 从网络中手动注销
3 选择尽有有格式
4 手动或自动选择,如果手动失败,则自动使能
<format> 0 支持长字节格式,能升到16字节长
1 短字节格式
2 数字格式,
AT+CREG与AT+COPS结合使用事例:
AT+CREG=1//允许网络注册主动提供结果代码
AT+COPS=0//设置为自动模式
AT+COPS?//查询当前模式和网络运营商
4、AT+CSQ(读取信号强度)
返回+CSQ: 20.0之格式的信息,信号强度
5、AT+CMGF(设置短消息格式)
AT+CMGF=0 选择PDU格式,=1选择TEXT格式
6、AT+CMGS(发送短信)
若想发往13508485560,短消息内容为:“test“,则格式如下:
AT+CMGS="13508485560"(目的地址)回车 >test^z ;发送完号码后回车,符号”>”为系统返回,不是需要输入的符号。输入完短信内容后,按Ctrl+Z结束。
另一方面也可以发送命令AT+CMGS=6,即设置发送的短信的长度为6个。
7、AT+CSCA 设置短消息中心
AT+CSCA=“+8613800270500”回车(具体的号码由当地的运营商决定。其中+861380不变,后四位是地区区号。这里显示0270表示地区为武汉,后三位基本不变为500)。
AT+CSCA?可以得到短信中心号码。
8、AT+CSQ?(查询信号强度)
三. 发送短信
开发环境是ARM11&linux。例子是飞凌的6410开发板,3G模块选中兴的AD3812,
短信的发送一般分为三种模式:Block Mode, Text Mode和PDUMode,其中blockmode已经很少使用。下面介绍的内容,是在PDUMode下发送和接收短消息的实现方法。text模式发送短信的时候比较简单,pdu模式相比而言的话要麻烦一下。具体使用那种模式,还要看你的需求,如果所要发送的短信内容全部是英文或者数字的话可以使用text模,如果你发送的短信中含有中文字符或者汉子的话就只能用pdu模式进行发送了。
我做的短信开发,发送的信息包含中文,而且接收的短信命令中也有中文,所以使用的是pdu模式。使用pdu模式发送短信的步骤如下:
(1)串口初始化。
(2)构建SMS的pdu串。
(3)设置短信发送模块的模式。
(4)使用AT指令发送pdu串到指定的手机号码。
下面对以上步骤进行详细的解释:
(1)串口初始化,串口的初始化要按照短信发送模块的默认来设置,我所使用的AD3812的说明书上明确指出 :115200,8,N,1,即传输速率是115200,数据位是8位,无奇偶校验位,一位停止位。
(2)构建SMS的pdu串。这一步是整个过程最主要的一步,关系到发送能否成功。首先要知道短信pdu串的组成,sms pdu串主要由9个部分组成,按照顺序分别为 SCA(servicecenter adress)服务中心的电话号码;pdu—type(protocoldata unit type):协议数据但与类型;MR(messagereference) 所有成功的sms—submit参考数目;OA (originatoradress)发送方sme(short-message-entity)的地址;DA(destination)接收方SME的地址;PID(ProtocolIdentifier)参数显示SMSC以何种方式处理SM;DCS(datacoding scheme)参数表示用户数据采用什么编码方案;SCTS(servicecenter time stamp)smsc接收到消息是的时间戳;UDL,用户数据长度;UD,用户要发送信息的内容。
(3)之前已经说过了,使用pdu模式,所以这一步其实就是告诉设备,我们使用的是pdu模式,对用的at指令是:AT+CMGF=0\r.注意:\r表示的是回车,指令后面必须跟有\r设备才能识别。
(4)第1-3搞定之后,剩下的就是告诉设备发送该短信了,具体的命令是AT+CMGS=%d\r,%d是一个正整数,该数的值与你发送短信的内容有关系,%d=15+2*发送的字符数。
现在根据我做的具体来说明过程,希望对你有帮助:
上面已经把我的软硬件环境说明了,下面重点说明短信的发送过程,我需要发送的短信内容是:江大科茂欢迎您!目的电话号码是18796082112,我使用是移动的sim卡。最后构建的sms pdu为:0891683108501105F011000D91688197062811F2000800166C5F592779D183026B228FCE60A8FF01
如上所示,其实整个sms pdu构建过程中,需要自己做的只有四处,分别是发送方的短信中心号码,目的手机号码,短信内容长度,短信内容的unicode码。其中紫色的为所在地的短信中心号码,因为我用的是镇江移动的号吗作为发送手机号,所以从网上就可以查到,对应的短信中心号是13800511500,需要按照前后位交换,最后一位补F进行重新排列。3108501105F0。红色的为目的手机号码,也需要进行重新排列。绿色的是短信的内容的长度具体计算方法为:短信内容的字符数*2,并要注意要以4位16进制表示。蓝色的为短信内容“江大科茂欢迎您!”的unicode吗,网上可以查到,这样就sms pdu就构建完成了。还需要特别提醒一下的是,在pdu构建完成,向设备写pdu串的时候不要忘记最后要添加ctrl+z,因为这是设备识别pdu串结束的标志。ctrl+z的assic码是0x1a。其中还要重点提一下就是 AT+CMGS=?的计算方法 15+短信字符数*2。具体的实现代码如下。
charsmstype[]="AT+CMGF=0\r";
charsmscmgs[]="AT+CMGS=31\r";
charpdu[]="0891683108501105F011000D91688197062811F2000800316C5F592779D183026B228FCE60A8FF01
\0x1a";
write(fd_usb,smstype,sizeof(smstype));
usleep(20000);
write(fd_usb,smscmgs,sizeof (smscmgs));
usleep(20000);
write(fd_usb,pdu_warn,sizeof(pdu_warn));
usleep(20000);
四. 开发其他功能,详细参见AT指令集