> 文章列表 > STM32驱动SIM900A短信模块

STM32驱动SIM900A短信模块

STM32驱动SIM900A短信模块

简介:STM32F103C8T6驱动SIM900A短信模块源码介绍。

开发平台:KEIL ARM

MCU型号:STM32F103C8T6

传感器型号:SIM900A

特别提示:驱动内可能使用了某些其他组件,比如delay等,在文末外设模板下载地址内有。

1积分源码下载地址在文末!!!

接口图:

使用举例:

#include <stdio.h>
#include "GSM_func.h"int main()
{char mes[] = "this is message";uint8_t recMesID = 0;GSM_Init(); // 初始化GSM_sendMessage(mes);while(1) {// 接收到短信send:1if((recMesID = GSM_waitMessage()) != 0) {char val = GSM_readMessage(recMesID); // val = 1printf("rec mes val:%c\\n", val);}}
}

驱动源码:

GSM_config.c

#include "main.h"#if 0
#define  GSM_USARTx                   USART1
#define  GSM_USART_CLK                RCC_APB2Periph_USART1
#define  GSM_USART_APBxClkCmd         RCC_APB2PeriphClockCmd
#define  GSM_USART_BAUDRATE           9600#define  GSM_USART_GPIO_CLK           (RCC_APB2Periph_GPIOA)
#define  GSM_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd#define  GSM_USART_TX_GPIO_PORT       GPIOA   
#define  GSM_USART_TX_GPIO_PIN        GPIO_Pin_9
#define  GSM_USART_RX_GPIO_PORT       GPIOA
#define  GSM_USART_RX_GPIO_PIN        GPIO_Pin_10#define  GSM_USART_IRQ                USART1_IRQn
#define  GSM_USART_IRQHandler         USART1_IRQHandler#else
#define  GSM_USARTx                   USART2
#define  GSM_USART_CLK                RCC_APB1Periph_USART2
#define  GSM_USART_APBxClkCmd         RCC_APB1PeriphClockCmd
#define  GSM_USART_BAUDRATE           9600#define  GSM_USART_GPIO_CLK           (RCC_APB2Periph_GPIOA)
#define  GSM_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd#define  GSM_USART_TX_GPIO_PORT       GPIOA   
#define  GSM_USART_TX_GPIO_PIN        GPIO_Pin_2
#define  GSM_USART_RX_GPIO_PORT       GPIOA
#define  GSM_USART_RX_GPIO_PIN        GPIO_Pin_3#define  GSM_USART_IRQ                USART2_IRQn
#define  GSM_USART_IRQHandler         USART2_IRQHandler
#endif//	
char GSM_USART_RX_BUF[GSM_USART_MAX_RECV_LEN]; 				
char GSM_USART_TX_BUF[GSM_USART_MAX_SEND_LEN]; 				// [14:0]: 接收字节数 [15]: 接收完成标志
volatile uint16_t GSM_USART_RX_STA = 0;   	// GSM串口中断处理
void GSM_USART_IRQHandler(void)
{uint8_t res;	      if(USART_GetITStatus(GSM_USARTx, USART_IT_RXNE) != RESET){	 res = USART_ReceiveData(GSM_USARTx);if((GSM_USART_RX_STA&(1<<15))==0){ if(GSM_USART_RX_STA<GSM_USART_MAX_RECV_LEN){TIM_SetCounter(TIM3,0);if(GSM_USART_RX_STA==0) {TIM_Cmd(TIM3,ENABLE);}GSM_USART_RX_BUF[GSM_USART_RX_STA++]=res;	}else {GSM_USART_RX_STA|=1<<15;} }USART_ClearITPendingBit(GSM_USARTx, USART_IT_RXNE);}  				 											 
}   
// TIM3中断处理
void TIM3_IRQHandler(void)
{ 	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){	 			   GSM_USART_RX_STA|=1<<15;TIM_ClearITPendingBit(TIM3, TIM_IT_Update);TIM_Cmd(TIM3, DISABLE); }	    
}
/*** @brief  GSM 10ms定时器初始化* @param  None* @retval None* @note   用于检测GSM串口接收状态
*/
void GSM_TIM3_Init(void)
{	NVIC_InitTypeDef NVIC_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);TIM_DeInit(TIM3);TIM_TimeBaseStructure.TIM_Period = 1000-1; TIM_TimeBaseStructure.TIM_Prescaler = 7200-1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);TIM_Cmd(TIM3,DISABLE);NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}
/*** @brief  GSM 串口初始化* @param  bound: 波特率* @retval None* @note   None
*/
void GSM_USART_Init(uint32_t bound)
{  NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;GSM_USART_GPIO_APBxClkCmd(GSM_USART_GPIO_CLK, ENABLE);GSM_USART_APBxClkCmd(GSM_USART_CLK,ENABLE);USART_DeInit(GSM_USARTx); //USART_TXGPIO_InitStructure.GPIO_Pin = GSM_USART_TX_GPIO_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GSM_USART_TX_GPIO_PORT, &GPIO_InitStructure);//USART_RXGPIO_InitStructure.GPIO_Pin = GSM_USART_RX_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GSM_USART_RX_GPIO_PORT, &GPIO_InitStructure);USART_InitStructure.USART_BaudRate = bound;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	USART_Init(GSM_USARTx, &USART_InitStructure);USART_Cmd(GSM_USARTx, ENABLE);USART_ITConfig(GSM_USARTx, USART_IT_RXNE, ENABLE);NVIC_InitStructure.NVIC_IRQChannel = GSM_USART_IRQ;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);	//GSM_USART_RX_STA=0;
}

GSM_config.h

#ifndef __GSM_CONFIG_H
#define __GSM_CONFIG_H	 #include "main.h"#define GSM_USART_MAX_RECV_LEN		128		//	接收缓存大小
#define GSM_USART_MAX_SEND_LEN		32		//  发送缓存大小
#define GSM_USART_RX_EN 			1		//  接收使能标志#define  GSM_USARTx 				USART2extern char  GSM_USART_RX_BUF[GSM_USART_MAX_RECV_LEN]; 
extern char  GSM_USART_TX_BUF[GSM_USART_MAX_SEND_LEN];
extern volatile uint16_t GSM_USART_RX_STA; // 接收数据状态void GSM_USART_IRQHandler(void);
void TIM3_IRQHandler(void);
void GSM_TIM3_Init(void);
void GSM_USART_Init(uint32_t bound);#endif

GSM_func.c

#include "main.h"C lib
//#include <stdlib.h>
//#include <string.h>
//#include <stdio.h>system
//#include "delay.h"
// GSM
#include "GSM_config.h"static char* GSM_check_cmd(char *str);
static void GSM_sendData(char* fmt,...);// GSM信息
const char* GSM_phoneNum = "19198022169";
const char* GSM_head = "send:";/*** @brief  向GSM串口发送数据* @param  fmt: 类似printf的数据格式* @retval None* @note   None*/
void GSM_sendData(char* fmt,...)  
{  uint16_t i,j; va_list ap; va_start(ap,fmt);vsprintf((char*)GSM_USART_TX_BUF,fmt,ap);va_end(ap);i = strlen((const char*)GSM_USART_TX_BUF);		for(j=0; j<i; j++)						{while(USART_GetFlagStatus(GSM_USARTx,USART_FLAG_TC)==RESET); USART_SendData(GSM_USARTx,GSM_USART_TX_BUF[j]); } 
}
/*** @brief  检测应答* @param  str: 期待的应答结果* @retval 0: 没有接收到期待应答* @retval !0: 其他值代表期待应答结果的位置* @note   None*/
static char* GSM_check_cmd(char *str)
{char *strx=0;// 接收到一次数据了if(GSM_USART_RX_STA&0X8000)		{ // 添加结束符GSM_USART_RX_BUF[GSM_USART_RX_STA&0X7FFF]=0;// 检索字符串strx=strstr(GSM_USART_RX_BUF,str);#ifdef DEBUG_printfprintf("rec data: %s\\n",GSM_USART_RX_BUF);#endif} return strx;
}
/*** @brief  向GSM发送命令* @param  cmd: 发送的命令字符串* @param	ack: 期待的应答结果,如果为空,则表示不需要等待应答* @param	waittime: 等待时间(单位:10ms)* @retval 0: 发送成功(得到了期待的应答结果), * @retval	1: 发送失败* @note   None*/
char GSM_send_cmd(char *cmd,char *ack,uint16_t waittime)
{char res=0; GSM_USART_RX_STA=0;//发送命令GSM_sendData("%s",cmd);	if(ack&&waittime)		//需要等待应答{while(--waittime)	//等待倒计时{DELAYClass.DelayMs(10);if(GSM_USART_RX_STA&0X8000)//接收到期待的应答结果{if(GSM_check_cmd(ack) != ((void *)0)){break; // 得到有效数据 }GSM_USART_RX_STA=0;} }if(waittime==0)res=1; }return res;
} 
/*** @brief  string转换int* @param  *str:字符串地址* @retval 返回int型* @note   None*/
int stringToInt(char *str)
{char *p = str;int nNUM = 0;while (*p >= '0' && *p <= '9'){nNUM = nNUM * 10 + (*p - '0');p++;}return nNUM;
}
/*** @brief  发送短信* @param  None* @retval None*/
void GSM_sendMessage(char *message)
{char p[40];#ifdef DEBUG_printfprintf("0. AT+CPIN?\\n");#endifwhile(GSM_send_cmd("AT+CPIN?\\r\\n","OK",100));		// 查询卡状态#ifdef DEBUG_printfprintf("1. AT+CMGF=1\\n");#endifwhile(GSM_send_cmd("AT+CMGF=1\\r\\n","OK",100));		// 设置TXT模式#ifdef DEBUG_printfprintf("2. AT+CMGS=\\n");#endifsprintf((char*)p,"AT+CMGS=\\"%s\\"\\r\\n",GSM_phoneNum); // 设置目标手机号while(GSM_send_cmd(p,">",100));  DELAYClass.DelayMs(50);#ifdef DEBUG_printfprintf("3. %s\\n",message);#endifsprintf((char*)p,"%s\\r\\n",message); // 设置发送内容GSM_send_cmd(p,">",100);  DELAYClass.DelayMs(50);#ifdef DEBUG_printfprintf("4. %x\\n", 0x1A);#endifUSART_SendData(USART2, 0x1A); // 确认发送
}
/*** @brief  等待接收短信* @param  None* @retval 0:无短信,!0:接收到的短信的存放地址*/
uint8_t GSM_waitMessage(void)
{// 接收到一次数据了if(GSM_USART_RX_STA&0X8000)		{ GSM_USART_RX_BUF[GSM_USART_RX_STA&0X7FFF]=0; // 添加结束符
#ifdef DEBUG_printfprintf("(waitMes)%s\\n", GSM_USART_RX_BUF);
#endif		char *strx = 0;// 检索字符串  含有"SM",则代表接收到短信strx=strstr(GSM_USART_RX_BUF,"\\"SM\\",");// 返回不为空则检索到指定字符串if(strx != ((void *)0)){
#ifdef DEBUG_printfprintf("message rec success, addr : %d\\n", stringToInt(strx+5));
#endifuint8_t addrNum = stringToInt(strx+5); // 将地址号保存GSM_USART_RX_STA = 0; // 清除接收标记return addrNum;}GSM_USART_RX_STA = 0;} return 0;
}
/*** @brief  查看短信* @param  None* @retval 返回帧头后的一个字节数据*/
char GSM_readMessage(uint8_t addrNum)
{char pp[40];uint8_t i = 0;sprintf((char*)pp,"AT+CMGR=%d\\r\\n",addrNum); // 查看该地址下的短信GSM_USART_RX_STA = 0;// 等待2sfor(i = 0; i <= 200; i++) {if(i % 50 == 0) // 每0.5s重发一次{
#ifdef DEBUG_printfprintf("i = %d\\n", i);
#endifGSM_sendData("%s", pp);}DELAYClass.DelayMs(10);if(GSM_USART_RX_STA&0X8000)		{ // 添加结束符GSM_USART_RX_BUF[GSM_USART_RX_STA&0X7FFF]=0;
#ifdef DEBUG_printfprintf("(readMes)%s\\n", GSM_USART_RX_BUF);
#endifchar *strx = 0;// 检索字符串  含有"send:",则代表查看短信成功strx=strstr(GSM_USART_RX_BUF,GSM_head);// 返回不为空则检索到指定字符串if(strx != ((void *)0)){
#ifdef DEBUG_printfprintf("message read success, cmd : %c\\n", strx[5]);
#endifchar cmd = 0;cmd = strx[5]; // 此处可根据需求修改 当前是返回的send:后的一个字节GSM_USART_RX_STA = 0; // 清除接收标记DELAYClass.DelayMs(10);sprintf((char*)pp,"AT+CMGD=%d\\r\\n",addrNum); // 删除该地址下的短信GSM_sendData("%s", pp);return cmd;}GSM_USART_RX_STA = 0;}}GSM_USART_RX_STA = 0;return 0;
}
/*** @brief  GSM初始化* @param  None* @retval None* @note   None*/
void GSM_Init(void)
{GSM_USART_Init(9600);GSM_TIM3_Init();
}

GSM_func.h

#ifndef __GSM_FUNC_H
#define __GSM_FUNC_H#include "main.h"char GSM_send_cmd(char *cmd,char *ack,uint16_t waittime);
int stringToInt(char *str);
void GSM_sendMessage(char *message);
uint8_t GSM_waitMessage(void);
char GSM_readMessage(uint8_t addrNum);
void GSM_Init(void);#endif

驱动下载地址:

https://download.csdn.net/download/m0_50669075/87672911

STM32工程模板、外设模板、模块模板下载地址:

stm32_template: STM32F103工程模板,外设模板,模块模板。模块模板包括:DHT11温湿度传感器,OLED屏幕,DS18B20温度传感器,DS1302时钟模块,红外测温模块,RFID模块,SIM900A短信模块,OneNET入网,ADXL345三轴传感器,离线语音识别模块,语音播报模块,甲醛传感器,PM2.5模块,SG90舵机,健康检测模块,消息队列示例,链表示例,分时调度系统示例等。