1. 程式人生 > >GSM模組_STM32實現GPRS與伺服器資料傳輸經驗總結

GSM模組_STM32實現GPRS與伺服器資料傳輸經驗總結

硬體環境

MCU:STM32F103RET6 (偵錯程式:J-Link)

GSM模組:Ai-Thinker_A6 (安信可)(還需要配一個串列埠列印工具,當初選這個模組純粹是因為價格是最便宜的)

-------------------------------------------------------------------------

軟體環境

Keil4

-------------------------------------------------------------------------

開篇廢話

    經過兩週時間的編碼、除錯,終於實現了GSM模組通過GPRS連線伺服器的功能,併成功移植到了公司自己的專案裡面。趁著有點空,我就把整個開發除錯的過程記錄下來,給自己做個備忘,也給大家做個參考。

-------------------------------------------------------------------------

時間列表

2天時間完成底層驅動部分函式的編寫。

4天時間完成模組與伺服器的連線,測試例項:獲取伺服器的RTC資訊。

1天時間移植到公司的專案,純程式碼搬運工作

3天時間測試修復BUG並優化程式碼,找BUG的這幾天,有1天只修改了1條程式碼,我也是醉了。

-------------------------------------------------------------------------

函式清單和注意事項

(底層驅動部分)


1. IO口初始化:控制 IO 和通訊 IO,控制包括電源控制,復位和低功耗模式,通訊就是串列埠啦,相信大家應該都很熟悉了。

                      當然在這個基礎上還可以組合出復位的功能,復位在GPRS連接出錯的時候會用到。

2. 串列埠初始化:模組的波特率為115200,8位資料位,1位停止位,沒有校驗位和流控。

                      串列埠還需要兩個傳送函式,傳送一個位元組和傳送一串字串的。串列埠中斷處理函式放到後面說。

3. AT指令操作:傳送AT指令

                        設定GPRS資料長度

                        傳送GPRS資料內容

                        接收GPRS資料內容

                        AT指令/GPRS資料解析

4. 串列埠中斷函式:包含AT指令/GPRS資料解析 和 接收GPRS資料內容,判斷AT指令是否傳送成功。

    AT指令返回的結束符除了設定GPRS資料長度的是'>',其他都是"\r\n"。但是在判斷接收結束的時候不能只考慮這兩種情況,還有一個情況需要特殊處理,那就是當接收到GPRS資料的時候,完全有可能會出現'\r','\n'對應的十六進位制數。解決的辦法就是在接收到"+CIPRCV:xxx,"的時候,附帶判斷接收到的資料長度,"xxx"代表的是GPRS資料長度資訊,字元型格式,在這裡還需要做一個格式轉換。資料長度的位數根據字元 ','來進行判斷,',' 將AT命令和GPRS資料進行分割。"xxx"換算過來的數值決定了 ',' 後面接收到的資料長度。

    由於目前採用的SIM卡模組內部沒有自帶緩衝區,在GPRS資料接收的時候,需要另外開闢一個儲存空間用於資料的臨時儲存,建議採用環形緩衝區Buffer, 將串列埠接收到的資料按順序儲存,這個部分在串列埠中斷函式裡面實現。在大迴圈裡面將資料取出處理,並設定相關標誌位。我一開始設計的時候只開闢了一個非環形的緩衝區,每次接收到完整的資料,會從緩衝區的0地址重新開始儲存,那麼就會導致未及時處理的資料被新的資料沖掉。 不知道有沒有別家的SIM卡模組是自帶緩衝區的。 

(主迴圈部分)

1. TCP/IP連線流程控制:

    step1、"AT\r\n"//檢測模組串列埠工作

    step2、"AT+CCID\r\n"//檢查是否插卡

    step3、"AT+CREG?\r\n"//檢查網路註冊情況

    step4、"AT+CGATT=1\r\n"//附著網路

    step5、"AT+CGDCONT=1,\"IP\",\"CMNET\"\r\n"//設定PDP引數

    step6、"AT+CGACT=1,1\r\n"//啟用網路

    step7、"AT+CIPSTART=\"TCP\",\"121.41.xxx.xxx\",port\r\n"//連線TCPIP伺服器

    我用的這個模組硬體初始化差不多就要10秒了,在硬體初始化完成後,按照以上七步進行伺服器連線,測試下來,連線的成功率還是蠻高的。前面兩步是硬體檢測用的,如果這兩步都測不過,那就需要檢查下硬體是否完整。三到六步如果返回ERROR,可重複傳送,直至返回OK,每一步之間可間隔數秒。最後一步如果失敗,需先關閉連線,再重新發起連線。如果第七步一直連線不成功,那麼可以通過控制 IO 復位模組,當然也可以先確認下你的伺服器的埠是否開啟。

    我的經驗是連線和通訊的過程中,如果出現錯誤的情況,復位模組是最有效和快捷的方式。在確認硬體連線正常的情況下,如果多次傳送命令失敗,返回ERROR的話,那你還是乖乖的復位它吧。

    另外兩個AT命令也很好用

"AT+CIPCLOSE\r\n"//關閉TCPIP連線

"ATE0\r\n"//關閉回顯,關閉自己發給模組的串列埠資料,除錯的時候可以不開啟這個功能,方便觀察

2. 資料鏈路層資料處理:實現GPRS資料接收/傳送控制,儲存串列埠中斷接收到的資料,傳送GPRS資料長度和GPRS資料內容。

    這個函式裡面需要注意的是傳送GPRS長度和資料的操作,需要在一次操作流程裡面完成。我一開始腦殘的將GPRS資料長度和資料傳送分開處理,導致設定完資料長度後,傳送狀態處於準備好的狀態,此時只要檢測到有資料是需要傳送的,便會通過GPRS傳送出去,而無法保證是當前資料長度對應的資料幀(我在這裡一共開闢了8個數據快取,但是沒有對傳送狀態進行分開判斷)。在設定完資料長度後,需要判斷是否接收到字元'>',大概需要50毫秒的時間。一開始分開發送也是和這個'>'字元的操作有關的,我已經幫大家試過了,連在一起發就好了。

    傳送完GPRS長度幀後,返回字元'>',接著傳送資料幀,在模組返回"OK"之前,傳送的資料都會被髮送到伺服器,導致通訊出錯。所以在資料傳送後,需要等待判斷模組是否已經發送成功。

3. 超時判斷:檢測GPRS資料是否傳送失敗,失敗後可關閉TCP/IP連線,進行重連,如果還是失敗,可復位模組,重新進行TCP/IP連線流程。

-------------------------------------------------------------------------

小技巧

1、官方的例程裡面,在GPRS資料傳送完之後,需要傳送結束符0x1A,其實是不需要的。

最近一直有朋友問我要程式碼,我整理了一下,程式碼和資料已經放到資源裡面了,有需要的朋友請自行下載。