STM32实战总结:HAL之GPRS

2024-03-09 08:10
文章标签 实战 总结 stm32 hal gprs

本文主要是介绍STM32实战总结:HAL之GPRS,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

关于无线传输的基础知识,参考:

无线通信技术概览_路溪非溪的博客-CSDN博客

和wifi一样,GPRS现在也基本上是使用模组。不过GPRS不用和WiFi一样要输入SSID和密码,开机就会自动联网,所以使用起来更方便一些。但是GPRS要有手机卡,流量是要钱的。

GRPS的天线通常是外置的。

关于天线可参考:物联网天线|IoT天线|GPS天线|WiFi天线- 德宝通信

SIM8000C

SIM800C是一款四频GSM/GPRS模块,支持高达85.6kbps的GPRS数据传输。它具有强大的扩展能力和丰富的接口,包括UART、USB2.0、GPIO等。该模块为客户的应用提供了极大的灵活性和易于集成的能力。

更多参考:SIM800C

AT指令示例:

更多详细内容查看厂家给的模组使用手册,此处不再赘述。

关键代码

/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"/* Private define-------------------------------------------------------------*/
#define TCP_Server  (uint8_t*)"AT+CIPSTART=\"TCP\",\"115.29.109.104\",6511\r\n"  //Doit.am远程信息转发服务/* Private variables----------------------------------------------------------*/
static uint8_t SIM800C_Connect_Error_Flag = FALSE; //SIM800C联网错误标志位/* Private function prototypes------------------------------------------------*/
static void StartUp(void);             //启动SIM800C
static void TCP_Connect_Server(void);  //通过TCP连接服务器
static void Transfer_SHT30(void);      //传送SHT30的温湿度
static void Receive_Information(void); //接收信息
static void DMA_Receive_Set(void);     //DMA重新设置
static void Error(void);               //错误信息//内部函数
static void SendAT(uint8_t *,uint8_t *);            //发送AT指令static void Moudle_Sync_Baud(void);                 //同步波特率
static void Moudle_Check_SIM_Status(void);          //检查SIM卡状态
static void Moudle_Check_Network_Register(void);    //检查网络注册
static void Moudle_Check_Attach_GPRS_Service(void); //检查粘附GPRS网络
static void Moudle_BringUp_Wireless_Connect(void);  //建立无线链接
static void Moudle_StartUp_TCP_Connect(void);       //开始TCP连接/* Public variables-----------------------------------------------------------*/
SIM800C_t  SIM800C = 
{FALSE,TIMER6_10S,StartUp,TCP_Connect_Server,Transfer_SHT30,Receive_Information,DMA_Receive_Set,Error
};/** @name   StartUp* @brief  启动SIM800C* @param  None* @retval None      
*/
static void StartUp() 
{//如果模块处于开机状态,先关机if(READ_GPRS_STATUS == GPIO_PIN_SET){printf("The module of SIM800C shutdown!\r\n");//模块关机SET_GPRS_PWRKEY;HAL_Delay(1000);HAL_Delay(1000);HAL_Delay(1000);CLR_GPRS_PWRKEY;//等待模块关机完成Timer6.usDelay_Timer = 0;while(READ_GPRS_STATUS == GPIO_PIN_SET){if(Timer6.usMCU_Run_Timer >= TIMER6_10S){SIM800C.Error();break;}}//按手册提示,关机后迅速重启模块,至少延时800msHAL_Delay(1000);}//如果模块处于关机状态,进行开机if(READ_GPRS_STATUS == GPIO_PIN_RESET){printf("The module of SIM800C startup!\r\n");//模块开机SET_GPRS_PWRKEY;HAL_Delay(1000);HAL_Delay(1000);CLR_GPRS_PWRKEY;//等待模块开机完成Timer6.usDelay_Timer = 0;while(READ_GPRS_STATUS == GPIO_PIN_RESET){if(Timer6.usMCU_Run_Timer >= TIMER6_10S){SIM800C.Error();break;}}}
}/** @name   SendAT* @brief  发送AT指令* @param  AT_Command  -> 待发送的AT指令Respond_Str -> 回应数据中包含的字符串* @retval None      
*/
static void SendAT(uint8_t * AT_Command,uint8_t * Respond_Str)
{uint8_t* const  Ptr_AT_Command   = AT_Command;uint8_t* const  Ptr_Respond_Str  = Respond_Str;//DMA重新接收设置SIM800C.DMA_Receive_Set();//发送AT指令UART2.SendString(Ptr_AT_Command);	//打印信息printf("%s",Ptr_AT_Command);//等待模块回应数据,超时错误处理Timer6.usDelay_Timer = 0;while(strstr((const char*)UART2.pucRec_Buffer,"\r\n") == NULL){if(Timer6.usDelay_Timer > TIMER6_100mS){SIM800C.Error();break;}}//延时10ms,接收完全部字节HAL_Delay(10);//模块回应数据处理处理if(strstr((const char*)UART2.pucRec_Buffer,(const char*)Ptr_Respond_Str) == NULL){SIM800C.Error();}//打印信息printf("%s",UART2.pucRec_Buffer);
}/** @name   TCP_Connect_Server* @brief  通过TCP连接服务器* @param  None* @retval None      
*/
static void TCP_Connect_Server()
{__HAL_UART_DISABLE_IT(&huart2,UART_IT_IDLE);   //禁止串口2的空闲中断SIM800C.StartUp();                      //启动GPRS模块Moudle_Sync_Baud();                     //同步波特率SendAT(AT_CMD_ECHO_OFF,(uint8_t*)"OK"); //关闭回显Moudle_Check_SIM_Status();              //检查SIM卡状态SendAT(AT_CMD_CCID,(uint8_t*)"OK");     //显示ICCIDMoudle_Check_Network_Register();        //检查网络注册Moudle_Check_Attach_GPRS_Service();     //检查粘附GPRS网络SendAT(AT_CMD_CIPMODE,(uint8_t*)"OK");  //设置为透传模式SendAT(AT_CMD_CSTT,(uint8_t*)"OK");     //开始任务,设置APNMoudle_BringUp_Wireless_Connect();      //建立无线链接SendAT(AT_CMD_CIFSR,(uint8_t*)".");     //获取本地IP地址Moudle_StartUp_TCP_Connect();           //开始TCP连接SIM800C.DMA_Receive_Set();	            //DMA重新接收设置,开始接收TCP服务器的指令if(SIM800C.TCP_Connect_Status == TRUE)__HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);   //使能串口2的空闲中断
}/** @name   Moudle_Sync_Baud* @brief  同步波特率* @param  None * @retval None      
*/
static void Moudle_Sync_Baud()
{SIM800C_Connect_Error_Flag = FALSE;LED.LED_OFF(LED2);LED.LED_OFF(LED3);HAL_GPIO_WritePin(OUT_NPN_GPIO_Port,OUT_NPN_Pin,GPIO_PIN_RESET);Timer6.usDelay_Timer = 0;do{//DMA重新接收设置SIM800C.DMA_Receive_Set();//发送AT指令UART2.SendString(AT_CMD_AT);//打印信息printf("%s",AT_CMD_AT);//延时100ms,等待接收完成HAL_Delay(100);//打印信息printf("%s",UART2.pucRec_Buffer);//超时处理if(Timer6.usDelay_Timer >= TIMER6_10S){SIM800C.Error();break;}}while(strstr((const char*)UART2.pucRec_Buffer,"OK") == NULL);
}  /** @name   Moudle_Check_SIM_Status* @brief  检查SIM卡状态* @param  None * @retval None      
*/
static void Moudle_Check_SIM_Status()
{if(SIM800C_Connect_Error_Flag == FALSE){Timer6.usDelay_Timer = 0;do{//DMA重新接收设置SIM800C.DMA_Receive_Set();//发送AT指令UART2.SendString(AT_CMD_CPIN);//打印信息printf("%s",AT_CMD_CPIN);//延时1000ms,等待接收完成HAL_Delay(1000);//打印信息printf("%s",UART2.pucRec_Buffer);//超时处理if(Timer6.usDelay_Timer >= TIMER6_10S){SIM800C.Error();break;}}while(strstr((const char*)UART2.pucRec_Buffer,"OK") == NULL);}
}/** @name   Moudle_Check_Network_Register* @brief  检查网络注册* @param  None * @retval None      
*/
static void Moudle_Check_Network_Register()
{if(SIM800C_Connect_Error_Flag == FALSE){Timer6.usDelay_Timer = 0;while(1){//DMA重新接收设置SIM800C.DMA_Receive_Set();//发送AT指令UART2.SendString(AT_CMD_CREG);//打印信息printf("%s",AT_CMD_CREG);//延时100ms,等待接收完成HAL_Delay(100);		//打印信息printf("%s",UART2.pucRec_Buffer);//判断注册if((strstr((const char*)UART2.pucRec_Buffer,",1") != NULL) || (strstr((const char*)UART2.pucRec_Buffer,",5") != NULL)){break;}else{HAL_Delay(1000);HAL_Delay(1000);}//超时处理if(Timer6.usDelay_Timer >= TIMER6_2min){SIM800C.Error();break;}}}
}/** @name   Moudle_Check_Attach_GPRS_Service* @brief  建立无线链接* @param  None * @retval None      
*/
static void Moudle_Check_Attach_GPRS_Service()
{if(SIM800C_Connect_Error_Flag == FALSE){Timer6.usDelay_Timer = 0;while(1){//输出信号强度SendAT(AT_CMD_CSQ,(uint8_t*)"OK");//DMA重新接收设置SIM800C.DMA_Receive_Set();//发送AT指令UART2.SendString(AT_CMD_CGATT);//打印信息printf("%s",AT_CMD_CGATT);//延时100ms,等待接收完成HAL_Delay(100);		//打印信息printf("%s",UART2.pucRec_Buffer);//判断注册if(strstr((const char*)UART2.pucRec_Buffer,"+CGATT: 1") != NULL){break;}else{HAL_Delay(1000);HAL_Delay(1000);}//超时处理if(Timer6.usDelay_Timer >= TIMER6_2min){SIM800C.Error();break;}}}
}/** @name   Moudle_BringUp_Wireless_Connect* @brief  建立无线链接* @param  None * @retval None      
*/
static void Moudle_BringUp_Wireless_Connect()
{if(SIM800C_Connect_Error_Flag == FALSE){Timer6.usDelay_Timer = 0;while(1){//DMA重新接收设置SIM800C.DMA_Receive_Set();//发送AT指令UART2.SendString(AT_CMD_CIICR);//打印信息printf("%s",AT_CMD_CIICR);//延时100ms,等待接收完成HAL_Delay(100);		//打印信息printf("%s",UART2.pucRec_Buffer);//建立无线链接成功if(strstr((const char*)UART2.pucRec_Buffer,"OK") != NULL){LED.LED_ON(LED2);break;}//建立无线链接失败if(strstr((const char*)UART2.pucRec_Buffer,"ERROR") != NULL){SIM800C.Error();break;}//超时处理if(Timer6.usDelay_Timer >= TIMER6_85S){SIM800C.Error();break;}}}
}/** @name   Moudle_StartUp_TCP_Connect* @brief  开始TCP连接* @param  None * @retval None      
*/
static void Moudle_StartUp_TCP_Connect()
{if(SIM800C_Connect_Error_Flag == FALSE){printf("Connect TCP Server!\r\n");Timer6.usDelay_Timer = 0;while(1){//DMA重新接收设置SIM800C.DMA_Receive_Set();//发送AT指令UART2.SendString(TCP_Server);//打印信息printf("%s",TCP_Server);//等待模块返回数据while(Timer6.usDelay_Timer < TIMER6_160S){if((strstr((const char*)UART2.pucRec_Buffer,"CONNECT") != NULL) | (strstr((const char*)UART2.pucRec_Buffer,"FAIL") != NULL)){break;}}	//延时100ms,等待接收完成HAL_Delay(100);//打印信息printf("%s",UART2.pucRec_Buffer);//TCP服务器链接失败if(strstr((const char*)UART2.pucRec_Buffer,"FAIL") != NULL){printf("Connect TCP Server Failure!\r\n");SIM800C.TCP_Reconnect_Timer = 0;SIM800C.Error();break;}//TCP服务器链接成功if(strstr((const char*)UART2.pucRec_Buffer,"CONNECT") != NULL){printf("Connect TCP Server Success!\r\n");SIM800C.TCP_Connect_Status  = TRUE;SIM800C.TCP_Reconnect_Timer = 0;LED.LED_ON(LED3);break;}//超时处理if(Timer6.usDelay_Timer >= TIMER6_160S){SIM800C.TCP_Reconnect_Timer = 0;SIM800C.Error();break;}}}
}/** @name 	Transfer_SHT30* @brief	传送SHT30的温湿度* @param	NONE* @retval None			
*/
static void Transfer_SHT30()
{float 	 Temp_float = 0;uint16_t Temp_uint16 = 0;//温度值  -40至125℃,精度0.1℃if(SHT30.fTemperature < 0){Temp_float = 0 - SHT30.fTemperature;*(UART2.pucSend_Buffer + 0) = '-';}else{Temp_float = SHT30.fTemperature;*(UART2.pucSend_Buffer + 0) = ' ';}Temp_uint16 = (uint16_t)(Temp_float*10);if(Temp_uint16 < 10) //0.x{*(UART2.pucSend_Buffer + 1) = ' ';*(UART2.pucSend_Buffer + 2) = ' ';*(UART2.pucSend_Buffer + 3) = '0';*(UART2.pucSend_Buffer + 4) = '.';*(UART2.pucSend_Buffer + 5) = Temp_uint16 + '0';}else if(Temp_uint16 < 100)//x.x{*(UART2.pucSend_Buffer + 1) = ' ';*(UART2.pucSend_Buffer + 2) = ' ';*(UART2.pucSend_Buffer + 3) = Temp_uint16/10 + '0';*(UART2.pucSend_Buffer + 4) = '.';*(UART2.pucSend_Buffer + 5) = Temp_uint16%10 + '0';}else if(Temp_uint16 < 1000)//xx.x{*(UART2.pucSend_Buffer + 1) = ' ';*(UART2.pucSend_Buffer + 2) = Temp_uint16/100 + '0';*(UART2.pucSend_Buffer + 3) = Temp_uint16%100/10 + '0';*(UART2.pucSend_Buffer + 4) = '.';*(UART2.pucSend_Buffer + 5) = Temp_uint16%10 + '0';}else//xxx.x{*(UART2.pucSend_Buffer + 1) = Temp_uint16/1000 + '0';*(UART2.pucSend_Buffer + 2) = Temp_uint16%1000/100 + '0';*(UART2.pucSend_Buffer + 3) = Temp_uint16%100/10 + '0';*(UART2.pucSend_Buffer + 4) = '.';*(UART2.pucSend_Buffer + 5) = Temp_uint16%10 + '0';}//数据传送UART2.SendString((uint8_t *)"The Temperature of SHT30 is ");HAL_Delay(3);  //延时,等待字符串发送完	 时间 = (11*1000ms)/115200 * 28 = 2.68msUART2.SendArray(UART2.pucSend_Buffer,6);HAL_Delay(1);  //延时,等待数组发送完 		时间 = (11*1000ms)/115200 * 6 = 0.58msUART2.SendString((uint8_t *)"℃\r\n");HAL_Delay(1);  //延时,等待字符串发送完	 时间 = (11*1000ms)/115200 * 4 = 0.39ms//湿度值 0 - 100%RH,精度1%RHif(SHT30.ucHumidity < 10){*(UART2.pucSend_Buffer + 0) = ' ';*(UART2.pucSend_Buffer + 1) = SHT30.ucHumidity + '0';}else{*(UART2.pucSend_Buffer + 0) = SHT30.ucHumidity/10 + '0';*(UART2.pucSend_Buffer + 1) = SHT30.ucHumidity%10 + '0';}*(UART2.pucSend_Buffer + 2) = '%';*(UART2.pucSend_Buffer + 3) = 'R';*(UART2.pucSend_Buffer + 4) = 'H';//数据传送UART2.SendString((uint8_t *)"The Humidity of SHT30 is ");HAL_Delay(3);  //延时,等待字符串发送完	 时间 = (11*1000ms)/115200 * 25 = 2.39msUART2.SendArray(UART2.pucSend_Buffer,5);
}/** @name 	Receive_Information* @brief	接收信息* @param	None * @retval None			
*/
static void Receive_Information()
{ if(SIM800C.TCP_Connect_Status == TRUE){printf("Received information from the TCP server\r\n");printf("%s",UART2.pucRec_Buffer);printf("\r\n");//切换继电器状态if(strstr((const char*)UART2.pucRec_Buffer,"Flip Relay") != NULL){Relay.Relay_Flip();}if(strstr((const char*)UART2.pucRec_Buffer,"Flip Buzzer") != NULL){if(Buzzer.Status == Buzzer_Status_OFF){Buzzer.ON();}else{Buzzer.OFF();}}//DMA重新接收设置,接收TCP服务器的新指令SIM800C.DMA_Receive_Set();}
}/** @name 	DMA_Receive_Set* @brief	DMA接收设置* @param	None * @retval None			
*/
static void DMA_Receive_Set(void)
{//串口2禁止DMA接收HAL_UART_DMAStop(&huart2);//清缓存Public.Memory_Clr(UART2.pucRec_Buffer,strlen((const char*)UART2.pucRec_Buffer));		//串口2开启DMA接收HAL_UART_Receive_DMA(&huart2,UART2.pucRec_Buffer,UART2_Rec_LENGTH);
}/** @name 	Error* @brief	错误信息* @param	None * @retval None			
*/
static void Error()
{SIM800C_Connect_Error_Flag	= TRUE;SIM800C.TCP_Reconnect_Timer = 0;HAL_GPIO_WritePin(OUT_NPN_GPIO_Port,OUT_NPN_Pin,GPIO_PIN_SET);
}
/*************************************End Of File
*************************************/

这篇关于STM32实战总结:HAL之GPRS的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/790052

相关文章

精选20个好玩又实用的的Python实战项目(有图文代码)

《精选20个好玩又实用的的Python实战项目(有图文代码)》文章介绍了20个实用Python项目,涵盖游戏开发、工具应用、图像处理、机器学习等,使用Tkinter、PIL、OpenCV、Kivy等库... 目录① 猜字游戏② 闹钟③ 骰子模拟器④ 二维码⑤ 语言检测⑥ 加密和解密⑦ URL缩短⑧ 音乐播放

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)

《java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)》:本文主要介绍java中pdf模版填充表单踩坑的相关资料,OpenPDF、iText、PDFBox是三... 目录准备Pdf模版方法1:itextpdf7填充表单(1)加入依赖(2)代码(3)遇到的问题方法2:pd

PyTorch中的词嵌入层(nn.Embedding)详解与实战应用示例

《PyTorch中的词嵌入层(nn.Embedding)详解与实战应用示例》词嵌入解决NLP维度灾难,捕捉语义关系,PyTorch的nn.Embedding模块提供灵活实现,支持参数配置、预训练及变长... 目录一、词嵌入(Word Embedding)简介为什么需要词嵌入?二、PyTorch中的nn.Em

在IntelliJ IDEA中高效运行与调试Spring Boot项目的实战步骤

《在IntelliJIDEA中高效运行与调试SpringBoot项目的实战步骤》本章详解SpringBoot项目导入IntelliJIDEA的流程,教授运行与调试技巧,包括断点设置与变量查看,奠定... 目录引言:为良驹配上好鞍一、为何选择IntelliJ IDEA?二、实战:导入并运行你的第一个项目步骤1

Spring Boot3.0新特性全面解析与应用实战

《SpringBoot3.0新特性全面解析与应用实战》SpringBoot3.0作为Spring生态系统的一个重要里程碑,带来了众多令人兴奋的新特性和改进,本文将深入解析SpringBoot3.0的... 目录核心变化概览Java版本要求提升迁移至Jakarta EE重要新特性详解1. Native Ima

Spring Boot 与微服务入门实战详细总结

《SpringBoot与微服务入门实战详细总结》本文讲解SpringBoot框架的核心特性如快速构建、自动配置、零XML与微服务架构的定义、演进及优缺点,涵盖开发环境准备和HelloWorld实战... 目录一、Spring Boot 核心概述二、微服务架构详解1. 微服务的定义与演进2. 微服务的优缺点三

SpringBoot集成MyBatis实现SQL拦截器的实战指南

《SpringBoot集成MyBatis实现SQL拦截器的实战指南》这篇文章主要为大家详细介绍了SpringBoot集成MyBatis实现SQL拦截器的相关知识,文中的示例代码讲解详细,有需要的小伙伴... 目录一、为什么需要SQL拦截器?二、MyBATis拦截器基础2.1 核心接口:Interceptor

从入门到进阶讲解Python自动化Playwright实战指南

《从入门到进阶讲解Python自动化Playwright实战指南》Playwright是针对Python语言的纯自动化工具,它可以通过单个API自动执行Chromium,Firefox和WebKit... 目录Playwright 简介核心优势安装步骤观点与案例结合Playwright 核心功能从零开始学习

Java docx4j高效处理Word文档的实战指南

《Javadocx4j高效处理Word文档的实战指南》对于需要在Java应用程序中生成、修改或处理Word文档的开发者来说,docx4j是一个强大而专业的选择,下面我们就来看看docx4j的具体使用... 目录引言一、环境准备与基础配置1.1 Maven依赖配置1.2 初始化测试类二、增强版文档操作示例2.