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

查看: 3349|回复: 22

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

[复制链接]

10

主题

88

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-11-11
发表于 2015-1-24 23:17:42 | 显示全部楼层 |阅读模式
本帖最后由 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

<
回复

使用道具 举报

12

主题

1347

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-9-2
发表于 2015-1-25 02:30:51 | 显示全部楼层
谢谢分享,看来国内用到Arduino接口的很少。 stm32.jpg
回复 支持 反对

使用道具 举报

17

主题

359

回帖

2

蝴蝶豆

中级会员

最后登录
1970-1-1
发表于 2015-1-25 08:36:06 | 显示全部楼层
功耗有多大 ?
回复 支持 反对

使用道具 举报

26

主题

845

回帖

0

蝴蝶豆

金牌会员

最后登录
2018-9-27
发表于 2015-1-25 09:05:46 | 显示全部楼层
一直也想弄这个GPRS远程,学习下,感谢分享!
回复 支持 反对

使用道具 举报

8

主题

252

回帖

0

蝴蝶豆

金牌会员

最后登录
2019-2-22
发表于 2015-1-25 12:53:38 | 显示全部楼层
感谢分享!顶一个
回复 支持 反对

使用道具 举报

8

主题

390

回帖

2

蝴蝶豆

论坛元老

最后登录
2019-10-14
发表于 2015-1-25 13:06:46 | 显示全部楼层
这模块在连网时的电流确实大。
在供电管脚旁边,得放上个大容量的钽电容,至少是 100uF,还好电压低,选择耐压为 6.3V 这一档的钽电容就可以。
回复 支持 反对

使用道具 举报

52

主题

3313

回帖

61

蝴蝶豆

论坛元老

最后登录
2020-12-9
发表于 2015-1-25 14:40:21 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

41

主题

2476

回帖

282

蝴蝶豆

论坛元老

最后登录
2020-12-8
发表于 2015-1-25 20:28:20 | 显示全部楼层
学习,谢谢分享
回复 支持 反对

使用道具 举报

5

主题

309

回帖

0

蝴蝶豆

金牌会员

最后登录
2019-5-24
发表于 2015-1-26 08:43:39 | 显示全部楼层

学习,谢谢分享
回复 支持 反对

使用道具 举报

40

主题

1595

回帖

1

蝴蝶豆

论坛元老

最后登录
2018-7-23
发表于 2015-1-26 20:19:02 | 显示全部楼层
多谢分享!
回复 支持 反对

使用道具 举报

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版