目录
简介
最近在做项目的时候有用到GSM模块进行短信报警,苦于找不到一篇合适的资料教我们如何去使用这个模块并且搭配STM32一起使用,经过我的一番摸索之后,成功的使用了,这里我将这些过程以及源码全部分享给大家。
实验需要的元件
SIM900A模块
SIM卡以及卡套
电源模块3.3V 5V多路输出+电源适配器(DC-9V2A)
CH340串口模块以及杜邦线若干
STM32F103C8T6最小系统板
SIM900A模块
1、SIM900A的通信方式
SIM900A 模块采用串口(UART)通信,每个SIM900A 开发板都含有TTL 接口,其中主要用到的是5VR(RXD)和5VT(TXD),3VR和3VT一般用很少用。
2、SIM900A的供电方式
说明书上是这么说的:常见供电电压为 5V(特殊版本除外),电流为 1A或以上(推荐 2A 或以上)。对于电源适配器提供的电流至少为 1A,考虑到参数虚标,我们推荐 5V 2A 的电源。当然 5V 3A 或 3A 以上的电源会更好的,这样的电源不会损害模块。
我强烈建议直接外部供电,虽然有些 USB—TTL 设备会提供一个 5V 电源,但是多数这样的 5V 电源并不能达到要求。当然也不是不可以,我第一次就是用的USB—TTL的供电的,也没问题,下面是两种供电方式的接线图:
下图为外部供电方式接线图
短信模块的VCC和GND分别接CH340的5V和GND,5VR和5VT分别接CH350的TXD以及RXD。
注意:如果是直接和STM32通信的话,接线如下:
短信模块的VCC和GND分别接外部电源的5V和GND,3VR和3VT分别接STM32的TXD以及RXD。并且GND以及MCU_VCC也要接上去STM32的5V或者3.3V。
下图为USB—TTL直接供电的接线图:
短信模块的VCC和GND分别接CH340的5V和GND,5VR和5VT分别接CH350的TXD以及RXD。
常用指令的含义
相关的AT主要有:这里我只放了和发送短信相关的,以及常见的。
AT+CPMS // 查询SIM卡内短消息使用状态
AT+CNMI // 新消息指示设置
AT+CMGF // 选择短消息格式
AT+CSCS // 编码设置
AT+CSCA // 查询、设置SMS服务中心号码
AT+CSMP // 设置短消息文本模式参数
AT+CMGS // 发送短消息
AT+CMGR // 读取短消息
AT+CMGD // 删除短消息
AT+CMGDA // 删除所有短消息
AT&F // 恢复出厂设置
AT+CSQ // 信号质量
利用电脑串口助手实现SIM900A发送英文和中文短信
一、发送英文短信
1、发送SIM卡检测指令和信号质量检测指令
注意:信号质量值在 0—31 之间,越大代表信号越强。0 代表无信号,一般此数要达到 10 以上,模块才能正确执行发短信等功能。
AT+CPIN? // 查询是否检测到SIM卡
+CPIN: READY
OK
AT+CSQ // 查询信号质量
+CSQ: 18,0
OK
2、发送英文短信指令
AT+CSCS="GSM"
AT+CMGF=1
AT+CMGS="132******63" //手机号码
>Love Kurumi //信息内容
1A(勾选串口助手的16进制发送)
注意:发送新行
发送十六进制0x1A其含义是告诉SIM900A确认发送,然后等待几秒,出现OK表示发送成功。
我手机上面显示的短信内容
二、发送中文短信(重点)
注意:这里需要用到中文转Unicode编码的软件,我们随便点开一个在线Unicode编码转换。
AT+CMGF=1
AT+CSCS="UCS2"
AT+CSMP=17,167,0,8 //普通文本模式
AT+CMGS="00310033003600390030003900360032003100320030" //手机号码的Unicode编码
> 4f60597dff0c72315b6675355b507684523b523b5e1d //短信内容(你好,爱学电子的刻刻帝)Unicode编码
ox1a //表示发送
手机这边收到的消息
利用STM32实现SIM900A发送短信
单片机与 SIM900A 模块引脚对应关系表
单片机引脚 | SIM900A 模块引脚 |
---|---|
PA9 | 3VR |
PA10 | 3VT |
GND | GND |
5V | VCC_MCU |
模块单独供电引脚对应关系表
模块引脚 | 外接电源引脚 |
---|---|
VCC (或 VCC5V) | DC5V |
GND | 电源 GND |
代码功能描述
上电之后,程序会向对应手机号发送Hello以及你好,爱学电子的刻刻帝。注意:我们要先给我们的短信模块上电在给我们的STM32,因为我们短信模块上电后要过一会稳定,而我们的代码是一上电就开始跑了,所以我们要先给我们的短信模块上电。
SIM900A发送英文短信代码
/**************************************************************************/
//函数作用:发送英文短信函数
//函数名称:sim900a_send_English_message(char *message,char *phonenumber)(uint8_t number);
//内部参数:message phonenumber
//修改日期:2024年11月20日
//作者: (CSDN搜)爱学电子的刻刻帝
/**************************************************************************/
void sim900a_send_English_message(char *message,char *phonenumber)
{
Uart_SendStr(USART1,"AT\r\n"); //SIM900A是否与单片机来连接成功
delay_ms(200);
while(Find_char((char*)Usart1_buff,"OK"));
memset(Usart1_buff,0,sizeof(Usart1_buff));
Uart_SendStr(USART1,(u8 *)"AT&F\r\n"); //SIM900A复位
delay_ms(200);
while(Find_char((char*)Usart1_buff,"OK")); //字符串匹对函数
memset(Usart1_buff,0,sizeof(Usart1_buff));
Uart_SendStr(USART1,(u8 *)"AT+CSCS=\"GSM\"\r\n"); //英文短信指令1
delay_ms(200);
while(Find_char((char*)Usart1_buff,"OK"));
memset(Usart1_buff,0,sizeof(Usart1_buff));
Uart_SendStr(USART1,(u8 *)"AT+CMGF=1\r\n"); //英文短信指令2
delay_ms(200);
while(Find_char((char*)Usart1_buff,"OK"));
memset(Usart1_buff,0,sizeof(Usart1_buff));
sprintf(dispbuf,"AT+CMGS=\"%s\"\r\n",phonenumber);
Uart_SendStr(USART1,(uint8_t *)dispbuf); //英文短信指令3
delay_ms(200);
memset(Usart1_buff,0,sizeof(Usart1_buff));
memset(dispbuf,0,sizeof(dispbuf));
Uart_SendStr(USART1,(uint8_t *)message); //英文短信指令4
delay_ms(200);
memset(Usart1_buff,0,sizeof(Usart1_buff));
Usart_SendHalfWord(USART1,0x1a); //结束指令
delay_ms(2000); //延时两秒
memset(Usart1_buff,0,sizeof(Usart1_buff));
}
代码为什么这么写,其实前面我们以及用电脑串口助手模拟过了,只不过我们这里是用STM32的串口进行发送AT指令。
SIM900A发送中文短信代码
/**************************************************************************/
//函数作用:发送中文短信函数
//函数名称:sim900a_send_Chinese_message(char *message,char *phonenumber)(uint8_t number);
//内部参数:message phonenumber
//修改日期:2024年11月20日
//作者: (CSDN搜)爱学电子的刻刻帝
/**************************************************************************/
void sim900a_send_Chinese_message(char *message,char *phonenumber)
{
Uart_SendStr(USART1,"AT\r\n"); //SIM900A是否与单片机来连接成功
delay_ms(200);
while(Find_char((char*)Usart1_buff,"OK"));
memset(Usart1_buff,0,sizeof(Usart1_buff));
Uart_SendStr(USART1,(u8 *)"AT&F\r\n"); //SIM900A复位
delay_ms(200);
while(Find_char((char*)Usart1_buff,"OK")); //字符串匹对函数
memset(Usart1_buff,0,sizeof(Usart1_buff));
Uart_SendStr(USART1,"AT+CSCS=\"UCS2\"\r\n"); //中文短信指令1
delay_ms(200);
while(Find_char((char*)Usart1_buff,"OK"));
memset(Usart1_buff,0,sizeof(Usart1_buff));
Uart_SendStr(USART1,"AT+CMGF=1\r\n"); //中文短信指令2
delay_ms(200);
while(Find_char((char*)Usart1_buff,"OK"));
memset(Usart1_buff,0,sizeof(Usart1_buff));
Uart_SendStr(USART1,"AT+CSMP=17,167,0,8\r\n"); //中文短信指令2
delay_ms(200);
while(Find_char((char*)Usart1_buff,"OK"));
memset(Usart1_buff,0,sizeof(Usart1_buff));
sprintf(dispbuf,"AT+CMGS=\"%s\"\r\n",phonenumber);
Uart_SendStr(USART1,(uint8_t *)dispbuf); //中文短信指令3
delay_ms(200);
memset(Usart1_buff,0,sizeof(Usart1_buff));
memset(dispbuf,0,sizeof(dispbuf));
Uart_SendStr(USART1,(uint8_t *)message); //中文短信指令4
delay_ms(200);
memset(Usart1_buff,0,sizeof(Usart1_buff));
Usart_SendHalfWord(USART1,0x1a); //中文结束指令
delay_ms(2000); //延时两秒
memset(Usart1_buff,0,sizeof(Usart1_buff));
}
发送中文和发送英文的区别就是电话号码和内容都要用Unicode编码实现。其次比发英文的多了一行代码 Uart_SendStr(USART1,"AT+CSMP=17,167,0,8\r\n"); //中文短信指令2
main.c文件代码
#include "stm32f10x.h" // Device header
#include "stdbool.h"
#include "string.h"
#include "stdio.h"
#include "Delay.h"
#include "usart.h"
#include "OLED.h"
#include "sim900a.h"
/*SIM900A短信内容和号码*/
char English_message[]={"Hello!!"}; //英文短信内容
char phonenumber[]={"13690962120"}; //接受短信的号码
char Chinese_message[]={"4f60597dff0c72315b6675355b507684523b523b5e1d"}; //中文短信 内容对应于 你好
char Unicode_phonenumber[]={"00310033003600390030003900360032003100320030"};
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart1_init(9600);//初始化串口1,与GSM短信模块通信
sim900a_send_English_message(English_message,phonenumber);
/*延时4s*/
delay_ms(500);
delay_ms(500);
delay_ms(500);
delay_ms(500);
delay_ms(500);
delay_ms(500);
delay_ms(500);
delay_ms(500);
sim900a_send_Chinese_message(Chinese_message,Unicode_phonenumber);
/*延时4s*/
delay_ms(500);
delay_ms(500);
delay_ms(500);
delay_ms(500);
delay_ms(500);
delay_ms(500);
delay_ms(500);
delay_ms(500);
while(1)
{
}
}
总结
这是最后我们手机收到短信的现象:
补充
我用的是移动的手机卡,其他卡我不是很清楚,但是有一点可以确认的是,天线旁边那个红色的灯,如果3-4s闪烁一次,说明信号接收正常,如果闪的很快,说明信号接收不正常,你可以尝试换一下手机卡或者重新检查手机卡是否正确插到模块上面。
完整的工程代码
注意:我的单片机型号是STM32F03C8T6,源码我上传到我的资源里面,供大家免费下载: