您好,
会员登录 快速注册
退出 ( 条未读消息)
关于本站 意见反馈 首页

公告:小宅博客网可以开发票了,需要发票的,去群里找群主哈!!
全部文章分类
  • 人工智能 >

  • 编程语言 >

  • WPF系列 >

  • ASP.NET系列 >

  • Linux >

  • 数据库 >

  • 嵌入式 >

  • WEB技术 >

  • PLC系列 >

  • 微服务与框架 >

  • 小宅DIY >

  • 学习资料 >

OpenCv基础 ANN车牌识别 yolov5车牌识别 指针式仪表识别 ROS系列 YOLO Halcon Detectron2 昇腾AI ChatGPT在线体验 英伟达JETSON ChatGLM ChatTTS FunASR 地平线 ByteTrack 魔搭社区 LangChain
C C# C++ Python Java Go
WPF
ASP.NET小功能 GPS定位系统-MVC GPS定位系统-VUE ASP.NET WebRTC
Linux Linux内核 Shell MakeFile
MySql SqlServer Oracle
STM8 STM32 51单片机
VUE入门 HTML JavaScript CSS layui镜像网站 ElementUi中文官网 element-plus 图标
三菱 欧姆龙 西门子 施耐德 松下 台达
IOTSharp IOTGateway ABP FRAMEWORK Docker
亚克力音响 编程仙途:智驭万法
面试题与技巧 Python入门技能树 微软C#教程
首页 编程之美 工具下载 全国就业 流量地图 文心一言
GPS定位系统-MVC
.NET6.0 GPS定位系统介绍(物联网) 系列源码下载 1、新建.net core web工程 2、添加自定义登录页面 3、添加百度地图页面 4、添加后台日志系统 5、添加mysql数据存储 6、添加SqlServer数据存储(额外内容) 7、用户注册与登录功能实现 8、添加坐标报表页面(用于遍历地图坐标) 9、前后端数据交互与报表数据展示 10、报表数据的编辑与修改 11、用户登录与退出 12、自定义GPRS通讯协议 13、添加TCP通讯功能(接收) 14、添加TCP通讯功能(发送) 15、模拟GPRS数据通讯 16、设备链接状态检测与提示 17、新建Windows Server虚拟机 18、服务器IIS运行环境配置 19、服务器.net程序发布 20、关于如何配置.net3.1框架 21、关于如何配置.net5.0框架 22、WinForm版地图上位机(带数据库和TCP功能) 23、WPF版地图上位机(带数据库和TCP功能) 24、公网映射与外网通讯 25、GPS协议与AT命令流程说明 26、GPRS协议与AT命令流程说明 27、STM32、A9G硬件连接图 28、STM32开发环境搭建 29、STM32 GPS/GPRS通讯功能实现 30、STM32 GPS定位数据上报服务器 31、室外最终效果演示 32、结束语
28、STM32开发环境搭建
30、STM32 GPS定位数据上报服务器
激萌の小宅 小宅博客网 GPS定位系统-MVC

文章作者:激萌の小宅

促销:¥0

价格:¥0

配送方式: 购买后立即生效(如购买异常,请联系站长)
付款之后一定要等待自动跳转结束,否则购买可能会失败
  • 0 天

    有效期

  • 0

    总销量

  • 0

    累计评价

STM32 GPS/GPRS通讯功能实现 - (第二十九讲)

视频讲解如下:


工程源码下载:GPS定位系统系列教程源码下载


工程源码中,A9G.c 文件的源代码如下,具体的工程源码,可直接去上面的链接下载。

#include <string.h>
#include <stdlib.h>
#include "delay.h"
#include "stdio.h"
#include "usart3.h"
#include "A9G.h"
#include "GpsCoord.h"

char A9G_Receive[700]={0}; // AT当前命令的反馈数据

// 等待A9G启动
void A9G_Start(void)
{
  u8 GpsBuff[700]=""; // 开辟一点空间,用来读取串口数据,经过测试,GPS单次数据包最大有547个字节,我这里直接开辟300字节的缓存空间
  int siz = 0;
  
  while(1) // 如果检测不通过,是不能退出循环的,只能重启设备
  {
    delay_ms(500); // 等待500ms,给串口中断留一些数据接收的时间
    siz = 0;
    memset(GpsBuff,0,sizeof(GpsBuff)); // 清空缓存数据
    siz = usart3_Receive(GpsBuff, sizeof(GpsBuff)); // 接收串口数据
    if(siz <= 0) continue; 
    
    // 解析串口数据,如果A9G模块启动完成,串口应该是能接收到带有“”字符的字符串的
    // 相当于下位机模拟器中 ComReadData()函数里面的 “A9G复位信息检测”代码
    if(strstr((char *)GpsBuff,"NO SIM CARD") != 0)
    {   
       printf("未检测到SIM卡...\r\n");
    }
    if(strstr((char *)GpsBuff,"+CREG:") != 0)
    {   
      printf("A9G启动成功...\r\n");
      break;
    }
  }
}

// 通用AT命令发送接口
// Order:需要发送的命令
// succeed:该命令对应的正确反馈
// oTime:等待超时时间(秒)
// 成功返回0,失败返回-1
int SendAT(char *Order, char *succeed, int oTime)
{
  int i = 0;
  int siz = 0;
  // 发送AT命令
  printf("发送:%s\r\n", Order);
  usart3_Send((u8 *)Order,strlen(Order));
  
  // 等待接收,超时时间:oTime(秒)
  for(i = 0;i < oTime * 5; i++)
  {
    delay_ms(200); // 等待200ms,给串口中断留一些数据接收的时间
    memset(A9G_Receive,0,sizeof(A9G_Receive)); // 清空缓存数据
    siz = usart3_Receive((u8 *)A9G_Receive, sizeof(A9G_Receive)); // 接收串口数据
    if(siz <= 0) continue; 
    printf("接收:%s\r\n", A9G_Receive);
    // 解析串口数据,如果接收到指定的字符串了,则认为命令发送成功了
    if(strstr((char *)A9G_Receive,(char *)succeed) != 0)
    {   
       // 接收关键字符串了,退出检测代码,继续执行下一步
      return 0;
    }
  }
  return -1;
}

// 初始化GPS
void A9G_Init_GPS(void)
{
  int order = 0; // 下发命令跳转控制
  while(1) // 如果配置不通过,是不能退出循环的,只能重启设备
  {
    delay_ms(500); // 每次命令,间隔500ms,也不知道A9G能支持多快的命令速度,我这里直接按500ms一个命令的速度进行下发,同时也给串口中断留一些数据接收的时间
    
    // 通过switch的方式来控制每次需要下发哪种命令
    switch(order)
    {
      case 0: // 设置为GPS模式(AT+GPSMD=1)/GPS+BD模式(AT+GPSMD=2),命令反馈3秒超时
        if(SendAT("AT+GPSMD=2\r\n", "OK", 3) == 0) {
          order++; // 命令下发成功,继续下一个命令
        }
        break;
        
      case 1: // 设置GPS每三秒输出一次定位信息,命令反馈3秒超时,也不要太快,给程序留点处理数据的时间
        if(SendAT("AT+GPSRD=3\r\n", "OK", 3) == 0) {
          return;// GPS初始化完成
        }
        break;
        
      default: break;
    } 
  }
}

// 启动GPS
void A9G_Start_GPS(void)
{
  while(1) // 如果启动不通过,是不能退出循环的,只能重启设备
  {
    printf("启动GPS...\r\n");
    delay_ms(1000);
    if(SendAT("AT+GPS=1\r\n", "OK", 3) == 0) {
      break;
    }
  }
}

// 停止GPS
void A9G_Stop_GPS(void)
{
  while(1)  // 如果停止不通过,是不能退出循环的,只能重启设备
  {
    printf("停止GPS...\r\n");
    delay_ms(1000);
    if(SendAT("AT+GPS=0\r\n", "OK", 3) == 0) {
      break;
    }
  }
}

// 初始化GPRS
// IP:服务器公网IP
// port:服务器公网端口
void A9G_Init_GPRS(char IP[30], char port[30])
{
  char CIPSTART[255]= "AT+CIPSTART=\"TCP\",\"";
  char str1[30]="\",";
  char str2[30]="\r\n";
  int order = 0; // 下发命令跳转控制
  
  strcat(CIPSTART, IP);
  strcat(CIPSTART, str1);
  strcat(CIPSTART, port);
  strcat(CIPSTART, str2);
  
  printf("GPS Server:%s\r\n", CIPSTART);

  while (1)
  {
      delay_ms(500); // 每次命令,间隔500ms,也不知道A9G能支持多快的命令速度,我这里直接按500ms一个命令的速度进行下发,同时也给串口中断留一些数据接收的时间
      switch (order)
      {
          case 0: // 查询SIM ,序列号唯一,可以用来判断卡是否正常
              if (SendAT("AT+CCID\r\n", "OK", 3) == 0)
              {
                  order++; // 命令下发成功,继续下一个命令
              }
              break;

          case 1: // 第一个参数1表示允许注册入网;第二个参数5表示已注册,处于漫游状态,如果是1的话,表示已注册本地网络,出现其他参数表示不正常
              if (SendAT("AT+CREG?\r\n", "+CREG: 1,1", 3) == 0)
              {
                  order++; // 命令下发成功,继续下一个命令
              }
              break;

          case 2: // 查询信号强度 第一个参数为信号强度值,
              if (SendAT("AT+CSQ\r\n", "OK", 5) == 0)
              { 
                // 在这里可以将 A9G_Receive 中的信号强度数据解析出来,C语言写这个太麻烦了,我就不写了,解析思路可以参考模拟器中的算法。。。。
                printf("%s\r\n",A9G_Receive);
                order++; // 命令下发成功,继续下一个命令
              }
              break;

          case 3: // 附着网络,如果需要上网,这条指令是必选的
              if (SendAT("AT+CGATT=1\r\n", "OK", 3) == 0)
              {
                  order++; // 命令下发成功,继续下一个命令
              }
              break;

          case 4: // 设置PDP参数
              if (SendAT("AT+CGDCONT=1,\"IP\",\"CMNET\"\r\n", "OK", 3) == 0)
              {
                  order++; // 命令下发成功,继续下一个命令
              }
              break;

          case 5: // 激活PDP,正确激活以后就可以上网了
              if (SendAT("AT+CGACT=1,1\r\n", "OK", 3) == 0)
              {
                  order++; // 命令下发成功,继续下一个命令
              }
              break;

          case 6: // 连接TCP服务器
              if (SendAT(CIPSTART, "CONNECT OK", 3) == 0)
              {
                  order++; // 命令下发成功,继续下一个命令
              }
              break;

          case 7: 
              // 查询透传默认参数
              if (SendAT("AT+CIPHMODE=1\r\n", "OK", 3) == 0)
              {
                  printf("GPRS初始化完成!\r\n");
                  return;// GPRS所有设置完成,退出
              }
              break;

          default: break;
      }
  }
}

// 启动GPRS
void A9G_Start_GPRS(void)
{
  while(1) // 这里的逻辑和模拟器还是有些差异的,模拟器是手动控制命令下发,所以不需要循环,但是下位机是自动的,如果命令不成功,只能不停的尝试,或者重启设备
  {
    printf("启动GPRS...\r\n");
    delay_ms(1000);
    if(SendAT("AT+CIPTMODE=1\r\n", "OK", 3) == 0) {
      printf("启动GPRS...OK\r\n");
      break;
    }
  }
}
// 停止GPRS
void A9G_Stop_GPRS(void)
{
  // 停止命令有点奇葩,只有第一次的时候会返回OK,第二次的时候就没有OK了,所以这里不能用循环,只能祈祷停止命令一次性发送成功吧~~
  printf("停止GPRS...\r\n");
  if (SendAT("+++", "OK", 3) == 0)
  {
      printf("停止GPRS...OK\r\n");
  }
  else
  {
      printf("停止GPRS...Error\r\n");
  }
}


A9G.h 文件的源代码如下:

#ifndef __A9G_H_
#define __A9G_H_	

#include "sys.h"
 
void A9G_Start(void);
void A9G_Init_GPS(void);
void A9G_Start_GPS(void);
void A9G_Stop_GPS(void);
 
void A9G_Init_GPRS(char IP[30], char port[30]);
void A9G_Start_GPRS(void);
void A9G_Stop_GPRS(void);


#endif


28、STM32开发环境搭建
30、STM32 GPS定位数据上报服务器

友情链接: CSDN激萌の小宅 95知识库 自考题库 罗分明个人网络博客 精益编程leanboot

小宅博客  www.bilibili996.com All Rights Reserved. 备案号: 闽ICP备2024034575号

网站经营许可证  福建省福州市 Copyright©2021-2025 版权所有

小宅博客
首页 智能家居 地图定位
公告:小宅博客网可以开发票了,需要发票的,去群里找群主哈!!

文章作者:激萌の小宅

促销:¥0

价格:¥0

配送方式: 购买后立即生效(如购买异常,请联系站长)
付款之后一定要等待自动跳转结束,否则购买可能会失败
  • 0 天

    有效期

  • 0

    总销量

  • 0

    累计评价

STM32 GPS/GPRS通讯功能实现 - (第二十九讲)

视频讲解如下:


工程源码下载:GPS定位系统系列教程源码下载


工程源码中,A9G.c 文件的源代码如下,具体的工程源码,可直接去上面的链接下载。

#include <string.h>
#include <stdlib.h>
#include "delay.h"
#include "stdio.h"
#include "usart3.h"
#include "A9G.h"
#include "GpsCoord.h"

char A9G_Receive[700]={0}; // AT当前命令的反馈数据

// 等待A9G启动
void A9G_Start(void)
{
  u8 GpsBuff[700]=""; // 开辟一点空间,用来读取串口数据,经过测试,GPS单次数据包最大有547个字节,我这里直接开辟300字节的缓存空间
  int siz = 0;
  
  while(1) // 如果检测不通过,是不能退出循环的,只能重启设备
  {
    delay_ms(500); // 等待500ms,给串口中断留一些数据接收的时间
    siz = 0;
    memset(GpsBuff,0,sizeof(GpsBuff)); // 清空缓存数据
    siz = usart3_Receive(GpsBuff, sizeof(GpsBuff)); // 接收串口数据
    if(siz <= 0) continue; 
    
    // 解析串口数据,如果A9G模块启动完成,串口应该是能接收到带有“”字符的字符串的
    // 相当于下位机模拟器中 ComReadData()函数里面的 “A9G复位信息检测”代码
    if(strstr((char *)GpsBuff,"NO SIM CARD") != 0)
    {   
       printf("未检测到SIM卡...\r\n");
    }
    if(strstr((char *)GpsBuff,"+CREG:") != 0)
    {   
      printf("A9G启动成功...\r\n");
      break;
    }
  }
}

// 通用AT命令发送接口
// Order:需要发送的命令
// succeed:该命令对应的正确反馈
// oTime:等待超时时间(秒)
// 成功返回0,失败返回-1
int SendAT(char *Order, char *succeed, int oTime)
{
  int i = 0;
  int siz = 0;
  // 发送AT命令
  printf("发送:%s\r\n", Order);
  usart3_Send((u8 *)Order,strlen(Order));
  
  // 等待接收,超时时间:oTime(秒)
  for(i = 0;i < oTime * 5; i++)
  {
    delay_ms(200); // 等待200ms,给串口中断留一些数据接收的时间
    memset(A9G_Receive,0,sizeof(A9G_Receive)); // 清空缓存数据
    siz = usart3_Receive((u8 *)A9G_Receive, sizeof(A9G_Receive)); // 接收串口数据
    if(siz <= 0) continue; 
    printf("接收:%s\r\n", A9G_Receive);
    // 解析串口数据,如果接收到指定的字符串了,则认为命令发送成功了
    if(strstr((char *)A9G_Receive,(char *)succeed) != 0)
    {   
       // 接收关键字符串了,退出检测代码,继续执行下一步
      return 0;
    }
  }
  return -1;
}

// 初始化GPS
void A9G_Init_GPS(void)
{
  int order = 0; // 下发命令跳转控制
  while(1) // 如果配置不通过,是不能退出循环的,只能重启设备
  {
    delay_ms(500); // 每次命令,间隔500ms,也不知道A9G能支持多快的命令速度,我这里直接按500ms一个命令的速度进行下发,同时也给串口中断留一些数据接收的时间
    
    // 通过switch的方式来控制每次需要下发哪种命令
    switch(order)
    {
      case 0: // 设置为GPS模式(AT+GPSMD=1)/GPS+BD模式(AT+GPSMD=2),命令反馈3秒超时
        if(SendAT("AT+GPSMD=2\r\n", "OK", 3) == 0) {
          order++; // 命令下发成功,继续下一个命令
        }
        break;
        
      case 1: // 设置GPS每三秒输出一次定位信息,命令反馈3秒超时,也不要太快,给程序留点处理数据的时间
        if(SendAT("AT+GPSRD=3\r\n", "OK", 3) == 0) {
          return;// GPS初始化完成
        }
        break;
        
      default: break;
    } 
  }
}

// 启动GPS
void A9G_Start_GPS(void)
{
  while(1) // 如果启动不通过,是不能退出循环的,只能重启设备
  {
    printf("启动GPS...\r\n");
    delay_ms(1000);
    if(SendAT("AT+GPS=1\r\n", "OK", 3) == 0) {
      break;
    }
  }
}

// 停止GPS
void A9G_Stop_GPS(void)
{
  while(1)  // 如果停止不通过,是不能退出循环的,只能重启设备
  {
    printf("停止GPS...\r\n");
    delay_ms(1000);
    if(SendAT("AT+GPS=0\r\n", "OK", 3) == 0) {
      break;
    }
  }
}

// 初始化GPRS
// IP:服务器公网IP
// port:服务器公网端口
void A9G_Init_GPRS(char IP[30], char port[30])
{
  char CIPSTART[255]= "AT+CIPSTART=\"TCP\",\"";
  char str1[30]="\",";
  char str2[30]="\r\n";
  int order = 0; // 下发命令跳转控制
  
  strcat(CIPSTART, IP);
  strcat(CIPSTART, str1);
  strcat(CIPSTART, port);
  strcat(CIPSTART, str2);
  
  printf("GPS Server:%s\r\n", CIPSTART);

  while (1)
  {
      delay_ms(500); // 每次命令,间隔500ms,也不知道A9G能支持多快的命令速度,我这里直接按500ms一个命令的速度进行下发,同时也给串口中断留一些数据接收的时间
      switch (order)
      {
          case 0: // 查询SIM ,序列号唯一,可以用来判断卡是否正常
              if (SendAT("AT+CCID\r\n", "OK", 3) == 0)
              {
                  order++; // 命令下发成功,继续下一个命令
              }
              break;

          case 1: // 第一个参数1表示允许注册入网;第二个参数5表示已注册,处于漫游状态,如果是1的话,表示已注册本地网络,出现其他参数表示不正常
              if (SendAT("AT+CREG?\r\n", "+CREG: 1,1", 3) == 0)
              {
                  order++; // 命令下发成功,继续下一个命令
              }
              break;

          case 2: // 查询信号强度 第一个参数为信号强度值,
              if (SendAT("AT+CSQ\r\n", "OK", 5) == 0)
              { 
                // 在这里可以将 A9G_Receive 中的信号强度数据解析出来,C语言写这个太麻烦了,我就不写了,解析思路可以参考模拟器中的算法。。。。
                printf("%s\r\n",A9G_Receive);
                order++; // 命令下发成功,继续下一个命令
              }
              break;

          case 3: // 附着网络,如果需要上网,这条指令是必选的
              if (SendAT("AT+CGATT=1\r\n", "OK", 3) == 0)
              {
                  order++; // 命令下发成功,继续下一个命令
              }
              break;

          case 4: // 设置PDP参数
              if (SendAT("AT+CGDCONT=1,\"IP\",\"CMNET\"\r\n", "OK", 3) == 0)
              {
                  order++; // 命令下发成功,继续下一个命令
              }
              break;

          case 5: // 激活PDP,正确激活以后就可以上网了
              if (SendAT("AT+CGACT=1,1\r\n", "OK", 3) == 0)
              {
                  order++; // 命令下发成功,继续下一个命令
              }
              break;

          case 6: // 连接TCP服务器
              if (SendAT(CIPSTART, "CONNECT OK", 3) == 0)
              {
                  order++; // 命令下发成功,继续下一个命令
              }
              break;

          case 7: 
              // 查询透传默认参数
              if (SendAT("AT+CIPHMODE=1\r\n", "OK", 3) == 0)
              {
                  printf("GPRS初始化完成!\r\n");
                  return;// GPRS所有设置完成,退出
              }
              break;

          default: break;
      }
  }
}

// 启动GPRS
void A9G_Start_GPRS(void)
{
  while(1) // 这里的逻辑和模拟器还是有些差异的,模拟器是手动控制命令下发,所以不需要循环,但是下位机是自动的,如果命令不成功,只能不停的尝试,或者重启设备
  {
    printf("启动GPRS...\r\n");
    delay_ms(1000);
    if(SendAT("AT+CIPTMODE=1\r\n", "OK", 3) == 0) {
      printf("启动GPRS...OK\r\n");
      break;
    }
  }
}
// 停止GPRS
void A9G_Stop_GPRS(void)
{
  // 停止命令有点奇葩,只有第一次的时候会返回OK,第二次的时候就没有OK了,所以这里不能用循环,只能祈祷停止命令一次性发送成功吧~~
  printf("停止GPRS...\r\n");
  if (SendAT("+++", "OK", 3) == 0)
  {
      printf("停止GPRS...OK\r\n");
  }
  else
  {
      printf("停止GPRS...Error\r\n");
  }
}


A9G.h 文件的源代码如下:

#ifndef __A9G_H_
#define __A9G_H_	

#include "sys.h"
 
void A9G_Start(void);
void A9G_Init_GPS(void);
void A9G_Start_GPS(void);
void A9G_Stop_GPS(void);
 
void A9G_Init_GPRS(char IP[30], char port[30]);
void A9G_Start_GPRS(void);
void A9G_Stop_GPRS(void);


#endif