當(dāng)前位置:首頁>>硬件技巧>>手機(jī)>>新聞內(nèi)容
“通過串口收發(fā)短消息”Q&A
作者:pgz_007 發(fā)布時間:2004-3-22 8:42:44 文章來源:西部E網(wǎng)

  就"通過串口收發(fā)短消息"的問題,本人將同網(wǎng)友交流、探討的部分技術(shù)問題整理成如下文字。希望這篇文章能對更多對SMS感興趣的朋友有所幫助。由于本人是業(yè)余愛好,時間和金錢都有限,沒有力量將很多型號的手機(jī)和模塊一一試驗(yàn),可能存在這樣那樣的差錯,希望行內(nèi)高人批評指正。

  Q 我寫了個短信發(fā)送程序,使用PDU格式發(fā)送,程序在廣州使用一點(diǎn)問題也沒有,在河南卻怎么也發(fā)不出去。不知道為什么,短信"你好嗎"格式如下:

河南: 0891683108200005F011000D91683170031618F20008A9064F60597D5417

廣州: 0891683108301705F011000D91683170031618F20008A9064F60597D5417

  A 發(fā)送短信時要用SIM卡屬地的SMSC號碼。如果是在廣州辦的卡,即使在外地還是要用廣州的SMSC號碼。你的兩個短信內(nèi)SMSC號碼不同,但用的是同一張SIM卡,不知是否是此原因。

  Q 短信中心的號碼可否直接使用SIM卡中的號碼,而不要用戶輸入?我用過的短信軟件好像都是不用輸SMSC號碼的。

  A 有一條"AT+CSCA"指令,可用于設(shè)置或查詢服務(wù)中心號碼。若手機(jī)中已存在此號碼,有兩種解決辦法:
 
  用"AT+CSCA?"指令查詢出來,然后自動將此號碼寫到PDU的SCA中。

  PDU的SCA字段只寫一個"00": "08 91 68 31 ..." -> "00"

  可用"AT+CSCA=xxxxxxxx"指令設(shè)置服務(wù)中心號碼。

  Q 我在超級終端上,用at+cmgs發(fā)送短消息,格式好像沒有錯誤,但總返回"ERROR"。我輸入的就象這樣:

at+cmgs=30
> 0891683108100005F011000D91683118405057F000000006C8329BFD0E01

  請問是什么原因?

  A "at+cmgs"指令很特殊,回車后還需要輸入數(shù)據(jù)。此處是"CR",不是"CRLF",注意在超級終端里直接回車是不是生成了兩個字符(查看設(shè)置)。象"at+cmgl"指令,即使最后輸入"CRLF"也是不要緊的。

  你的問題出在長度上。長度不是隨便寫的,你的例子中,長度應(yīng)為21。除去SMSC段(0891683108100005F0),從"11"開始算(即"11000D91683118405057F000000006C8329BFD0E01"),除以2即得。

  正確的寫法應(yīng)該是

at+cmgs=21
> 0891683108100005F011000D91683118405057F000000006C8329BFD0E01
(">"是手機(jī)提示,不是輸入的)

  Q 我最近在編一個關(guān)于短消息的程序,在你的"通過串口收發(fā)短消息"中提到"Text Mode是純文本方式,可使用不同的字符集,從技術(shù)上說也可用于發(fā)送中文短消息,但國內(nèi)手機(jī)基本上不支持,主要用于歐美地區(qū)。"是不是說我用AT指令"AT+CMGF=1"或"AT+CMGF=0"對我后來的收發(fā)短消息沒什么影響啊?

  A Text mode寫起來簡單,直接發(fā)原文就行,發(fā)送非ASCII碼內(nèi)容也能發(fā),但需要手機(jī)支持才能正確顯示。如法語、德語的很多字符,編碼大于0x80,他們都是用text mode。Text mode靠什么區(qū)分字符編碼方式呢?有專門的字符集設(shè)定指令"AT+CSCS"。可以設(shè)定為擴(kuò)充字符集"UCS2"。Siemens TC35/TC37資料上說,它的"AT+CSCS"支持"UCS2"字符集,但我目前沒有機(jī)會去親自試驗(yàn)。正在使用TC35/TC37模塊的朋友不妨試一下。

  據(jù)我了解,中文短消息方面,在國內(nèi)賣的各種手機(jī)只支持PDU mode,這成了事實(shí)上的標(biāo)準(zhǔn)。其實(shí)PDU mode真的挺好用,估計以后text mode會萎縮。我們寫的程序,我建議只采用PDU mode,即使是發(fā)純英文信息也這樣,編碼倒是可以靈活采取7bit或UCS2,因?yàn)?bit能發(fā)的長度是UCS2的2倍(僅對純英文而言)。如果發(fā)送純數(shù)據(jù),不需要手機(jī)顯示,可用8bit。

  Q 你的smstraffic類中的發(fā)送接收大循環(huán)中,是不是把所有收到的消息都放入消息隊(duì)列后,然后執(zhí)行刪除程序。咳绻沂遣l(fā)量很大的話,就是網(wǎng)關(guān)有很多短消息等著進(jìn)入手機(jī),讀完所有短消息后,進(jìn)行刪除的過程中,因?yàn)槎滔⒌呐帕许樞,而?dǎo)致誤刪除呢(比如說我現(xiàn)在手機(jī)里有1-15條短消息,然后在我刪除第一二條后,第三條自動填補(bǔ)為第一條,而新進(jìn)來的短消息,16條排在了第三條,而被cancel掉呢?)我試過好象短消息的排列不是每次都一樣?(在接收的時候,同一條短消息有時是14條,有時是第15條)這個怎么解決。

  A 手機(jī)里消息都有一個物理序號,讀出的時候帶序號,刪除也要根據(jù)序號刪。"物理"二字很關(guān)鍵。這個序號相當(dāng)于ID,無論它前面有沒有刪除、刪除了多少消息,都不會變的。假如原來有1-15,刪除了1和2,又來了一條消息,手機(jī)內(nèi)部的軟件有兩種處理方式:有的放在第1條,有的則放在第16條,我都見過。其實(shí),它愿意放到哪個空閑的地方都行。但無論怎樣,不會引起混亂的,因?yàn)樽x出是什么序號,就刪除什么序號的。在執(zhí)行刪除命令前,消息還是在原來那個地方,不會被后來的覆蓋。

  如果說網(wǎng)關(guān)有很多短消息等著進(jìn)入手機(jī),量很大,這種處理方式效率不高,因?yàn)锳T+CMGL占用很長時間,這段時間手機(jī)無法從SMSC接收新消息。采用我說的"實(shí)時"接收方法比較好,消息來了直接傳出來,不經(jīng)過寫入手機(jī)的過程。

  Q 我用Nokia 8210串口數(shù)據(jù)線,連上電腦的com1口,用SmsTest運(yùn)行提示"沒有發(fā)現(xiàn)MODEM",跟蹤發(fā)現(xiàn)gsmInit()檢測中串口發(fā)AT指令沒有回應(yīng)"OK"。按您的提示我安裝了Nokia modem驅(qū)動程序,(WIN2000 server系統(tǒng))虛擬出com3口的一個8210 MODEM設(shè)備,再次調(diào)用smsTest還是提示"沒有發(fā)現(xiàn)MODEM"。但用串口線,手機(jī)能通過LogoManager手機(jī)管理軟件進(jìn)行相應(yīng)的圖片LOGO,短信發(fā)送操作。

  A Nokia手機(jī)本身沒有帶modem功能,用專業(yè)術(shù)語講就是不具備TA(Terminal Adapter)接口,需要驅(qū)動轉(zhuǎn)換,不管是真的串口,USB還是紅外接口,反正它能虛擬出"標(biāo)準(zhǔn)MODEM"串口來。AT命令只能用標(biāo)準(zhǔn)異步通信。

  在我的印象中,Nokia 8210需用紅外線接口同PC通信。估計你裝的那個驅(qū)動是IR->COM轉(zhuǎn)換的,而不是驅(qū)動串口數(shù)據(jù)線的,可能你的電腦沒有紅外接口,所以com3也連不上?

  要試(虛擬)串口是否連接正確,很簡單,用windows自帶的"超級終端"在特定虛擬端口連上,敲個"AT"回車,看有沒有反應(yīng),正確回答應(yīng)該是"OK"。

  Nokia數(shù)據(jù)線上跑的是"Nokia語"- Nokia專有協(xié)議的數(shù)據(jù),不是通用/擴(kuò)展的AT命令集。LogoManager能聽、能說"Nokia語",所以不需要安裝驅(qū)動就能工作。Nokia有一個免費(fèi)的"Nokia PC Connectivity SDK",可供開發(fā)Nokia手機(jī)使用。至于LogoManager是不是用的這個開發(fā)包,那就不得而知了。

  Q 在SmsTest中,發(fā)出AT命令,然后接收應(yīng)答,比如

WriteComm("AT+CMGF=0\r", 10);
ReadComm(ans, 128);

  在WriteComm函數(shù)后接著就調(diào)用ReadComm,是不是太急,這里的ReadComm函數(shù)是讀返回的這個字符串還是其中的單個字符或不完全的字符串?請問超時控制設(shè)多少最合適。

  A 關(guān)于讀串口,程序中是這樣設(shè)定超時控制的:

COMMTIMEOUTS timeouts = { // 串口超時控制參數(shù)
100, // 讀字符間隔超時時間: 100 ms
1, // 讀操作時每字符的時間: 1 ms (n個字符總共為n ms)
500, // 基本的(額外的)讀超時時間: 500 ms
1, // 寫操作時每字符的時間: 1 ms (n個字符總共為n ms)
100}; // 基本的(額外的)寫超時時間: 100 ms
ReadComm什么時候返回呢?按此timeout設(shè)定,若n=128(ReadComm的第二個參數(shù)),則

  若無任何數(shù)據(jù),等待500+1*128=628毫秒返回。也就是說,若沒有連上手機(jī),根本不存在應(yīng)答,ReadComm會持續(xù)阻塞628毫秒,而后返回。

  若數(shù)據(jù)連續(xù)傳輸,且字符間隔也未超過了100毫秒,但時間已經(jīng)到了628毫秒,返回已讀取的字符(串)。接收到的可能是不完全的字符串。

  若在628毫秒內(nèi),字符間隔超過了100毫秒(第一個字符之前等待的時間不算),返回已讀取的字符(串)。接收到的應(yīng)該是完整的字符串。

  在手機(jī)正確連接的情況下,主要是最后一條起作用。一段數(shù)據(jù)是連續(xù)傳輸?shù)模舨ㄌ芈适?600bps,可以算出字符間隔是0.1毫秒左右,遠(yuǎn)小于100毫秒,不會讀一個字節(jié)或部分?jǐn)?shù)據(jù)就返回;通常是數(shù)據(jù)完畢后才可能出現(xiàn)等待100毫秒而返回的情況。舉個例子,若在執(zhí)行ReadComm(ans, 128)后150毫秒收到"OK\r\n",則還需要額外等100毫秒,也就是說函數(shù)將在250毫秒后返回。這里傳輸4個字節(jié)數(shù)據(jù)的時間被忽略不計了。如果覺得讀得太急,可將基本的(額外的)讀超時時間調(diào)大一些。不過500毫秒內(nèi)還沒有應(yīng)答,可能是連接故障造成的。

  需要特別注意的是"AT+CMGL"指令及其應(yīng)答?赡苁怯捎谛枰獟呙杷写鎯^(qū)域的緣故,手機(jī)在逐條送出短消息后,還需要延遲好幾秒的時間才能送出最后的"OK"。當(dāng)然可以通過設(shè)定上面的基本讀超時時間很長(比如20秒),并且一次讀很長的數(shù)據(jù)(比如2000),來達(dá)到目的。但這樣一來,函數(shù)阻塞時間太長,若恰好這時要程序退出,你會赫然發(fā)現(xiàn)"該程序無響應(yīng)"。SmsTest中解決辦法是:循環(huán)讀取串口數(shù)據(jù),將每次讀取的數(shù)據(jù)拼接起來,最后得到完整的應(yīng)答。gsmGetResponse()每次可能讀取部分?jǐn)?shù)據(jù),將新數(shù)據(jù)追加到已讀數(shù)據(jù)后,且檢測是否見到"OK"或"ERROR",以判斷是否已經(jīng)讀到完整的數(shù)據(jù)。


最新更新
·什么是WAPI?中國為什么要制定WAPI標(biāo)準(zhǔn)
·陜西電信CDMA EV-DO網(wǎng)絡(luò)下載實(shí)測
·解決諾基亞N85不能上網(wǎng)的問題(移動)
·手機(jī)SIM卡后面數(shù)字的秘密
·網(wǎng)友最關(guān)注的十大手機(jī)品牌排行榜
·需要知道的14條手機(jī)電池充電技巧
·用手機(jī)看奧運(yùn)會節(jié)目的三種方式
·什么是CMMB手機(jī)?哪些城市有CMMB信號?
·手機(jī)存儲卡真?zhèn)巫R別技巧:Sandisk/金士頓
·WiFi、WiMAX、WBMA、3G大比拼
相關(guān)信息
放生
愚愛
夠愛
觸電
白狐
心跳
知足
犯錯
降臨
分愛
葬愛
光榮
畫心
火花
稻香
愛得起
這種愛
大丈夫
花蝴蝶
二缺一
小酒窩
下雨天
右手邊
安靜了
棉花糖
明天過后
邊做邊愛
擦肩而過
沒有如果
懷念過去
等一分鐘
越來越愛
寂寞暴走
你的承諾
Nobody
我們都一樣
永遠(yuǎn)在身邊
天使的翅膀
原諒我一次
i miss you
原諒我一次
吻的太逼真
姑娘我愛你
做你的愛人
一定要愛你
飛向別人的床
愛上別人的人
感動天感動地
心在跳情在燒
不潮不用花錢
如何能把你忘記
即使知道要見面
愛上你是一個錯
最后一次的溫柔
愛上你是我的錯
怎么會狠心傷害我
親愛的那不是愛情
傷心時候可以聽情歌
愛上你等于愛上了錯
不是因?yàn)榧拍畔肽?/a>