STM32F1与GSM |
您所在的位置:网站首页 › 实时短信源码是什么 › STM32F1与GSM |
平台:野火霸道开发板(STM32F103ZET6) 模块:SIM900A(大卡的SIM卡) 测试内容: STM32对GSM模块控制(串口2),控制其发送短信给10086(我用的移动卡),然后通过32转发接收,再把其内容发到串口1上
连接: GSM模块上的STX STM32 PA3; SRX STM32 PA2; GND(GSM) GND(开发板上随便一个地) 注意,GSM模块上有STX和MRX,这个M指的是MAX3232,是工业串口用的, S才是我们常用的TTL电平(有可能是MOS电平)
程序: 需要发送短信号码修改为10086 USART_Config(); 配置串口1,主要是用来GSM与STM32通信的内容,通过串口1进行转发打印到串口助手上
GSM_USART_Config(); 配置串口2,主要是通过STM32通过串口2对GSM模块进行AT控制发送指令 SysTick_Init(); 系统滴答定时器,主要是用来做延时的,如后面的delay_ms //检测模块响应是否正常 while(gsm_cmd("AT\r","OK",1000) != GSM_TRUE) { printf("\r\n模块响应测试不正常!!\r\n"); printf("\r\n若模块响应测试一直不正常,请检查模块的连接或是否已开启电源开关\r\n"); }gsm_cmd("AT\r","OK",1000) 通过这个封装好的函数, stm32通过串口2,对GSM发送 'AT\r' 指令, 发送之后,再通过里面的 gsm_cmd_check(reply); 进行对接收数据的判断,判断接收到GSM返回来的指令是不是"OK",是OK就返回正常(GSM_TRUE)
如果返回不是OK, 串口1就会输出 printf("\r\n模块响应测试不正常!!\r\n"); printf("\r\n若模块响应测试一直不正常,请检查模块的连接或是否已开启电源开关\r\n"); 如果串口没有打印上面的信息,那么就是正常,证明连接上了GSM了 如果错误,检测下你是不是接错线,或者漏了接GND-GND的线,又或者没有插入SIM卡
printf("\r\n通过了模块响应测试\r\n"); printf("\r\n正在等待GSM模块初始化...\r\n"); while(IsInsertCard() != GSM_TRUE) { if(++testCard >20) { printf("\r\n检测不到电话卡,请断电并重新接入电话卡\r\n"); } GSM_DELAY(1000); } IsInsertCard() 同样的,有用的只有这一条 gsm_cmd("AT+CNUM\r","OK",200); 通过串口2发送"AT+CNUM\r", 然后等待200ms,然后判断接收的内容是不是"OK",是就返回正常(GSM_TRUE)
这时候GSM模块就已经初始化好了,下面可以发送消息了 /* 延时5秒再发送命令到模块 */ GSM_DELAY(5000); //发送英文短信 if(gsm_sms((char *)num,"cxye") == GSM_TRUE) printf("\r\n英文短信已发送至:%s,为方便测试,请在程序中修改接收短信的手机号码",num); else { printf("\r\n短信发送失败,请确认目标号码有效"); } GSM_DELAY(2000); 通过下面函数,发送"cxye" 查询余额 gsm_sms((char *)num,"cxye") 其中num是上面的 10086号码, "cxye"就是发送的内容 //生成电话号码命令 sprintf(cmdbuff,"AT+CMGS=\"%s\"\r",num); 将发送的电话号码10086,通过sprintf,复制到cmdbuff里面, 并且附加上短信头指令 然后把cxye内容复制到converbuff里面去
先发送电话号码 \\ sprintf(cmdbuff,"AT+CMGS=\"%s\"\r",num); gsm_cmd(cmdbuff,">",200) 然后坐等回复一个> 再把信息通过 GSM_USART_printf("%s",converbuff);//发送短信内容 发送出去 (类似上图的This is a test 只是这里换成了cxye)
主循环 while(1) { GSM_DELAY(1000); newmessadd=IsReceiveMS(); if(newmessadd) { IsRead=readmessage(newmessadd,namenum,str); // printf("newmessadd=%d,IsRead:%d\n",newmessadd,IsRead); if(IsRead) { printf("新短信\n\r"); hexuni2gbk(namenum,namegbk); hexuni2gbk(str,gbkstr); printf("新短信:\n发件人:%s\n内容:%s\n\r",namegbk,gbkstr); } } }newmessadd=IsReceiveMS(); 查询是否接收到新短信 gsm_cmd_check("+CMTI:") 这个就是判断 有没有接收到 +CMTI: 字符串
找到回复信息的 内容首地址,通过strstr来匹配"+CMTI: \"SM\" redata_off = strstr(redata,"+CMTI: \"SM\","); 主函数中的 IsRead=readmessage(newmessadd,namenum,str); newmessadd为接收到回复信息的内容首地址 namenum为发送人(10086给你发送回信,这里发送人就是10086) str 为10086给你发送的内容信息
sprintf(cmd,"AT+CMGR=%d\r",messadd); 先准备好字符内容cmd(通过sprintf,将AT+CMGR=内容地址,赋值给cmd的) 然后把要读取的信息头cmd发送出去, 然后坐等匹配到+CMGR:
匹配到之后 看看是不是首次读(UNREAD)
把发送人的手机号码提取出来(10086) 把日期,时间,和回复的内容都保存到str上面去
主函数中 hexuni2gbk功能为unicode与gbk互转功能 hexuni2gbk(namenum,namegbk); // 转换接受人姓名 hexuni2gbk(str,gbkstr); // 接收内容 最后把转好的内容通过printf打印到串口1上 printf("新短信:\n发件人:%s\n内容:%s\n\r",namegbk,gbkstr);
编译, 下载 看看
结果没有收到回信 开始调试程序 串口助手显示了下面 查一下CMGS:36, 只是说明已经发送成功了而已(现在发的是第36条),还是没接收到回信 现在问题是系统没有给我 自动上报接收到短信通知
不用32调试,直接用串口来发送AT命令看看 把串口1的短接帽拔下,拿来给GSM作USB转串口用 sTX->RXD ; sRx-> TXD, GND->GND 不需要程序,直接打开开关发命令就好 先发AT\r\n ,看看正常不 注意敲个回车 显示正常 检测是否插卡了, 显示也是正常
发短信试试 但还是没有收到新信息的命令
-------------------------------------------------------------------- 2020年10月9日 昨天已经发现问题所在了,今天才有空写一写 1.AT+CNMI=?新消息指示 需要设置 设置为 AT+CNMI=2,1,0,0,0 就好,转自 https://blog.csdn.net/qq_35629563/article/details/82752886
2.问题调试出现再:短信只能存50条,多余50条就接受不了新消息了,只能删除 因此,我们要先查看信息 短信查看全部的,获取的数据要转码 AT+CMGL="ALL" 一般用上面语句,列出所有信息
删除具体某一条信息可以用 AT+CMGD=50 具体作用为删除第50条短信
也可以用AT+CMGDA="DEL READ" 作用为删除所有已读短信
3.当你再输入AT+CMGL="ALL" 列出所有信息时,如果还有空间容纳新短信(小于50条才能接受新内容,指示SIM900A是这样的),这时才能接受新的信息 比如你收到了一条信息, 它是下面的语句格式的(AT+CNMI=2,1,0,0,0设置情况下) +CMTI: "SM",22 +CMTI就是标头, SM是指信息, 22是指的信息存储的位置
如果你要读22位置的短信,使用下面语句 AT+CMGR=32,0 作用为读取第32条消息,0指正常读
读完之后,22这位置的短信状态会由 REC UNREAD 变成 REC READ |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |