1。AT指令
很多手机都带有数据线,同时提供软件可以与手机进行交互,控制之手机的行为;市场上也有很多GSM、GPRS模块,用这些模块加上简单的电路,就可以制作成所谓的短信群发器,在加上一个软件,就可以狂发短信了。不管是手机还是这些短信短发模块,安装在电脑上的软件一般都是通过AT指令来控制手机或模块的行为。
通过AT指令能够控制手机的许多行为,包括拨叫号码、按键控制、传真、GPRS等。随便搜索以下,就可以搜索很多各种手机或模块其AT指令的文档,其多数指令都是相同的,各个常见一般会根据自身的情况对指令进行扩展,这里不必细说。
通过串口线连接计算机的串口与手机或者GSM/GPRS模块,打开超级终端,设置好相关参数,然后就可以在电脑使用AT指令了。手机一般通过USB与计算机连接,可以找一个USB转串口的软件。
2。GSM/GPRS模块
市场有很多这种模块,提供不同的功能。比如,有的GPRS模块内置了TCP/IP协议栈,就可以很方便的通过厂家扩展的AT指令直接进行TCP或UDP通信。如果没有提供TCP/IP协议栈,那么就需要编写相关的程序,在软件中实现网络访问功能。
GSM/GPRS模块通常不能直接使用,其通常用于嵌入式系统中,需要扩展外围电路。厂家一般也都提供了详细的扩展电路图,如果加上一个嵌入式CPU,弄一个Linux或Windows CE作为操作系统,那么就俨然一个高端智能手机。
用于发送短信的扩展电路一般比较简单,仅仅添加一个基本的电路,提供一个电源接口和一个用于连接计算机的串口。
3。常用的AT指令
命令 | 作用 |
AT | 测试连接是否正确 |
ATE0/ATE1 | 关闭回显/打开回显 |
AT+CGMI | 得到厂商信息 |
AT+CGMR | 得到手机版本号 |
AT+CGSN | 得到手机序列号(IMEI) |
AT+CIMI | 得到手机IMSI号码 |
AT+CSCS | 获取、设置手机当前字符集。可设置为 GSM 或 UCS2 |
AT+CCLK | 获取设置手机时钟 |
AT+COPS | 网络营运商 |
AT+CSCA | 短信中心号码 |
AT+CPMS | 选择短信储存地点。可选择 ME(SIM卡)和MT(机身) |
AT+CMGL | 列出短信,列出指定状态的短信息的PDU代码 |
AT+CMGR | 读短信,列出指定序号的短信息PDU代码 |
AT+CMGS | 发送短信 |
AT+CMGD | 删除指定的短信 |
AT+CMGF | 短信格式。分为Text模式和PDU模式 |
AT+CNMI | 设置新短消息通知电脑端 |
4。通过串口发送AT的过程
(1)设置串口参数
(2)打开串口
(3)发送AT指令,然后等待模块响应
(4)接收相应,然后处理
(5)通讯完成,关闭串口
5。编程技巧
发送完AT指令后,一般需要等待模块做出响应。串口通讯是一种流式通讯,通讯另一方可能正常相应,也有可能不能正常响应,这是就需要对这种情况进行处理。
(1)可以设置读超时,如果对方不能正常响应,则系统会认为与对方通讯失败
(2)如果对方成功响应,那么还需要对对方相应的信息进行判断,确定串口数据流中的那些是相应自己AT指令的数据。一般地,期望的响应都有一定的特征信息,可以通过判断相应的数据是否包含特征信息来判断。
例如,一般当发送一个AT指令后,通常会有一个OK作为相应的结尾,那么就可以通过相应数据是否包含OK判断针对自己的响应是否结束。
例如,如果GSM/GPRS模块认为指令有问题,或者执行指令出错,会返回ERROR,那么程序就不能一直等待自己期望的特征数据出现,如遇到ERROR,就应该返回报错。
(3)即使对方能够成功响应,有时候对方对指令的处理需要一定的时间,这时候并不能通过一个read函数将所有的相应数据都读回。因此就需要将每次读回的数据缓存起来,然后不断的读取数据,直到期望的特征数据出现为止。
(4)在不断的读取数据时,应该在每次读取之间sleep一小会,以保证下次尽量能够读到数据。
6。VB.NET举例
(1)代码说明
定义串口变量。
Private serialDriver as SerialPort
定义全局变量,用来标志向串口发送数据是否成功。
Private isSendingCommand As Boolean
发送AT指令的函数,第一个参数为AT指令,第二个参数为期望的特征响应。
Public Function SendCmd(ByVal commandString As String, _
ByVal expectedResponse As String) As String
Dim response As String = ""
Dim iCount As Integer
If Not commandString.EndsWith(Chr(26)) Then
If Not (commandString.EndsWith(ControlChars.Cr) Or _
commandString.EndsWith(ControlChars.CrLf)) Then
commandString = commandString + ControlChars.Cr
End If
End If
Send(commandString)
'第一次读响应数据
If serialDriver.BytesToRead > 0 Then
response = serialDriver.ReadExisting()
If response Is Nothing Or response.IndexOf(expectedResponse) < 0 Then
If Not response Is Nothing Then
If response.Trim = "ERROR" Then
Throw New UnknownException("Unknown exception in sending command: " & commandString)
End If
If (response.IndexOf("+CMS ERROR") >= 0) Then
' Error in the command
Dim cols() As String = response.Split(":")
If cols.Length > 1 Then
Dim errorCode As String = cols(1)
Throw New Exception("CMS Error code " + errorCode)
End If
End If
End If
'读第一次没有读完的响应数据,直至读到特征数据或超时
For iCount = 1 To 100
Thread.Sleep(1000)
response = response + serialDriver.ReadExisting()
If response.IndexOf(expectedResponse) >= 0 Then
Exit For
End If
Next
End If
End If
Return response
End Function
向串口发送数据,如果有响应数据或者超时20秒钟,则返回,等待下一步处理
Public Sub Send(ByVal commandString As String)
Try
Dim callText As String
Dim callCommand As Byte()
Dim iCount As Integer
callText = commandString
iCount = 0
callCommand = System.Text.ASCIIEncoding.GetBytes(callText)
isSendingCommand = True
serialDriver.Write(callCommand, 0, callCommand.Length)
While serialDriver.BytesToRead <= 0
Thread.Sleep(1000)
iCount = iCount + 1
If (iCount = 20) Then
isSendingCommand = False
Exit While
End If
End While
isSendingCommand = False
Catch ex As System.Exception
isSendingCommand = False
Throw ex
End Try
End Sub
(2)使用举例
SendCmd("AT+CSCA?", "+CSCA")
发送“AT+CSCA?”指令,读取短信中心号码,其响应数据类似“+CSCA: "+8613800100500",145”,因此设置其期望的特征响应为“+CSCA ”。