簡介:STM32F103C8T6驅動SIM900A短信模塊源碼介紹。
開發(fā)平臺: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:1
if((recMesID = GSM_waitMessage()) != 0) {
char val = GSM_readMessage(recMesID); // val = 1
printf("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]: 接收字節(jié)數(shù) [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串口接收狀態(tài)
*/
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_TX
GPIO_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_RX
GPIO_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 // 發(fā)送緩存大小
#define GSM_USART_RX_EN 1 // 接收使能標志
#define GSM_USARTx USART2
extern 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; // 接收數(shù)據(jù)狀態(tài)
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串口發(fā)送數(shù)據(jù)
* @param fmt: 類似printf的數(shù)據(jù)格式
* @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;
// 接收到一次數(shù)據(jù)了
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_printf
printf("rec data: %s\n",GSM_USART_RX_BUF);
#endif
}
return strx;
}
/**
* @brief 向GSM發(fā)送命令
* @param cmd: 發(fā)送的命令字符串
* @param ack: 期待的應答結果,如果為空,則表示不需要等待應答
* @param waittime: 等待時間(單位:10ms)
* @retval 0: 發(fā)送成功(得到了期待的應答結果),
* @retval 1: 發(fā)送失敗
* @note None
*/
char GSM_send_cmd(char *cmd,char *ack,uint16_t waittime)
{
char res=0;
GSM_USART_RX_STA=0;
//發(fā)送命令
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; // 得到有效數(shù)據(jù)
}
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 發(fā)送短信
* @param None
* @retval None
*/
void GSM_sendMessage(char *message)
{
char p[40];
#ifdef DEBUG_printf
printf("0. AT+CPIN?\n");
#endif
while(GSM_send_cmd("AT+CPIN?\r\n","OK",100)); // 查詢卡狀態(tài)
#ifdef DEBUG_printf
printf("1. AT+CMGF=1\n");
#endif
while(GSM_send_cmd("AT+CMGF=1\r\n","OK",100)); // 設置TXT模式
#ifdef DEBUG_printf
printf("2. AT+CMGS=\n");
#endif
sprintf((char*)p,"AT+CMGS=\"%s\"\r\n",GSM_phoneNum); // 設置目標手機號
while(GSM_send_cmd(p,">",100));
DELAYClass.DelayMs(50);
#ifdef DEBUG_printf
printf("3. %s\n",message);
#endif
sprintf((char*)p,"%s\r\n",message); // 設置發(fā)送內容
GSM_send_cmd(p,">",100);
DELAYClass.DelayMs(50);
#ifdef DEBUG_printf
printf("4. %x\n", 0x1A);
#endif
USART_SendData(USART2, 0x1A); // 確認發(fā)送
}
/**
* @brief 等待接收短信
* @param None
* @retval 0:無短信,!0:接收到的短信的存放地址
*/
uint8_t GSM_waitMessage(void)
{
// 接收到一次數(shù)據(jù)了
if(GSM_USART_RX_STA&0X8000)
{
GSM_USART_RX_BUF[GSM_USART_RX_STA&0X7FFF]=0; // 添加結束符
#ifdef DEBUG_printf
printf("(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_printf
printf("message rec success, addr : %d\n", stringToInt(strx+5));
#endif
uint8_t addrNum = stringToInt(strx+5); // 將地址號保存
GSM_USART_RX_STA = 0; // 清除接收標記
return addrNum;
}
GSM_USART_RX_STA = 0;
}
return 0;
}
/**
* @brief 查看短信
* @param None
* @retval 返回幀頭后的一個字節(jié)數(shù)據(jù)
*/
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;
// 等待2s
for(i = 0; i <= 200; i++)
{
if(i % 50 == 0) // 每0.5s重發(fā)一次
{
#ifdef DEBUG_printf
printf("i = %d\n", i);
#endif
GSM_sendData("%s", pp);
}
DELAYClass.DelayMs(10);
if(GSM_USART_RX_STA&0X8000)
{
// 添加結束符
GSM_USART_RX_BUF[GSM_USART_RX_STA&0X7FFF]=0;
#ifdef DEBUG_printf
printf("(readMes)%s\n", GSM_USART_RX_BUF);
#endif
char *strx = 0;
// 檢索字符串 含有"send:",則代表查看短信成功
strx=strstr(GSM_USART_RX_BUF,GSM_head);
// 返回不為空則檢索到指定字符串
if(strx != ((void *)0))
{
#ifdef DEBUG_printf
printf("message read success, cmd : %c\n", strx[5]);
#endif
char cmd = 0;
cmd = strx[5]; // 此處可根據(jù)需求修改 當前是返回的send:后的一個字節(jié)
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工程模板、外設模板、模塊模板下載地址:文章來源:http://www.zghlxwxcb.cn/news/detail-477541.html
stm32_template: STM32F103工程模板,外設模板,模塊模板。模塊模板包括:DHT11溫濕度傳感器,OLED屏幕,DS18B20溫度傳感器,DS1302時鐘模塊,紅外測溫模塊,RFID模塊,SIM900A短信模塊,OneNET入網(wǎng),ADXL345三軸傳感器,離線語音識別模塊,語音播報模塊,甲醛傳感器,PM2.5模塊,SG90舵機,健康檢測模塊,消息隊列示例,鏈表示例,分時調度系統(tǒng)示例等。文章來源地址http://www.zghlxwxcb.cn/news/detail-477541.html
到了這里,關于STM32驅動SIM900A短信模塊的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!