單片機控制GSM模塊(TC35)收發(fā)短信接打電話
這兩天用單片機控制GSM模塊(TC35)收發(fā)短信接打電話碰到了一些問題,也走了一些彎路,總的看來用AT命令控制GPRS算是比較簡單,不過要注意的是一些細(xì)節(jié)問題,如果沒注意到這些問題將會耗費很多時間。
網(wǎng)上相關(guān)的資料有很多,但感覺比較雜,一些細(xì)節(jié)問題沒有強調(diào)清楚。先看下發(fā)短信的幾個AT命令。
直接在pc上面串口操作的命令如下:
依次執(zhí)行下列命令,
AT+CMGF=1 //文本方式
AT+CSCS="GSM" //字符模式
AT+CSMP=17,168,0,0 //字符編碼
AT+CSCA="+8613800791500",145 //短信中心號碼
AT+CMGS="136********" //發(fā)短信命令 接收短信的號碼
//當(dāng)命令A(yù)T+CMGS="136********"執(zhí)行后超級終端出現(xiàn)>(大于號),提示用戶在大于號后面輸入短信內(nèi)容。
短信內(nèi)容輸入完畢后直接按鍵盤上的Ctrl+z確認(rèn)發(fā)送。除命令“AT+CMGS="136********"”執(zhí)行成功后是返回“>”,其它命令執(zhí)行成功后都直接返回“OK”,當(dāng)然“AT+CMGS="136********"”這條命令執(zhí)行完后是等待用戶的輸入,用戶按
Ctrl+z發(fā)送后,發(fā)送成功依然會返回“OK”。
接收短信的操作更簡單,只要通過執(zhí)行AT+CMGF=1命令選擇文本方式后就能通過讀取命令讀取收到的短信,收短信我們不用設(shè)置GPRS怎樣接收短信,因為GPRS接收短信的操作是內(nèi)部完成的,我們不用去理會。當(dāng)然如果之前你發(fā)短信的操作已經(jīng)執(zhí)行了AT+CMGF=1命令的話,那你收短信的時候就沒必要重復(fù)操作了。
收短信的操作如下:
1.列舉所有短信:
AT+CMGF=1
AT+CMGL="ALL" //讀取所有短信
2.列舉未讀的短信:
AT+CMGF=1
AT+CMGL=”REC UNREAD”
3.列舉已讀的短信:
AT+CMGF=1
AT+CMGL=”REC READ”
其實叫列舉,也就是讀取的意思,只是讀取的是多條短信,是所有的短信內(nèi)容的列表。
4.讀取短信:
AT+CMGF=1
AT+CMGR=短信索引號
刪除短信的操作:
按索引號刪除:
AT+CMGF=1
AT+CMGD=短信存儲索引號 //當(dāng)讀出所有短信時,每條短信前面都對應(yīng)了本條//短信的索引編號
刪除已讀短信:
AT+CMGF=1
AT+CMGD=1,2
接聽電話:
簡單的一個ATA就搞定。
撥打電話:
ATD136********; //別漏掉了“;”
掛電話命令:
ATH
以上所講的都是直接通過超級終端或串口調(diào)試平臺進行的命令操作。在編程應(yīng)用這些命
令時還要注意一些細(xì)節(jié)問題。
編程中注意除了確認(rèn)短信發(fā)送的這條指令0X1A(對應(yīng)ctrl+z的十六進制表示)外每條命令結(jié)尾都要加上“\r\n”。
具體發(fā)短信的操作可以參考我的代碼:
//發(fā)送短信
//參數(shù) 1短信號碼 2短信內(nèi)容
void SendMessage(unsigned char *num,unsigned char *massge)
{
unsigned char instuct[]="AT+CMGS=\"";
unsigned char numinstuct[27];
strcpy(numinstuct,instuct);
strcat(numinstuct,num);
strcat(numinstuct,"\"\r\n");
USART1_Write_DR(numinstuct);//AT+CMGS=\"136********\"
USART1_Write_DR(massge);
UART1_SendByte(0x1a);
}
調(diào)用該函數(shù):
SendMessage("158********","test!\r\n"); //發(fā)送短信 注意加\r\n
我做本程序所要實現(xiàn)的是從短信的內(nèi)容中提取相關(guān)的控制命令,MUC根據(jù)相關(guān)命令執(zhí)行對應(yīng)的操作,一開始我想從GPRS通過串口返回的字符串中提取相關(guān)的命令字符,由于GPRS通過串口返回的字符有其特殊的格式,提取比較麻煩,而且提取得按一定的格式來操作,顯然操作起來不靈活,而用戶也得按這種格式來發(fā)命令顯然不方便用戶操作,并且使得用戶的操作更為復(fù)雜。
折騰了好一陣子后我突然意識到直接用strstr(char *str1, char *str2)(未檢測到str2則返回NULL,檢測到了就返回從str2開始到后面的字符)函數(shù)檢測字符更方便,而且可以實現(xiàn)短信內(nèi)容的智能識別,這樣我只要判斷短信中存不存在相應(yīng)的命令字符就可以,沒必要考慮繁雜的字符串提取問題。而且用戶發(fā)命令可以相對自由,只要單個命令不出錯,多個命令之間可以自由排列,甚至可以出現(xiàn)不相關(guān)的字符,當(dāng)然前提是這些不相關(guān)的字符的組合不會出現(xiàn)用戶命令協(xié)議中的命令字符。
編寫AT命令時大家還得注意確保字符是在英文輸入法下輸入的。
就總結(jié)到這里了,大家可以參考我的代碼,進一步分析我以上總結(jié)的。
每條指令用0x0D結(jié)尾。