SIM900A GSM短信模块
模块来源
资料下载:
https://pan.baidu.com/s/1URIDQv_UNmlGHA5MxJhdHQ
提取码:91yb
规格参数
工作电压:2.0V-5.5V
工作电流:52mA~104mA
默认频率:433Mhz
发射功率:20dBm
参考通信距离:3km
控制方式:串口
文件3.10.2-1 相关手册
移植过程
我们的目标是在立创开发板GD32E230C8T6上能够完成无线传输的功能。首先要获取资料,查看数据手册应如何实现,再移植至我们的工程。
查看资料
模块供电必须使用5V-1A以上,如果供电电源是电脑的USB口,则无法正常工作,需要外部供电。这里采用手机充电器给开发板供电。
模块上 5VR(RX) 5VT(TX) 是可以兼容单片机各种 TTL 电平接口的。接不同的单片机 TTL 电平接口时,只要保证模块上 VCC_MCU 接入的电压跟单片机的TTL电平电压一致就可以了。
SIM卡的选择:
SIM900A 模块为 2G 模块,支持全部 2G 卡,支持大部分 3G 或 4G 的手机卡, 不支持电信卡。支持全部的移动和联通卡。并接入天线。
模块接入电源后,模块上的两个指示灯开始工作,此时可以通过观察 D5 和 D6 LED来大致判断模块的工作状态。
引脚选择
GSM模块的电压是5V,但是电流要大于1A。可以使用充电器、充电宝、或者降压模块,给立创开发板的USB口供电即可。使用电脑的USB口供电,模块会一直复位。
移植至工程
移植步骤中的导入.c和.h文件与上一节相同,只是将.c和.h文件更改为bsp_sim900a.c与bsp_sim900a.h。移植完成后面修改相关代码。
详细可见【TTP224触摸传感器】中的移植至工程目录。这里不再过多讲述。移植完成后面修改相关代码。
工程参考入门手册工程模板
在文件bsp_sim900a.c中,编写如下代码。
/******************************************************************************
* 测试硬件:立创开发板·GD32E230C8T6 使用主频72Mhz 晶振8Mhz
* 版 本 号: V1.0
* 修改作者: www.lckfb.com
* 修改日期: 2023年11月02日
* 功能介绍:
*****************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:【立创·GD32E230C8T6开发板】模块移植手册
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
******************************************************************************/
#include "bsp_sim900a.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
unsigned char GSM_RX_BUFF[];
unsigned char GSM_RX_FLAG = 0;
unsigned char GSM_RX_LEN = 0;
/************************************************************
* 函数名称:GSM_USART_Init
* 函数说明:连接GSM的初始化
* 型 参:bund=串口波特率
* 返 回 值:无
* 备 注:模块波特率默认是 9600
*************************************************************/
void GSM_USART_Init(unsigned int bund)
{
/* 使能 GSM_USART 的时钟 */
rcu_periph_clock_enable(RCU_GSM_USART);
/* 使能时钟 */
rcu_periph_clock_enable(RCU_GSM_TX);
rcu_periph_clock_enable(RCU_GSM_RX);
/* 配置引脚为复用功能 */
gpio_af_set(PORT_GSM_TX, BSP_GSM_AF, GPIO_GSM_TX);
/* 配置引脚为复用功能 */
gpio_af_set(PORT_GSM_RX, BSP_GSM_AF, GPIO_GSM_RX);
/* 配置TX引脚为复用上拉模式 */
gpio_mode_set(PORT_GSM_TX, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_GSM_TX);
/* 配置RX引脚为复用上拉模式 */
gpio_mode_set(PORT_GSM_RX, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_GSM_RX);
/* 配置PA2引脚为为输出模式 */
gpio_output_options_set(PORT_GSM_TX, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_GSM_TX);
/* 配置PA3引脚为为输出模式 */
gpio_output_options_set(PORT_GSM_RX, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_GSM_RX);
/* 设置GSM_USART的波特率为115200 */
usart_baudrate_set(GSM_USART, bund);
/* 设置GSM_USART的校验位为无 */
usart_parity_config(GSM_USART, USART_PM_NONE);
/* 设置GSM_USART的数据位为8位 */
usart_word_length_set(GSM_USART, USART_WL_8BIT);
/* 设置GSM_USART的停止位为1位 */
usart_stop_bit_set(GSM_USART, USART_STB_1BIT);
/* 使能串口1 */
usart_enable(GSM_USART);
/* 使能GSM_USART传输 */
usart_transmit_config(GSM_USART, USART_TRANSMIT_ENABLE);
/* 使能GSM_USART接收 */
usart_receive_config(GSM_USART, USART_RECEIVE_ENABLE);
/* 使能GSM_USART接收中断标志位 */
usart_interrupt_enable(GSM_USART, USART_INT_RBNE);
/* 使能GSM_USART空闲中断标志位 */
usart_interrupt_enable(GSM_USART, USART_INT_IDLE); // DLE 线检测中断
/* 配置中断优先级 */
nvic_irq_enable(GSM_USART_IRQ, 2); // 配置中断优先级
}
/******************************************************************
* 函 数 名 称:GSM_USART_Send_Bit
* 函 数 说 明:向GSM模块发送单个字符
* 函 数 形 参:ch=字符
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void GSM_USART_Send_Bit(unsigned char ch)
{
//发送字符
usart_data_transmit(GSM_USART, ch);
// 等待发送数据缓冲区标志自动置位
while(RESET == usart_flag_get(GSM_USART, USART_FLAG_TBE) );
}
/******************************************************************
* 函 数 名 称:GSM_USART_send_String
* 函 数 说 明:向GSM模块发送字符串
* 函 数 形 参:str=发送的字符串
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void GSM_USART_send_String(unsigned char *str)
{
while( str && *str ) // 地址为空或者值为空跳出
{
GSM_USART_Send_Bit(*str++);
}
}
//清除串口接收的数据
/******************************************************************
* 函 数 名 称:Clear_GSM_RX_BUFF
* 函 数 说 明:清除GSM发过来的数据
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void Clear_GSM_RX_BUFF(void)
{
unsigned char i = GSM_RX_LEN_MAX-1;
while(i)
{
GSM_RX_BUFF[] = 0;
}
GSM_RX_LEN = 0;
GSM_RX_FLAG = 0;
}
/******************************************************************
* 函 数 名 称:GSM_Send_Cmd
* 函 数 说 明:向GSM模块发送指令,并查看GSM模块是否返回想要的数据
* 函 数 形 参:cmd=发送的AT指令 ack=想要的应答 waitms=等待应答的时间 cnt=等待应答多少次
* 函 数 返 回:1=得到了想要的应答 0=没有得到想要的应答
* 作 者:LC
* 备 注:无
******************************************************************/
char GSM_Send_Cmd(char *cmd,char *ack,unsigned int waitms,unsigned char cnt)
{
GSM_USART_send_String((unsigned char*)cmd);//1.发送AT指令
while(cnt--)
{
//串口中断接收蓝牙应答
if( GSM_RX_FLAG == 1 )
{
GSM_RX_FLAG = 0;
GSM_RX_LEN = 0;
//查找是否有想要的数据
if( strstr((char*)GSM_RX_BUFF, ack) != NULL )
{
return 1;
}
//清除接收的数据
memset( GSM_RX_BUFF, 0, sizeof(GSM_RX_BUFF) );
}
//时间间隔
delay_1ms(waitms);
}
GSM_RX_FLAG = 0;
GSM_RX_LEN = 0;
return 0;
}
/**********************************************************
* 函 数 名 称:Get_Signal_Quality
* 函 数 功 能:获取模块信号强度
* 传 入 参 数:无
* 函 数 返 回:信号强度0~99
* 作 者:LC
* 备 注:99=未知 小于10信号差
**********************************************************/
uint8_t Get_Signal_Quality(void)
{
int send_time = 3;
int signal = 0;
char *signal_buff;
//查询信号强度
GSM_USART_send_String((unsigned char*)"AT+CSQ\r\n");
while(send_time--)
{
//假设接收到 "+CSQ:19,0"
if( strstr((char*)GSM_RX_BUFF,"+CSQ:") != NULL )
{
//获取子字符串地址 signal_buff = "+CSQ:19,0"
signal_buff = strstr( (char*)GSM_RX_BUFF, "+CSQ:" );
//字符串以","分割,得到 signal_buff = "+CSQ:19"
signal_buff = strtok( signal_buff, "," );
//字符串地址增加,得到 signal_buff = "19"
signal_buff = signal_buff + strlen("+CSQ:");
//将字符串类型转为整型,得到 signal = 19
signal = atoi( signal_buff );
// //如果信号未知
// if( signal == 99 ) return 2;
}
delay_1ms(200);
}
return signal;
}
/******************************************************************
* 函 数 名 称:Get_GSM_State
* 函 数 说 明:获取GSM模块状态
* 函 数 形 参:无
* 函 数 返 回:1=未检查到设备
2=未检查到天线
3=SIM卡未插入
4=没有注册到网络
* 作 者:LC
* 备 注:如果接收到‘>’,说明当前处于发送短信模式。
******************************************************************/
uint8_t Get_GSM_State(void)
{
char buff[]={0};
GSM_USART_Send_Bit(0X1A);
//检查设备是否存在
if( GSM_Send_Cmd("AT\r\n","OK", 1000,3) == 0 )
{
return 1;
}
Get_Signal_Quality();
//检查SIM卡是否插入
if( GSM_Send_Cmd("AT+CPIN?\r\n","READY", 1000,3) == 0 )
{
return 3;
}
//检查是否注册网络
if( GSM_Send_Cmd("AT+COPS?\r\n","CHINA", 1000,3) == 0 )
{
return 4;
}
return 0;
}
/**********************************************************
* 函 数 名 称:Send_message_text
* 函 数 功 能:向指定电话号码发送英文短信
* 传 入 参 数:phone_number=接收短信的电话号码 send_text=发送的英文短信
* 函 数 返 回:0=发送成功
1=设置模块使用GSM字符串格式失败
2=设置短信格式失败
3=选择短信接收人失败
4=发送内容失败
* 作 者:LC
* 备 注:无
**********************************************************/
uint8_t Send_Message_Text(char *phone_number, char *send_text)
{
char buff[]={0};
//确保上一条信息发送完毕
GSM_USART_Send_Bit(0X1A);
if( GSM_Send_Cmd("AT+CSCS=\"GSM\"\r\n","OK", 1000,3) == 0 )
{
return 1;
}
//设置短信的输入和发送格式为文本模式
if( GSM_Send_Cmd("AT+CMGF=1\r\n","OK", 1000,3) == 0 )
{
return 2;
}
//向MESSAGE_TEXT发送短信
sprintf(buff,"AT+CMGS=\"%s\"\r\n", phone_number);
if( GSM_Send_Cmd(buff,">", 1000,3) == 0 )
{
return 3;
}
//发送内容为Hello\r\n
sprintf(buff,"%s\r\n", send_text);
if( GSM_Send_Cmd(buff,">", 1000,3) == 0 )
{
return 4;
}
//发送短信结束符
GSM_USART_Send_Bit(0X1A);
return 0;
}
/******************************************************************
* 函 数 名 称:GSM_USART_IRQHandler
* 函 数 说 明:连接GSM的串口中断服务函数
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void GSM_USART_IRQHandler(void)
{
if(usart_interrupt_flag_get(GSM_USART,USART_INT_FLAG_RBNE) != RESET) // 接收缓冲区不为空
{
//接收数据
GSM_RX_BUFF[] = usart_data_receive(GSM_USART);
#if DEBUG
//测试,查看接收到了什么数据
printf("%c", GSM_RX_BUFF[]);
#endif
//接收长度限制
GSM_RX_LEN = ( GSM_RX_LEN + 1 ) % GSM_RX_LEN_MAX;
}
if(usart_interrupt_flag_get(GSM_USART,USART_INT_FLAG_IDLE) == SET) // 检测到空闲中断
{
usart_data_receive(GSM_USART); // 必须要读,读出来的值不能要
GSM_RX_BUFF[] = '\0'; //字符串结尾补 '\0'
GSM_RX_FLAG = SET; // 接收完成
usart_interrupt_flag_clear(USART1, USART_INT_FLAG_IDLE);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
在文件bsp_sim900a.h中,编写如下代码。
/******************************************************************************
* 测试硬件:立创开发板·GD32E230C8T6 使用主频72Mhz 晶振8Mhz
* 版 本 号: V1.0
* 修改作者: www.lckfb.com
* 修改日期: 2023年11月02日
* 功能介绍:
*****************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:【立创·GD32E230C8T6开发板】模块移植手册
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
******************************************************************************/
#ifndef _BSP_SIM900A_H_
#define _BSP_SIM900A_H_
#include "gd32e23x.h"
#include "string.h"
#include "systick.h"
//是否开启串口0调试,查看GSM回显数据
#define DEBUG 1
//发送给这个号码
#define MESSAGE_TEXT "15676033359"
/**************************** 串口配置 ****************************/
#define RCU_GSM_TX RCU_GPIOA // 串口TX的端口时钟
#define RCU_GSM_RX RCU_GPIOA // 串口RX的端口时钟
#define RCU_GSM_USART RCU_USART1 // 串口1的时钟
#define PORT_GSM_TX GPIOA // 串口TX的端口
#define PORT_GSM_RX GPIOA // 串口RX的端口
#define GPIO_GSM_TX GPIO_PIN_2 // 串口TX的引脚
#define GPIO_GSM_RX GPIO_PIN_3 // 串口RX的引脚
#define BSP_GSM_AF GPIO_AF_1 // 串口1的复用功能
#define GSM_USART USART1 // 串口1
#define GSM_USART_IRQ USART1_IRQn // 串口1中断
#define GSM_USART_IRQHandler USART1_IRQHandler // 串口1中断服务函数
#define GSM_RX_LEN_MAX 200 //串口接收最大长度
void GSM_USART_Init(unsigned int bund);
void GSM_USART_send_String(unsigned char *str);
uint8_t Get_GSM_State(void);
uint8_t Send_Message_Text(char *phone_number, char *send_text);
#endif
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
案例一 向指定电话号码发送英文信息
在main.c中编写以下代码。(确保.c和.h已经按照以上进行移植)
/******************************************************************************
* 测试硬件:立创开发板·GD32E230C8T6 使用主频72Mhz 晶振8Mhz
* 版 本 号: V1.0
* 修改作者: www.lckfb.com
* 修改日期: 2023年11月02日
* 功能介绍:
*****************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:【立创·GD32E230C8T6开发板】模块移植手册
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
******************************************************************************/
#include "gd32e23x.h"
#include "systick.h"
#include "bsp_usart.h"
#include "stdio.h"
#include "BSP_sim900a.h"
int main(void)
{
systick_config(); //滴答定时器初始化 1ms
usart_gpio_config(9600);
GSM_USART_Init(9600);
printf("start\r\n");
Get_GSM_State();
Send_Message_Text("15676033359","1234567890");
while(1)
{
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
实验现象:15676033359会接收到短信内容为1234567890。