你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

Nucleo开发板方案设计——GSM/GPRS

[复制链接]
dvd1478 提问时间:2015-1-24 23:17 /
本帖最后由 dvd1478 于 2015-2-2 14:10 编辑

GSM 的英文是 GlobalSys-temForMobileCommunica-tion,即全球移动通信系统,由欧洲标准化委员会设计提出。GSM 系统具有防盗拷贝能力佳、网络容量大、号码资源丰富、 通话清晰、稳定性强不易受干扰、信息灵敏、通话死角少、手机耗电量低等特点。我国自 1994 年底开始建设 GSM 蜂窝移动通信网,其发展势头世人皆叹。目前,中国移动通信拥有世界上网络 规模最大和客户数量最多的GSM移动通信网。
    GPRS 是GeneralPacketRadioService 的英文简称,中文为通用无线分组业务。它具有实时在线、按 量计费、快捷登录、高速传输、自如切换的优点。使用 GPRS 上网的方法与 WAP 不同, 用WAP上网就如在家中上网,先“拨号连接”,上网后便不能同时使用该电话线,但用 GPRS 下载资料和通话可以同时进行,即通话继续使用 GSM,而数据的传送便可使用 GPRS。  
    我们可以简单地理解成为:GSM 是手机语音通话网络,就是打电话发短信的网络;而GPRS 是用手机上网收发数据的网络! 在紧急呼叫机与现下很流行的物联网通讯都有广泛的应用。紧急呼叫机是GSM功能的应用,而物联网是一般都是GPRS的应用。
    这里主要是针对这两个功能进行学习与开发,另外一方向是学习mbed的开发的思想。mbed的开发思想是抛开硬件底层,从而面对类的开发。所用的就是C++/C的开发。


    而有选用的是SIM900A模块,SIM900A 模块板载 SIMCOM 公司的工业级双频GSM/GPRS 模块:SIM900A,工作频段双频:900/1800Mhz,可以低功耗实现语音、SMS(短 信,不支持彩信)、数据和传真信息的传输。 SIM900A 模块支持 RS232 串口和 LVTTL 串口(即支持 3.3V/5V 系统),并带硬件流控制,支持5V~24V的超宽工作范围,使得本模块可以非常方便的与您的产品进行连接,从而给您的产品提供包括语音、短信和GPRS数据传输等功能。


    (1)我是淘宝上选择SIM900A模块,选择时注意不要选太贵的,不值,就算把所有功能引出来,确实方面全方面的学习,但实际上大多数的产品,依我所了解,大都数都是GSM与GPRS的应用。不要选太便宜的,在这方面我就吃过亏了,在功率上并没有处理好或者是信号处理不好,给调试上带我了很大的麻烦。 SIM900A地收发时的瞬间功耗还是很大的,电源上做一些处理,如添加大电容等等。当然初期,调试时可以选择外置电源,这样给给调试带来方便。
     
    (2)判断接线有没问题,其实用一个很简单的方法即可。就是电脑 串口 <===> Nucleo  F072RB  <===> SIM900A串口,Nucleo 在中间只做一个转发的功能即。在mbed这方面却,做得很方面啦,就是关键的几句即可。
  1. Serial serial(SERIAL_TX, SERIAL_RX);  //<span style="color: rgb(0, 0, 0); font-family: 微软雅黑; background-color: rgb(255, 255, 255);">串口 <===> Nucleo  F072RB</span>
  2. GPRSInterface eth(PA_0, PA_1, 115200, "apn", "username", "password");//<span style="color: rgb(0, 0, 0); font-family: 微软雅黑; background-color: rgb(255, 255, 255);">Nucleo  F072RB</span><span style="color: rgb(0, 0, 0); font-family: 微软雅黑; background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 0); font-family: 微软雅黑; line-height: 1.5; background-color: rgb(255, 255, 255);"><span style="background-color: inherit;"> </span><===><span style="background-color: inherit;"> SIM900A串口</span></span>
  3. int main()
  4. {
  5.     wait(3);
  6. bool flag = eth.init();
  7.    
  8.     while(1){
  9. <font color="#ff0000">        while(eth.serialModem.readable()){
  10.             serial.putc(eth.serialModem.getc());</font>
  11.             }
  12. <font color="#ff0000">        while(serial.readable()){
  13.             eth.serialModem.putc(serial.getc());</font>
  14.             }
  15.         }  
  16. }
复制代码
         (3) 就是SIM900A是自动识串口的波特率的,2400~115200 ,但较高波特率时,要多发几次 AT 命令,并且要有一定的延时。
  1. bool GPRS::preInit()
  2. {
  3.     for(int i = 0; i < 2; i++) {
  4.         sendCmd("AT\r\n");
  5.         wait(1);
  6.     }
  7.    
  8.     if(0 != sendCmdAndWaitForResp("AT\r\n","OK",DEFAULT_TIMEOUT,CMD)){
  9.     return false;
  10.    
  11.     }
  12.     if(0 != checkSIMStatus()) {
  13.         return false;
  14.     }
  15.    
  16.     return true;
复制代码

还有很多的心理,不一一写上来的。写代码的,在这方面我还是菜鸟,这里只是显显羞罢了,有什么不足请大家狠狠拍砖。


以下说一下我学习mbed后的思想

UML关系图.jpg
Serial 是SIM900A的接口,继承了Serial类,是其子类。代码上只要以下书写即可
  1. <font color="#000000">class Modem</font>
  2. <font color="#000000">{</font>

  3. <font color="#000000">public:</font>
  4. <font color="#000000">    /**        Create Modem Instance</font>
  5. <font color="#000000">     *  @param tx        uart transmit pin to communicate with Modem</font>
  6. <font color="#000000">     *  @param rx        uart receive pin to communicate with Modem</font>
  7. <font color="#000000">     *  @param baudRate        baud rate of uart communication</font>
  8. <font color="#000000">     */</font>
  9. <font color="#ff0000">    Modem(PinName tx, PinName rx, int baudRate) : serialModem(tx, rx) </font><font color="#000000">{</font>
  10. <font color="#000000">        serialModem.baud(baudRate);</font>
  11. <font color="#000000">    };</font>
  12.         
  13. <font color="#ff0000">        Serial serialModem;</font>
  14. <font color="#000000">protected:</font>
  15.    
  16. 。。。。。。。。。。。
  17. <font color="#000000">private:</font>

  18. <font color="#000000">};</font>
复制代码
把低层的接口封装至modem 类中,而上层的GSM 、GPRS继承了modem类。以下书写即可 ,即能

  1. <font color="#ff0000">class GPRS: public Modem</font>
  2. {
  3. 。。。。。。。。。。。
  4. }
复制代码


GSM 功能已经调试好,而GPRS 还在调试中,好像参赛方案提交的时间快到,我针对GSM功能,做一个简单的紧急呼叫机,设计的思法是这样,任何的操作都有一个按键,拨打接听都是一个按键,保持着 “keep it simple stupid”的思法。

紧急拨号.jpg

QQ图片20150124221045.jpg

紧急拨号流程图.jpg
程序流程图


写得很匆忙,C++也是现学现用的,说错的地方,请大学指点指点。方案做得不怎么好,请大学原谅!~

贴了我调试时的代码片段
一、呼叫测试代码
  1. #if 1
  2. /*call up*/
  3.     bool flag = eth.init();
  4.     CallAnswer callFlag = CallWait;
  5.     if (flag != NULL) {
  6.         printf(">>> Could not initialise. Halting!\n");
  7.         exit(0);
  8.     }
  9.    
  10.     printf("Call the number \r\n");
  11.     eth.callUp("1008611");
  12.    
  13.     while(1){
  14.         callFlag =eth.callWaitAsk();
  15.         switch(callFlag){
  16.             case CallOk:
  17.                 printf("\r\n Is Calling \r\n");
  18.                 //printf("\r\n正在呼叫\r\n");
  19.                 break;
  20.             case CallBusy:
  21.                 printf("\r\n You dial telephone is on the phone, please later again dial \r\n");
  22.                 //printf("\r\n你拨打的电话正在通话中,请稍后再拨\r\n");
  23.                 break;
  24.             case CallNoAnswer:
  25.                 printf("\r\nYou dial telephone temporarily no man answer, please later again dial \r\n");
  26.                 //printf("\r\n你拨打的电话暂时无人接听,请稍后再拨\r\n");
  27.                 break;
  28.             case CallNoCarrier:
  29.                 printf("\r\nEnd of the conversation\r\n");
  30.                 //printf("\r\n通话结束\r\n");
  31.                 break;
  32.             default:
  33.                 printf("\r\n In the middle of, please wait \r\n");
  34.                 //printf("\r\n正中进行,请等待\r\n");
  35.                 break;
  36.             } // end switch(callFlag)
  37.             wait(1);
  38.         }
  39. #endif
复制代码
二、发短信测试代码
(这里发了很长时间,原本是自动判断中英文发送的,但是UNICODE GBK双向转换码 即占用很大部分的ROM空间,后面没有使用mbed开法,却没有超出。我想应该是c++占用了很大的ROM空间,最后还是选择舍去了中文的短信的发送,因为这里主要是学习mbed开发的思想)
  1. #if 1
  2. #define PHONE_NUMBER "186****2964"
  3. #define MESSAGE  "hello,world"
  4. /* send message*/
  5.     bool flag = eth.init();
  6.     if (flag != NULL) {
  7.         printf(">>> Could not initialise. Halting!\n");
  8.         exit(0);
  9.     }
  10.    
  11.     printf("start to send message.... \r\n");
  12.    
  13.     eth.sendSMS(PHONE_NUMBER,MESSAGE);
  14.    
  15.     exit(0);
  16. #endif
复制代码
读短信

  1. #if 1
  2. /* read message */
  3. #define MESSAGE_LENGTH 160
  4. char message[MESSAGE_LENGTH];
  5. int messageIndex = 0;
  6. char phone[16];
  7. char datetime[24];
  8. while(1){
  9.         messageIndex = eth.isSMSunread();
  10.         if (messageIndex > 0) { //At least, there is one UNREAD SMS
  11.           eth.readSMS(messageIndex, message, MESSAGE_LENGTH, phone, datetime);           
  12.           //In order not to full SIM Memory, is better to delete it
  13.           eth.deleteSMS(messageIndex);
  14.           serial.printf("From number: %s \r\n",phone);
  15.           serial.printf("Datetime: %s \r\n",datetime);   
  16.           serial.printf("Recieved Message:" %s "\r\n",message);
  17.         }
  18.     }
  19. #endif
复制代码

四、自动接电话与读短信
  1. #if 1
  2. /*Loop Handle */
  3.     bool flag = eth.init();
  4.     CallAnswer callFlag = CallWait;
  5.     if (flag != NULL) {
  6.         printf(">>> Could not initialise. Halting!\n");
  7.         exit(0);
  8.     }
  9.    
  10.     printf("Call the number \r\n");
  11.    
  12.     while(1){
  13.         callFlag = eth.callWaitAsk();
  14.         switch(callFlag){
  15.             case CallRing:
  16.                 eth.answer();               
  17.                 break;
  18.             case CallSM:
  19.                 #define MESSAGE_LENGTH 160
  20.                 char message[MESSAGE_LENGTH];
  21.                 int messageIndex = 0;
  22.                 char phone[16];
  23.                 char datetime[24];
  24.                 messageIndex = eth.isSMSunread();
  25.                 if (messageIndex > 0) { //At least, there is one UNREAD SMS
  26.                   eth.readSMS(messageIndex, message, MESSAGE_LENGTH, phone, datetime);           
  27.                   //In order not to full SIM Memory, is better to delete it
  28.                   eth.deleteSMS(messageIndex);
  29.                   serial.printf("From number: %s \r\n",phone);
  30.                   serial.printf("Datetime: %s \r\n",datetime);   
  31.                   serial.printf("Recieved Message:" %s "\r\n",message);
  32.                 }
  33.                 break;
  34.             default:
  35.                 break;
  36.             } // end switch(callFlag)
  37.             wait(1);
  38.         }
  39. #endif
复制代码


五、紧急呼叫机
  1. #if 1
  2. const char num[]="551";
  3. bool flag = eth.init();
  4. CallAnswer callFlag = CallWait;
  5. if (flag != NULL) {
  6.     printf(">>> Could not initialise. Halting!\n");
  7.     exit(0);
  8. }
  9. flag = false;
  10. while(1){
  11.         callFlag = eth.callWaitAsk();
  12.         switch(callFlag){
  13.             case CallRing:
  14.                 if( mybutton )
  15.                 {
  16.                     eth.answer();
  17.                     flag = true;
  18.                     while(flag == true)
  19.                     {
  20.                         wait(1);
  21.                         callFlag = eth.callWaitAsk();
  22.                         if(CallNoCarrier==callFlag)
  23.                             flag = false;      
  24.                     }//end while(flag == true)
  25.                 }//end if( mybutton )         
  26.                 break;
  27.             case CallSM:
  28.                 #define MESSAGE_LENGTH 160
  29.                 char message[MESSAGE_LENGTH];
  30.                 int messageIndex = 0;
  31.                 char phone[16];
  32.                 char datetime[24];
  33.                 messageIndex = eth.isSMSunread();
  34.                 if (messageIndex > 0) { //At least, there is one UNREAD SMS
  35.                   eth.readSMS(messageIndex, message, MESSAGE_LENGTH, phone, datetime);           
  36.                   //In order not to full SIM Memory, is better to delete it
  37.                   eth.deleteSMS(messageIndex);
  38.                   serial.printf("From number: %s \r\n",phone);
  39.                   serial.printf("Datetime: %s \r\n",datetime);   
  40.                   serial.printf("Recieved Message:" %s "\r\n",message);
  41.                 }
  42.                 break;
  43.             default:
  44.                 break;
  45.             } // end switch(callFlag)
  46.             
  47.             
  48.             wait(1);
  49.             if( mybutton ){
  50.                 eth.callUp((char *)num);
  51.                     while(flag == true){
  52.                         wait(1);
  53.                         switch(callFlag){
  54.                            
  55.                         case CallOk:
  56.                             //printf("\r\n正在呼叫\r\n");
  57.                             if( mybutton )
  58.                             {
  59.                                 eth.callDown();
  60.                             }//end if( mybutton )
  61.                             break;
  62.                         case CallBusy:
  63.                             //printf("\r\n你拨打的电话正在通话中,请稍后再拨\r\n");
  64.                         case CallNoAnswer:
  65.                             //printf("\r\n你拨打的电话暂时无人接听,请稍后再拨\r\n");
  66.                             wait(10);
  67.                             eth.sendSMS((char *)num,"Hello world!\r\n How are you ?\r\n");
  68.                             break;
  69.                         case CallNoCarrier:
  70.                             //printf("\r\n通话结束\r\n");
  71.                         default:
  72.                             wait(1);
  73.                             //printf("\r\n正中进行,请等待\r\n");
  74.                             break;
  75.                         } // end switch(callFlag)
  76.                     }// end while(flag == true)
  77.                 }//end if( mybutton )
  78.         }//end while(1)
  79.    
  80.    
  81.    
  82. #endif
复制代码



SIM900A的库代码:


GPRS的功能还没有调试好,不好意思上传,迟些我搞个GIT 托管代码 才可以。

下一步计划就是做GPRS功能,实现TCP/IP,做一个远程读取现场温度。



==============================================================
以下为我收集的资料一起分享给大家。




上传了官方文档,链接 点击直达调试常用到的软件 传输门

GPRS.rar

下载

163.66 KB, 下载次数: 23, 下载积分: ST金币 -1

收藏 1 评论22 发布时间:2015-1-24 23:17

举报

22个回答
dvd1478 回答时间:2015-1-28 08:50:15
拼命三郎 发表于 2015-1-25 02:30
谢谢分享,看来国内用到Arduino接口的很少。

Arduino 接口?你用度绑线链接是没有区别的,Nucleo中的Arduino的接口,是为了与Arduino硬件模块接口相对应的。例如拿个Arduino的wifi模块,直接插入Nucleo的Arduino的接口即可以使的。为的就是硬件的兼容性,不必要重新设计。
dvd1478 回答时间:2015-2-2 14:09:20
上传几款常用的调试软件
5.野火串口GSM调试助手.rar (77.97 KB, 下载次数: 0)
dvd1478 回答时间:2015-1-27 18:09:06
SIM900A REACH Test Report Certificate .pdf (495.9 KB, 下载次数: 1)
拼命三郎 回答时间:2015-1-25 02:30:51
谢谢分享,看来国内用到Arduino接口的很少。 stm32.jpg
holts1 回答时间:2015-1-25 08:36:06
功耗有多大 ?
星辰一方 回答时间:2015-1-25 09:05:46
一直也想弄这个GPRS远程,学习下,感谢分享!
fjjjnk1234 回答时间:2015-1-25 12:53:38
感谢分享!顶一个
arm8686 回答时间:2015-1-25 13:06:46
这模块在连网时的电流确实大。
在供电管脚旁边,得放上个大容量的钽电容,至少是 100uF,还好电压低,选择耐压为 6.3V 这一档的钽电容就可以。
wyxy163@126.com 回答时间:2015-1-25 14:40:21
提示: 作者被禁止或删除 内容自动屏蔽
埃斯提爱慕 回答时间:2015-1-25 20:28:20
提示: 作者被禁止或删除 内容自动屏蔽
我是酱油哥 回答时间:2015-1-26 08:43:39

学习,谢谢分享
lkl0305 回答时间:2015-1-26 20:19:02
多谢分享!
天天晓宇 回答时间:2015-1-27 13:15:31
sasmike 回答时间:2015-1-28 08:25:16
学习了……………………
dvd1478 回答时间:2015-1-28 08:45:54
arm8686 发表于 2015-1-25 13:06
这模块在连网时的电流确实大。
在供电管脚旁边,得放上个大容量的钽电容,至少是 100uF,还好电压低,选择 ...

是啊,我也是这样修改过,稳定一些,你是用什么模块,的好的GSM/GPRS模块介绍一下哟
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版