STM32——GPS模块(GY-NEO-6M)

news2024/11/16 7:51:33

1连接

1-1

使用 USB-TTL 工具,安装好驱动,可以在”设备管理器看到对应COM”按照如下链接测试模块: USB-TTL GPS 模块

3.3V--------------------------------->VCC

GND------------------------------>GND

RXD------------------------------>TXD

TXD------------------------------>RXD

1-2

GPS 模块                                    单片机

VCC----------------------------------- VCC(必须接)

GND-----------------------------------GND(必须接)

TXD-----------------------------------RXD(必须接)

RXD-----------------------------------TXD(可不接)

PPS------------------------------------某个 IO(可不接)

2指令

介绍

NMEA 0183是美国国家海洋电子协会(National Marine Electronics Association)为海用电子设备 制定的标准格式。目前业已成了GPS导航设备统一的RTCM(Radio Technical Commission for Maritime services)标准协议。 NMEA-0183协议采用ASCII码来传递GPS定位信息,我们称之为帧。 帧格式形如:$aaccc,ddd,ddd,…,ddd*hh(CR)(LF) 1、“$”:帧命令起始位 2、aaccc:地址域,前两位为识别符(aa),后三位为语句名(ccc) 3、ddd…ddd:数据 4、“*”:校验和前缀(也可以作为语句数据结束的标志) 5、hh:校验和(check sum),$与*之间所有字符ASCII码的校验和(各字节做异或运算,得到 校验和后,再转换16进制格式的ASCII字符) 6、(CR)(LF):帧结束,回车和换行符

 
3.2 指令讲解

 
3.2 指令讲解 

1,$GPGGA(GPS定位信息,Global Positioning System Fix Data) 
$GPGGA语句的基本格式如下(其中M指单位M,hh指校验和,CR和LF代表回车换行,下同): 
$GPGGA,(1),(2),(3),(4),(5),(6),(7),(8),(9),M,(10),M,(11),(12)*hh(CR)(LF) 
(1)UTC时间,格式为hhmmss.ss; 
(2)纬度,格式为ddmm.mmmmm(度分格式); 
(3)纬度半球,N或S(北纬或南纬); 
(4)经度,格式为dddmm.mmmmm(度分格式); 
(5)经度半球,E或W(东经或西经); 
(6)GPS状态,0=未定位,1=非差分定位,2=差分定位; 
(7)正在使用的用于定位的卫星数量(00~12) 
(8)HDOP水平精确度因子(0.5~99.9) 
(9)海拔高度(-9999.9到9999.9米) 
(10)大地水准面高度(-9999.9到9999.9米) 
(11)差分时间(从最近一次接收到差分信号开始的秒数,非差分定位,此项为空) 
(12)差分参考基站标号(0000到1023,首位0也将传送,非差分定位,此项为空) 
举例如下: 
$GPGGA,023543.00,2308.28715,N,11322.09875,E,1,06,1.49,41.6,M,-5.3,M,,*7D 
 

2,$GPGSA(当前卫星信息) 
$GPGSA语句的基本格式如下: 
$GPGSA,(1),(2),(3),(3),(3),(3),(3),(3),(3),(3),(3),(3),(3),(3),(4),(5),(6)*hh(CR)(LF) 
(1) 模式,M = 手动,A = 自动。 
(2) 定位类型,1=未定位,2=2D定位,3=3D定位。 
(3) 正在用于定位的卫星号(01~32) 
(4)  PDOP综合位置精度因子(0.5-99.9) 
(5) HDOP水平精度因子1(0.5-99.9) 
(6) VDOP垂直精度因子(0.5-99.9) 
举例如下: 
$GPGSA,A,3,26,02,05,29,15,21,,,,,,,2.45,1.49,1.94*0E 
注1:精度因子值越小,则准确度越高。 

3,$GPGSV(可见卫星数,GPS Satellites in View) 
$GPGSV语句的基本格式如下: 
$GPGSV, (1),(2),(3),(4),(5),(6),(7),...,(4),(5),(6),(7)*hh(CR)(LF) 
(1)  GSV语句总数。 
(2)  本句GSV的编号。 
(3)  可见卫星的总数(00~12,前面的0也将被传输)。 
(4)  卫星编号(01~32,前面的0也将被传输)。 
(5)  卫星仰角(00~90度,前面的0也将被传输)。 
(6)  卫星方位角(000~359度,前面的0也将被传输) 
(7)  信噪比(00~99dB,没有跟踪到卫星时为空)。 
注:每条GSV语句最多包括四颗卫星的信息,其他卫星的信息将在下一条$GPGSV语句中输出。 
举例如下: 
$GPGSV,3,1,12,02,39,117,25,04,02,127,,05,40,036,24,08,10,052,*7E 
$GPGSV,3,2,12,09,35,133,,10,01,073,,15,72,240,22,18,05,274,*7B 
$GPGSV,3,3,12,21,10,316,31,24,16,176,,26,65,035,42,29,46,277,18*7A 

4,$GPRMC(推荐定位信息,Recommended Minimum Specific GPS/Transit Data) 
$GPRMC语句的基本格式如下: 
$GPRMC,(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)*hh(CR)(LF) 
(1) UTC时间,hhmmss(时分秒) 
(2) 定位状态,A=有效定位,V=无效定位 
(3) 纬度ddmm.mmmmm(度分) 
(4) 纬度半球N(北半球)或S(南半球) 
(5) 经度dddmm.mmmmm(度分) 
(6) 经度半球E(东经)或W(西经) 
(7) 地面速率(000.0~999.9节) 
(8) 地面航向(000.0~359.9度,以真北方为参考基准) 
(9) UTC日期,ddmmyy(日月年) 
(10)磁偏角(000.0~180.0度,前导位数不足则补0) 
(11) 磁偏角方向,E(东)或W(西) 
(12) 模式指示(A=自主定位,D=差分,E=估算,N=数据无效) 
举例如下:  
$GPRMC,023543.00,A,2308.28715,N,11322.09875,E,0.195,,240213,,,A*78 

5,$GPVTG(地面速度信息,Track Made Good and Ground Speed) 
$GPVTG语句的基本格式如下: 
$GPVTG,(1),T,(2),M,(3),N,(4),K,(5)*hh(CR)(LF) 
(1) 以真北为参考基准的地面航向(000~359度,前面的0也将被传输) 
(2)  以磁北为参考基准的地面航向(000~359度,前面的0也将被传输) 
(3)  地面速率(000.0~999.9节,前面的0也将被传输) 
(4)  地面速率(0000.0~1851.8公里/小时,前面的0也将被传输) 
(5)  模式指示(A=自主定位,D=差分,E=估算,N=数据无效) 
举例如下: 
$GPVTG,,T,,M,0.195,N,0.361,K,A*2A 

6,$GPGLL(定位地理信息,Geographic Position) 
$GPGLL语句的基本格式如下: 
$GPGLL,(1),(2),(3),(4),(5),(6),(7)*hh(CR)(LF) 
(1)  纬度ddmm.mmmmm(度分) 
(2)  纬度半球N(北半球)或S(南半球) 
(3)  经度dddmm.mmmmm(度分) 
(4)  经度半球E(东经)或W(西经) 
(5)  UTC时间:hhmmss(时分秒) 
(6)  定位状态,A=有效定位,V=无效定位 
(7)  模式指示(A=自主定位,D=差分,E=估算,N=数据无效) 
举例如下: 
$GPGLL,2308.28715,N,11322.09875,E,023543.00,A,A*6A 

7,$GPZDA(当前时间信息) 
$GPZDA语句的基本格式如下: 
$GPZDA,(1),(2),(3),(4),(5),(6)*hh(CR)(LF) 
(1)  UTC时间:hhmmss(时分秒) 
(2)  日 
(3)  月 
(4)  年 
(5)  本地区域小时(NEO-6M未用到,为00) 
(6)  本地区域分钟(NEO-6M未用到,为00) 
举例如下: 
$GPZDA,082710.00,16,09,2002,00,00*64 
NMEA-0183协议命令帧部分就介绍到这里,接下来我们看看NMEA-0183协议的校验,通过前面
的介绍,我们知道每一帧最后都有一个hh的校验和,该校验和是通过计算$与*之间所有字符
ASCII码的异或运算得到,将得到的结果以ASCII字符表示就是该校验(hh)。 
例如语句:$GPZDA,082710.00,16,09,2002,00,00*64,校验和(红色部分参与计算)计算方法为: 
0X47xor 0X50xor 0X5Axor 0X44xor 0X41xor 0X2Cxor 0X30xor 0X38xor 0X32xor 0X37xor 
0X31xor 0X30xor 0X2Exor 0X30xor 0X30xor 0X2Cxor 0X31xor 0X36xor 0X2Cxor 0X30xor 
0X39xor 0X2Cxor 0X32xor 0X30xor 0X30xor 0X32xor 0X2Cxor 0X30xor 0X30xor 0X2Cxor 
0X30xor 0X30 

得到的结果就是0X64,用ASCII表示就是64。 
NMEA-0183协议我们就介绍到这里,了解了该协议,我们就可以编写单片机代码,解析
NMEA-0183数据,从而得到GPS定位的各种信息了。 

3其他知识

GPS(Global Positioning System,全球定位系统)表示的形式主要包括以下几种:

1. 坐标系统

  • 经纬度坐标:GPS通过经纬度来确定地球上的位置。经度表示地球中的横向位置(东西方向),范围从西经180°到东经180°,以本初子午线(通过伦敦的经线)为0°。纬度表示地球中的纵向位置(南北方向),范围从南纬90°到北纬90°,以赤道为0°。
  • 度分秒(DMS)格式:这是经纬度的一种常见表示方式,将度细分为分和秒,以便更精确地表示位置。例如,纬度可以表示为45°46′24″N,经度可以表示为116°43′30″E。
  • 十进制度(DD)格式:另一种常见的表示方式,直接使用小数来表示经纬度,如纬度45.773333°,经度116.725000°。

2. 时间系统

  • UTC时间:GPS使用UTC(协调世界时)作为时间基准,这是一种以原子时秒长为基础,在时刻上尽量接近于世界时的时间计量系统。GPS时间起始于1980年1月6日UTC 0时,保证时间的连续性。

3. 数据格式

  • NMEA 0183标准:GPS设备通常通过NMEA 0183标准输出数据,这是一种用于不同GPS导航设备之间的通信协议。该标准定义了多种数据格式,如GPRMC(推荐最小定位信息)、GPGGA(GPS定位信息)、GPGSV(可视卫星信息)等。每种格式都包含了一系列以逗号分隔的数据字段,如时间、定位状态、纬度、经度、速度等。

4. 精度指标

  • 位置精度稀释(PDOP、HDOP、VDOP):这些指标用于衡量GPS定位的精度。PDOP表示综合位置精度因子,HDOP表示水平精度因子,VDOP表示垂直精度因子。它们的值越小,表示定位精度越高。

5. 其他信息

  • 卫星信息:GPS设备还会输出当前接收到的卫星信息,包括卫星编号、仰角、方位角、信噪比等,这些信息有助于了解设备的定位状态和信号质量。

综上所述,GPS表示的形式涵盖了坐标系统、时间系统、数据格式、精度指标以及卫星信息等多个方面。这些形式共同构成了GPS技术的核心,使得我们能够准确地确定地球上的位置和时间。

实例代码

1-1思路

定义两个uart一个接收一个处理数据后发送

添加了串口重定义

1-2重要的代码

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
 
	uint8_t GPS_data[128];		//缓存所有的GPS的数据
	
	char *GPGGA;		//缓存特定的数据
	char GPGGA2[15][15];	//将数据拆分,才分为 第几行(数组的第几行) + 有效的数据(其以‘\0’结尾)
	char *parts_ptr; // 二维数组的指针
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
//获取数据
	  
	  // 清空数组,将所有元素设置为0
	  memset(GPS_data, 0,128);
	  
	  char data[2]; //临时缓存
	  int a=0;			//初始个数为零
	  
	  if(HAL_UART_Receive(&huart2,(uint8_t *)data,1,1)==HAL_OK){//查看是否有数据
			if(data[0] =='$'){//判断数据的开始符号
				do{
						GPS_data[a]=data[0]; //放入缓存中
						a++;				 //计数
					HAL_UART_Receive(&huart2,(uint8_t*)data,1,1);//读取下一个数据
				}while(data[0] != 0x0D);//判断结束
			}
	  }
//筛选数据
	  if(GPS_data[0]=='$' && GPS_data[4]=='G' && GPS_data[5]=='A'){ //筛选数据
			
		  //printf("%s",GPS_data); //打印原始数据
		  
		  // 使用 memset 清空二维数组
		  parts_ptr = (char *)GPGGA2; // 将二维数组的指针转换为指向第一行的指针
		  memset(parts_ptr, 0, 15); // 清空整个二维数组
		  
//拆分数据
		  
		  const char *delimiters = ",";//标志符
		  // 获取第一个标记
		  GPGGA = strtok((char*)GPS_data, delimiters);

		  int b=0; //记行数
		  
		  // 循环获取所有标记
			while (GPGGA != NULL) {
				strcpy(GPGGA2[b], GPGGA);//存储数据并在此数据末尾加‘\0’
				// 获取下一个标记
				GPGGA = strtok(NULL, delimiters);
				b++;
			}
			//显示原始数据
//			for (int j = 0; j < b; j++) {
//					printf("数据 %d: %s\n", j + 1, GPGGA2[j]);
//				}

//将接收到的度分数据转换为度分秒的格式			
			//	纬度		
			float wei=2622.82816;
			sscanf(GPGGA2[2],"%f",&wei);//将字符数转换为数字
			//度
			int wei_du =(int)(wei/100);
			//分
			int wei_fen=(int)wei-(wei_du*100);
			//秒
			float wei_miao1=fmod(wei,1.0)*60;
			float wei_miao2=fmod((fmod(wei_miao1,1.0)*60),1.0);
			wei_miao1=(int)wei_miao1+wei_miao2;
			printf("纬度 %s  %d°%d′%0.2f″",GPGGA2[3] ,wei_du,wei_fen,wei_miao1);

			//	经度		
			float jin=2622.82816;
			sscanf(GPGGA2[4],"%f",&jin);//将字符数转换为数字
			//度
			int jin_du =(int)(jin/100);
			//分
			int jin_fen=(int)jin-(jin_du*100);
			//秒
			float jin_miao1=fmod(jin,1.0)*60;
			float jin_miao2=fmod((fmod(jin_miao1,1.0)*60),1.0);
			jin_miao1=(int)jin_miao1+jin_miao2;
		
			printf("经度 %s  %d°%d′%0.2f″",GPGGA2[5] ,jin_du,jin_fen,jin_miao1);

	  }

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

格式转换(经纬度转换原理一样)

原始字符串(提取纬度和经度部分):

纬度: 2622.82816,N

转换为度分秒(DMS)形式:

  1. 纬度2622.82816

    • 度(°): 整数部分 26
    • 分('): (22.82816 * 60) % 60 = 22' + (0.82816 * 60)' = 22' + 49.6896' = 22'49.69"(四舍五入到小数点后两位)
    • 秒(""): (0.6896 * 60) = 41.376" = 41.38"(四舍五入到小数点后两位)
    • 完整表示: 26°22'49.38"N

    注意:我在秒的计算中做了四舍五入,但原始答案中的秒是41.37",这里我调整为了41.38"以匹配更常见的四舍五入规则。不过,这种微小的差异在实际应用中通常是可以接受的。

main.c文件源码

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "string.h"  //memset()指定数组为什么内容(用于清空数据)  //strtok()拆分数据   //strcpy()将字符串存入数组中
#include "stdio.h"   //sscanf()数学字符转换为数字    printf()串口输出
#include "math.h"  //fmod()取小数部分
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
 
	uint8_t GPS_data[128];		//缓存所有的GPS的数据
	
	char *GPGGA;		//缓存特定的数据
	char GPGGA2[15][15];	//将数据拆分,才分为 第几行(数组的第几行) + 有效的数据(其以‘\0’结尾)
	char *parts_ptr; // 二维数组的指针
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
//获取数据
	  
	  // 清空数组,将所有元素设置为0
	  memset(GPS_data, 0,128);
	  
	  char data[2]; //临时缓存
	  int a=0;			//初始个数为零
	  
	  if(HAL_UART_Receive(&huart2,(uint8_t *)data,1,1)==HAL_OK){//查看是否有数据
			if(data[0] =='$'){//判断数据的开始符号
				do{
						GPS_data[a]=data[0]; //放入缓存中
						a++;				 //计数
					HAL_UART_Receive(&huart2,(uint8_t*)data,1,1);//读取下一个数据
				}while(data[0] != 0x0D);//判断结束
			}
	  }
//筛选数据
	  if(GPS_data[0]=='$' && GPS_data[4]=='G' && GPS_data[5]=='A'){ //筛选数据
			
		  //printf("%s",GPS_data); //打印原始数据
		  
		  // 使用 memset 清空二维数组
		  parts_ptr = (char *)GPGGA2; // 将二维数组的指针转换为指向第一行的指针
		  memset(parts_ptr, 0, 15); // 清空整个二维数组
		  
//拆分数据
		  
		  const char *delimiters = ",";//标志符
		  // 获取第一个标记
		  GPGGA = strtok((char*)GPS_data, delimiters);

		  int b=0; //记行数
		  
		  // 循环获取所有标记
			while (GPGGA != NULL) {
				strcpy(GPGGA2[b], GPGGA);//存储数据并在此数据末尾加‘\0’
				// 获取下一个标记
				GPGGA = strtok(NULL, delimiters);
				b++;
			}
			//显示原始数据
//			for (int j = 0; j < b; j++) {
//					printf("数据 %d: %s\n", j + 1, GPGGA2[j]);
//				}

//将接收到的度分数据转换为度分秒的格式			
			//	纬度		
			float wei=2622.82816;
			sscanf(GPGGA2[2],"%f",&wei);//将字符数转换为数字
			//度
			int wei_du =(int)(wei/100);
			//分
			int wei_fen=(int)wei-(wei_du*100);
			//秒
			float wei_miao1=fmod(wei,1.0)*60;
			float wei_miao2=fmod((fmod(wei_miao1,1.0)*60),1.0);
			wei_miao1=(int)wei_miao1+wei_miao2;
			printf("纬度 %s  %d°%d′%0.2f″",GPGGA2[3] ,wei_du,wei_fen,wei_miao1);

			//	经度		
			float jin=2622.82816;
			sscanf(GPGGA2[4],"%f",&jin);//将字符数转换为数字
			//度
			int jin_du =(int)(jin/100);
			//分
			int jin_fen=(int)jin-(jin_du*100);
			//秒
			float jin_miao1=fmod(jin,1.0)*60;
			float jin_miao2=fmod((fmod(jin_miao1,1.0)*60),1.0);
			jin_miao1=(int)jin_miao1+jin_miao2;
		
			printf("经度 %s  %d°%d′%0.2f″",GPGGA2[5] ,jin_du,jin_fen,jin_miao1);

	  }

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
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_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 168;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  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_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2067410.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

应用程自定义协议与序列化反序列化

本篇将主要介绍在应用层中自定义的协议&#xff0c;自定义协议的同时还需要将我们的数据继续序列化和反序列化&#xff0c;所以本篇的重点为序列化、反序列化的原因以及如何自定义协议&#xff0c;接着探讨了关于为什么 tcp 协议可以支持全双工协议。还根据用户自定义协议结合 …

⼆⼿⻋交易系统前景分析

二手车交易系统开发小程序在当前市场中具有显著的优势和潜力。以下是对二手车交易系统小程序功能的综合分析&#xff1a; 车辆信息展示&#xff1a;小程序应提供详细的车辆信息展示&#xff0c;包括车辆的图片、品牌、型号、年份、里程数、价格等关键信息&#xff0c;方便用户…

Python爬虫—常用的网络爬虫工具推荐

以下列举几个常用的网络爬虫工具 1. 八爪鱼&#xff08;Bazhuayu&#xff09; 简介&#xff1a; 八爪鱼是一款面向非技术用户的桌面端爬虫软件&#xff0c;以其可视化操作和强大的模板库而受到青睐。它支持从各种网站上抓取数据&#xff0c;包括文本、图片、文档等&#xff…

特殊类设计和类型转换

前言 这一篇博客我们讲特殊类设计和类型转换 1. 特殊类设计 1.1 请设计一个类&#xff0c;不能被拷贝 这个比较简单 第一种方法就是将赋值和拷贝构造只定义不声明然后设置为私有就可以了 第二种方法就是直接令它为delete 1.2 请设计一个类&#xff0c;只能在堆上创建对象 …

自学成才:通过自学成为软件开发者——之入行成为软件开发者

一些优秀的程序员&#xff0c;可能以前从事的是其他职业&#xff0c;他们大都发现工作中的很多固定化的流程内容&#xff0c;如果可以实现自动化&#xff0c;不仅效率能够得到提高和保证&#xff0c;提高自己的生成力&#xff0c;同时自己也会从中释放出来&#xff0c;有更多的…

Go使用MongoDB应用指南

Go使用MongoDB应用指南 MongoDB 是一种高性能、开源、文档型的 NoSQL 数据库&#xff0c;广泛应用于 Web 应用、大数据以及云计算领域。Go 语言则以其快速、开发效率高、代码可维护性强著称。本指南将详细介绍如何在 Go 语言中使用 MongoDB 进行数据库操作&#xff0c;包括连接…

鸿蒙HarmonyOS开发知识:命令行工具Command Line Tools

该命令行工具集合了HarmonyOS应用开发所用到的系列工具&#xff0c;包括代码检查codelinter、三方库的包管理ohpm、命令行解析hstack、编译构建hvigorw。 命令行工具获取 请前往下载中心获取并下载命令行工具Command Line Tools。 配置环境变量 Windows 将解压后command-l…

英语四六级有多重要你不知道

卷出天际 IT业内卷严重大家都知道 因此也就打击了很多想入行的新人 到底什么是核心竞争力 放在十年前 稍微会Spring, CRUD 就能达到入门的台阶 那也是培训机构最繁荣的一段时期 而今顶峰已经过去 IT业从含金量上 已经大不如前 在野蛮发展期 如果不太挑的话 大专也是…

云轴科技ZStack AIOS平台智塔亮相FDS金融领袖峰会

人工智能&#xff08;AI&#xff09;正以前所未有的速度渗透到金融系统&#xff0c;推动着金融服务的创新和变革。这种深度融合不仅可以提高金融服务的效率和准确性&#xff0c;未来还可催生全新的金融产品和服务模式。尤其是生成式人工智能&#xff08;GenAI&#xff09;的出现…

算法的学习笔记—复杂链表的复制(牛客JZ35)

&#x1f600;前言 在许多实际应用中&#xff0c;我们会遇到复杂链表的复制问题。复杂链表不同于一般的单链表&#xff0c;不仅每个节点有指向下一个节点的指针&#xff0c;还有一个特殊的指针 random&#xff0c;可以指向链表中的任意节点或 null。如何高效地复制这样一个复杂…

CACTER直播预告:聚焦EDLP邮件数据防泄露实战重点

在信息高速流通的今天&#xff0c;邮件作为商务沟通的桥梁&#xff0c;不仅承载着日常沟通&#xff0c;更是企业机密和知识产权的重要载体。然而&#xff0c;邮件系统的开放性也使其成为网络攻击的主要目标。数据泄露不仅会导致商业损失&#xff0c;还可能对企业声誉造成不可逆…

【请安全下载】黑神话:悟空 单机游戏 它是如何保证安全的 怎样防破解的?安全措施:D加密,反外挂,代码加密,资源保护

单机 《黑神话&#xff1a;悟空》是一款单机游戏&#xff0c;由游戏科学开发&#xff0c;并于2024年8月20日全球同步上线。游戏以其独特的暗黑国风、深度的故事背景以及精致的游戏画面&#xff0c;重塑了西游题材&#xff0c;为玩家呈现了一个前所未有的悟空传奇。 黑神话&…

[Linux]在Ubuntu中安装samba并且正确配置(详细)

一、我们为什么需要samba服务 samba是一种实现windows和linux包括macos文件共享的套件。它能让我们像访问自己的磁盘一样去访问别的系统的文件。可以看得出来这种一种快速并且高效的文件传输协议。看到这里&#xff0c;大家可能会有些疑问。向linux传输文件&#xff0c;我们可以…

常用网络测试工具以及解决tcp协议带来得问题

一、解决粘包问题 1.1、tcp的特点 面向字节流特点&#xff0c;会造成可能数据与数据发送到一块&#xff0c;成为粘包&#xff0c;数据之间不区分 1.2、拆包 因为缓冲区的大小&#xff0c;一次性发送的数据会进行拆分&#xff08;大小不符合的时候&#xff09; 就和水一样一…

vue3使用i18n实现国际化

安装vue-i18n npm install vue-i18n创建一个ts文件用于存储各种翻译 globalLang.ts的内容如下&#xff1a; export default {"cn": {},"en": {},"de": {},"es": {},"fr": {},"id": {},"it": {},&quo…

HDMI画面发白

这个问题困扰我很久了&#xff0c;今天在抖音上看到了解决方案! https://v.douyin.com/Ceie2g2s/ 量化范围&#xff1a;有限范围改成全范围。

Tomcat安装部署

简介 Tomcat 是由 Apache 开发的一个 Servlet 容器&#xff0c;实现了对 Servlet 和 JSP 的支持&#xff0c;并提供了作为Web服务器的一些特有功能&#xff0c;如Tomcat管理和控制平台、安全域管理和Tomcat阀等。 简单来说&#xff0c;Tomcat是一个WEB应用程序的托管平台&…

关于elementui table组件 —— 竖向表格

前端模拟数据方式&#xff1a; html代码&#x1f447;&#xff1a; <template><el-table :data"tableData" style"width: 60%;margin-top:20px" stripe :show-header"false" border :row-style"rowStyle"><el-table…

培训第三十五天(容器的基础命令使用)

1、创建一个容器并同时执行echo命令 # 快速启动一个容器执行特定的一次性命令并查看输出结果&#xff0c;输出结果后容器直接退出[rootdocker ~]# docker run -it --namea0 centos:latest echo "abc"abc[rootdocker ~]# docker psCONTAINER ID IMAGE COMMAND …

FreeRTOS 快速入门(六)之互斥量

目录 一、互斥量1、基本概念2、运作机制3、死锁现象4、递归互斥量 二、优先级反转和优先级继承问题1、优先级反转问题2、优先级继承问题 三、互斥量函数1、互斥量1、创建 2、获取互斥量3、释放互斥量4、删除互斥量 一、互斥量 1、基本概念 互斥量又称互斥信号量&#xff08;本…