单片机 STM32 HAL GSM通讯 SIM800L

一、 简介

无论您是想聆听与您相距遥远的房屋中发生的情况,还是仅通过静音呼叫即可激活花园中的洒水系统;然后,SIM800L GSM / GPRS模块将成为您入门物联网的坚实起点!

SIM800L GSM / GPRS模块是微型GSM调制解调器,可以集成到许多IoT项目中。您可以使用此模块完成普通手机可以完成的几乎所有工作;短信,拨打或接听电话,通过GPRS,TCP / IP等连接到Internet!最重要的是,该模块支持四频GSM / GPRS网络,这意味着它可以在世界上的任何地方工作。

二、特性

该模块的核心是SimCom的SIM800L GSM蜂窝芯片。芯片的工作电压为3.4V至4.4V,这使其成为直接为Li电池供电的理想选择。这使其成为无需太多空间嵌入项目的不错选择。

SIM800L GSM芯片的所有必需数据引脚均被拆分为0.1英寸间距接头。这包括通过UART与微控制器通信所需的引脚。该模块支持1200bps至115200bps的波特率,并具有自动波特率检测功能。

该模块需要外部天线才能连接到网络。该模块通常带有螺旋天线,并直接焊接到PCB上的NET引脚。该板还具有U.FL连接器功能,以防天线远离板。

在这里插入图片描述
背面有一个SIM卡插槽!任何激活的2G micro SIM卡都可以正常工作。SIM卡插槽的表面通常刻有正确的SIM卡插入方向。

该模块的尺寸仅为1平方英寸,但在其小框架中却包含了令人惊讶的功能。下面列出了其中一些:

  • 支持四频:GSM850,EGSM900,DCS1800和PCS1900

  • 使用任何2G SIM连接到任何全球GSM网络

  • 使用外部8Ω扬声器和驻极体麦克风拨打和接听语音电话

  • 发送和接收短信

  • 发送和接收GPRS数据(TCP / IP,HTTP等)

  • 扫描和接收FM广播

  • 发射功率:

    • GSM850的4类(2W)
    • DCS1800的1类(1W)
  • 基于串行的AT命令集

  • 蜂窝天线的FL连接器

  • 接受Micro SIM卡

三、笔记

模式频率电流
掉电60微安
睡眠模式1 mA
支持18 mA
呼叫GSM850199 mA
呼叫EGSM900216 mA
呼叫DCS1800146 mA
呼叫PCS1900131 mA
GPRS453 mA
传输信号峰值2 A

四、示例代码

/*************笔记****************
1、本SIM800L模块采用huart3(串口3),然后huart1(串口1)作为调试输出。
2、CudeMX配置huart3:
   ------------------------------------------
   Mode        --> Asynchronous(异步)
   Baud Rate   --> 9600 Bit/s
   Word Length --> 8 Bit
   Parity      --> None
   Stop Bits   --> 1
   ------------------------------------------
   NVIC        --> 串口中断使能
   ------------------------------------------
   DMA         --> Add 增加RX TX
               --> Data Width --> Byte
   ------------------------------------------
3、需要FreeRTOS系统支持,需要"uartext.c"、"uartext.h"
4、本代码末尾有FreeRTOS任务模板。StartGSMTask()
5、
***********************************/
#include "SIM800L.h"
#include <stdlib.h>
#include "stm32f1xx_hal.h"
#include "cmsis_os.h"
#include "uartext.h"

extern UART_HandleTypeDef huart3;//串口3
extern uint8_t SIM800L_Get_text[32];
extern uint8_t Address;

/*********************************************************
函数名:SIM800L_Check_Cmd
功  能:发送命令后,检测接收到的应答
形  参:str--期待的应答结果
返回值:0--没有得到期待的应答结果 *?*--期待应答结果的位置(str的位置)
备  注:
**********************************************************/
uint8_t* SIM800L_Check_Cmd(uint8_t *str)
{
    char *strx = 0;
    strx = strstr((const char*)SIM800L_Get_text, (const char*)str); //寻找文本(被寻找,欲寻找)
    return (uint8_t*)strx;
}


/********************************************
函数名:SIM800L_Send_Cmd
功  能:向GSM发送命令
形  参:cmd:发送的命令字符串(不需要添加回车了)
        ack:期待的应答结果,如果为空,则表示不需要等待应答
        waittime:等待时间(单位:100ms)
返回值:0--发送成功(得到了期待的应答结果)
        1--发送失败
备  注:
*********************************************/
uint8_t SIM800L_Send_Cmd(uint8_t *cmd, uint8_t *ack, u16 WaitTime)
{
    uint8_t res = 0;
    uint8_t TxBuffer[32];
    uint8_t len;

    sprintf((char *)TxBuffer, "%s\r\n", cmd);
    UartPutStr(&huart3, TxBuffer, strlen((char *)TxBuffer));//发给串口3


    if(ack && WaitTime)     //需要等待应答
    {
        while(--WaitTime)    //等待倒计时
        {
            osDelay(100);
            len = UartGetStr(&huart3, SIM800L_Get_text); //从串口3读取一次数据
            if(len > 1) //接收期待的应答结果
            {
                if(SIM800L_Check_Cmd(ack))
                {
                    break;//得到有效数据
                }
            }
        }
        if(WaitTime == 0)
        {
            res = 1;
        }
    }
    return res;
}


/*********************************************************
函数名:SIM800L_Info_Show
功  能:GSM检测(SIM卡准备和是否注册成功)
形  参:无
返回值:2--正常  其他--错误代码
备  注:
**********************************************************/
uint8_t SIM800L_Info_Show(void)
{
    static uint8_t sim_flag = 0;
    uint8_t TxBuffer[40];

    switch(sim_flag)
    {
        case 0:
            if(SIM800L_Send_Cmd("AT+CPIN?", "OK", 20)) //查询SIM卡是否在位
            {
                sprintf((char *)TxBuffer, "%d,02,05,Not SIM Crad\r\n", Address);
                UartPutStr(&huart1, TxBuffer, strlen((char *)TxBuffer));//发给串口1方便调试
            }
            else
            {
                sim_flag = 1;
                sprintf((char *)TxBuffer, "%d,02,05,SIM Crad Yes\r\n", Address);
                UartPutStr(&huart1, TxBuffer, strlen((char *)TxBuffer));//发给串口1方便调试
            }
            break;
        case 1:
            if(SIM800L_Send_Cmd("AT+CREG?", "+CREG: 0,1", 20)) //查询SIM卡网络是否已注册
            {
                sprintf((char *)TxBuffer, "%d,02,05,Network Registering!\r\n", Address);
                UartPutStr(&huart1, TxBuffer, strlen((char *)TxBuffer));//发给串口1方便调试
            }
            else
            {
                sim_flag = 2;
                sprintf((char *)TxBuffer, "%d,02,05,Network Register Success!\r\n", Address);
                UartPutStr(&huart1, TxBuffer, strlen((char *)TxBuffer));//发给串口1方便调试
            }
            break;
    }
    return sim_flag;
}

/********************************************
函数名:SIM800L_CallNum
功  能:拨打指定号码
形  参:*num--手机号码("18977011111")
返回值:无
备  注:无
*********************************************/
void SIM800L_CallNum(uint8_t *Num)
{
    uint8_t TxBuffer[20];
    sprintf((char *)TxBuffer, "ATD%s;\r\n", Num);
    UartPutStr(&huart3, TxBuffer, strlen((char *)TxBuffer));//发给串口3
}

/********************************************
函数名:SIM800L_CmdShowOff
功  能:指令不回显
形  参:无
返回值:无
备  注:无
*********************************************/
void SIM800L_CmdShowOff(void)
{
    uint8_t TxBuffer[10];
    sprintf((char *)TxBuffer, "ATE0\r\n");
    UartPutStr(&huart3, TxBuffer, strlen((char *)TxBuffer));//发给串口3
}


/********************************************
函数名:SIM800L_SendEN_SMS
功  能:设置TEXT文本模式发送英文短信
形  参:*phone--接收短信的号码  *text--短信内容
返回值:无
备  注:SIM800L_SendEN_SMS(“10086”,“123”)
*********************************************/
void SIM800L_SendEN_SMS(uint8_t *phone, uint8_t *text)
{
    uint8_t TxBuffer[32];

    SIM800L_Send_Cmd("AT+CMGF=1", "OK", 10);       //设置文本模式
    SIM800L_Send_Cmd("AT+CSCS=\"GSM\"", "OK", 10); //设置TE字符集为GSM

    sprintf((char *)TxBuffer, "AT+CMGS=\"%s\"\r\n", phone);
    SIM800L_Send_Cmd(TxBuffer, ">", 10);                     //发送短信命令+电话号码

    UartPutStr(&huart3, text, strlen((char *)text)); //发给串口3,发送短信内容到GSM模块

    osDelay(1000);                                   //必须增加延时,否则接收方接收信息不全
    if(SIM800L_Send_Cmd("\x1a\r\n", "+CMGS:", 100) == 0) //发送结束符,等待发送完成(最长等待10秒钟,因为短信长了的话,等待时间会长一些)
    {
        sprintf((char *)TxBuffer, "%d,02,05,SMS Send Success!\r\n", Address);
        UartPutStr(&huart1, TxBuffer, strlen((char *)TxBuffer));//发给串口1方便调试
    }
    else
    {
        sprintf((char *)TxBuffer, "%d,02,05,SMS Send fail!\r\n", Address);
        UartPutStr(&huart1, TxBuffer, strlen((char *)TxBuffer));//发给串口1方便调试
    }
}


///*********************************************
//函数名:StartGSMTask
//功  能:处理GSM相关功能
//形  参:
//返回值:
//备  注:【GSM】的返回信息到达
//类型码:05
//**********************************************/
//uint8_t SIM800L_Get_text[32];
//void StartGSMTask(void const * argument)
//{
//    uint8_t RxBuffer[32], TxBuffer[32];
//    uint16_t len;
//    osDelay(400);
//    /*GSM初始化部分*/
//    sprintf((char *)TxBuffer, "AT\r\n");
//    UartPutStr(&huart3, TxBuffer, strlen((char *)TxBuffer));//初始化GSM模块的波特率,发送任意字符使其自适应
    while(SIM800L_Send_Cmd("AT", "OK", 100)) //检测是否应答AT指令
    {
        sprintf((char *)TxBuffer, "未检测到模块!!!\r\n");
        UartPutStr(&huart1, TxBuffer, strlen((char *)TxBuffer));//发给串口1方便调试
        osDelay(800);
        sprintf((char *)TxBuffer, "尝试连接模块...\r\n");
        UartPutStr(&huart1, TxBuffer, strlen((char *)TxBuffer));//发给串口1方便调试
        osDelay(400);
    }
//    for(;;)
//    {
//        len = UartGetStr(&huart3, RxBuffer); //从串口3读取一次数据
//        if(len > 1)
//        {
//            memcpy(SIM800L_Get_text, RxBuffer, strlen((char *)RxBuffer));
//            UartPutStr(&huart1, RxBuffer, len);
//        }

//        osMessagePut(QueWdtHandle, 0x08, 10);
//        osDelay(2);
//    }
//}

#ifndef _SIM800L_H
#define _SIM800L_H
#include "main.h"

uint8_t* SIM800L_Check_Cmd(uint8_t *str);
uint8_t SIM800L_Send_Cmd(uint8_t *cmd, uint8_t *ack, u16 WaitTime);

uint8_t SIM800L_Info_Show(void);
void SIM800L_CallNum(uint8_t *Num);
void SIM800L_CmdShowOff(void);
void SIM800L_SendEN_SMS(uint8_t *phone,uint8_t *text);
#endif

  • 4
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
好的,关于stm32hal串口通讯,你可以使用HAL库提供的函数来实现。首先需要初始化串口,然后使用HAL_UART_Transmit()函数发送数据,使用HAL_UART_Receive()函数接收数据。以下是一个简单的示例代码: ``` #include "stm32f4xx_hal.h" UART_HandleTypeDef huart2; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART2_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART2_UART_Init(); uint8_t txData[] = "Hello World!\r\n"; uint8_t rxData[10]; while (1) { HAL_UART_Transmit(&huart2, txData, sizeof(txData), HAL_MAX_DELAY); HAL_UART_Receive(&huart2, rxData, sizeof(rxData), HAL_MAX_DELAY); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } static void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF7_USART2; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jianqiang.xue

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值