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,其實是不需要的。


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

鏈接:STM32實現GPRS與服務器數據傳輸


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM