STM32F1与GSM-SIM900A模块短信测试

平台:野火霸道开发板(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

STM32F1与GSM-SIM900A模块短信测试_第1张图片

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' 指令,

STM32F1与GSM-SIM900A模块短信测试_第2张图片

发送之后,再通过里面的

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() 

STM32F1与GSM-SIM900A模块短信测试_第3张图片

同样的,有用的只有这一条

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"就是发送的内容

STM32F1与GSM-SIM900A模块短信测试_第4张图片

            //生成电话号码命令 
            sprintf(cmdbuff,"AT+CMGS=\"%s\"\r",num);

将发送的电话号码10086,通过sprintf,复制到cmdbuff里面, 并且附加上短信头指令

然后把cxye内容复制到converbuff里面去

STM32F1与GSM-SIM900A模块短信测试_第5张图片

 

STM32F1与GSM-SIM900A模块短信测试_第6张图片

先发送电话号码 \\ sprintf(cmdbuff,"AT+CMGS=\"%s\"\r",num);

gsm_cmd(cmdbuff,">",200)

然后坐等回复一个>

STM32F1与GSM-SIM900A模块短信测试_第7张图片

再把信息通过

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();

查询是否接收到新短信

STM32F1与GSM-SIM900A模块短信测试_第8张图片

gsm_cmd_check("+CMTI:")

这个就是判断 有没有接收到 +CMTI:   字符串

 

找到回复信息的 内容首地址,通过strstr来匹配"+CMTI: \"SM\"
        redata_off = strstr(redata,"+CMTI: \"SM\",");

STM32F1与GSM-SIM900A模块短信测试_第9张图片

主函数中的

IsRead=readmessage(newmessadd,namenum,str);    

newmessadd为接收到回复信息的内容首地址

namenum为发送人(10086给你发送回信,这里发送人就是10086)

str 为10086给你发送的内容信息

 

STM32F1与GSM-SIM900A模块短信测试_第10张图片

sprintf(cmd,"AT+CMGR=%d\r",messadd);    

先准备好字符内容cmd(通过sprintf,将AT+CMGR=内容地址,赋值给cmd的)

STM32F1与GSM-SIM900A模块短信测试_第11张图片

STM32F1与GSM-SIM900A模块短信测试_第12张图片

然后把要读取的信息头cmd发送出去, 然后坐等匹配到+CMGR:

 

STM32F1与GSM-SIM900A模块短信测试_第13张图片

匹配到之后 看看是不是首次读(UNREAD)

STM32F1与GSM-SIM900A模块短信测试_第14张图片

 

STM32F1与GSM-SIM900A模块短信测试_第15张图片

把发送人的手机号码提取出来(10086)

STM32F1与GSM-SIM900A模块短信测试_第16张图片

把日期,时间,和回复的内容都保存到str上面去

STM32F1与GSM-SIM900A模块短信测试_第17张图片

 

主函数中

STM32F1与GSM-SIM900A模块短信测试_第18张图片

hexuni2gbk功能为unicode与gbk互转功能

hexuni2gbk(namenum,namegbk); // 转换接受人姓名

hexuni2gbk(str,gbkstr);    // 接收内容

最后把转好的内容通过printf打印到串口1上

printf("新短信:\n发件人:%s\n内容:%s\n\r",namegbk,gbkstr);

 

编译, 下载 看看

STM32F1与GSM-SIM900A模块短信测试_第19张图片

 

结果没有收到回信

开始调试程序

STM32F1与GSM-SIM900A模块短信测试_第20张图片

串口助手显示了下面

STM32F1与GSM-SIM900A模块短信测试_第21张图片

查一下CMGS:36, 只是说明已经发送成功了而已(现在发的是第36条),还是没接收到回信

STM32F1与GSM-SIM900A模块短信测试_第22张图片

现在问题是系统没有给我 自动上报接收到短信通知

 

不用32调试,直接用串口来发送AT命令看看

把串口1的短接帽拔下,拿来给GSM作USB转串口用

sTX->RXD ; sRx-> TXD, GND->GND

不需要程序,直接打开开关发命令就好

STM32F1与GSM-SIM900A模块短信测试_第23张图片

先发AT\r\n ,看看正常不

STM32F1与GSM-SIM900A模块短信测试_第24张图片

注意敲个回车

STM32F1与GSM-SIM900A模块短信测试_第25张图片

显示正常

STM32F1与GSM-SIM900A模块短信测试_第26张图片

检测是否插卡了, 显示也是正常

STM32F1与GSM-SIM900A模块短信测试_第27张图片

STM32F1与GSM-SIM900A模块短信测试_第28张图片

 

发短信试试

STM32F1与GSM-SIM900A模块短信测试_第29张图片

STM32F1与GSM-SIM900A模块短信测试_第30张图片

但还是没有收到新信息的命令

 

 

 

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

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条就接受不了新消息了,只能删除

因此,我们要先查看信息

短信查看全部的,获取的数据要转码

STM32F1与GSM-SIM900A模块短信测试_第31张图片

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

你可能感兴趣的:(stm32)