STM32获取GY-25A倾角传感器串口输出数据

STM32获取GY-25A倾角传感器串口输出数据

GY-25A模块是新型的倾角传感器模块,具有X和Y两轴模拟角度输出和串口角度输出的功能。这里介绍STM32获取GY-25A串口输出的角度数据。
在这里插入图片描述

串口输出格式介绍

GY-25A默认以9600波特率输出TTL电平的串口数据,其一帧数据输出4种数据,共8个字节,如下所示:
在这里插入图片描述
其中横滚角对应模拟输出的X轴,俯仰角对应模拟输出的Y轴。

串口接收的数据帧里,前4个字节固定为16进制A4 03 14 08,其中第一个字节A4是GY-25A的访问地址, 第二个字节此次输出对应的指令,这里03是连续输出的指令,第三个指令是输出的寄存器收地址,14即为ROLL_H字节的地址,第四个指令是后面输出的字节数,08表示输出8个寄存器字节数据,也就是从ROLL_H输出到TEMP_L,在数据字节输出后还会输出1个字节,为前面输出的字节的累加和的低8位。如一帧数据为:A4 03 14 08 BB 36 02 01 FF 7E 0D 92 D3 。

GY-25A输出的这部分数据,采用放大100倍和补码方式表示。如16进制数据为02 01, 02是高字节,最高位为0,因此为正数,不做补码处理。02 01对应十进制数513, 将513除以100得到5.13,即当前的角度为5.13度。如16进制数据为BB 36,最高位为1,因此为负数,进行补码处理,得到其代表的负数为-17610,将-17610除以100得到-176.10,即当前的角度为-176.10度。

横滚角翻转特性

芯片的横滚角度变化关系如下面所示:
在这里插入图片描述
在这里插入图片描述
需要注意,在芯片朝下模块与水平面平行时,芯片X轴微动,会有180度输出和-180度输出的跳变!
以上为横滚角X轴的输出特性。

俯仰角翻转特性

芯片的俯仰角度变化关系如下面所示:
在这里插入图片描述
在这里插入图片描述
由横滚角和俯仰角的输出特性可以看出,横滚角是360度分辨特性,俯仰角是180度分辨特性,与名称来历相符。

另外两个输出数据即航向角和温度,数据输出格式也是一样,这里不做介绍。也可以通过串口指令,控制GY-25A的工作方式,将连续输出模式改为查询模式,可以查看数据手册进行操作。

STM32串口程序

这里以STM32F401CCU6开发板介绍串口获取GY-25A默认输出数据的方式。主要的逻辑设计为:

  1. 通过中断接收四个字节,并判断是否为帧头A4 03 14 08,如果不是,重新接收4个字节,重新判断帧头。
  2. 通过中断接收四个字节,并判断是否为帧头A4 03 14 08,如果是,通过轮询方式接收9个字节,前8个字节为有效数据,最后一个字节为校验字节。收完9个字节后,重新启动4个字节的中断接收。
    如果一开始接收的帧头错误,最多滑动3帧后就可以接收到正确的帧头,这一点可以自己分析。

通过STM32CUBEIDE建立HAL库工程做介绍:
首先建立工程并配置时钟,普通时序,采用内部时钟即可。
在这里插入图片描述
设置UART串口:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后生成工程初始代码:
在这里插入图片描述

编写代码实现数据接收:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 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"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* 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 ---------------------------------------------------------*/
UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */
uint8_t frame_head[4];
uint8_t frame_data[9];
uint8_t d1[2];
uint8_t d2[2];

uint8_t rd_flag = 0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(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();
  /* USER CODE BEGIN 2 */
  HAL_UART_Receive_IT(&huart1, frame_head, 4);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	 if(rd_flag==1)
	 {
		 rd_flag = 0;
		 HAL_UART_Receive(&huart1, frame_data, 9, 5000);

		 d1[0]=frame_data[0];
		 d1[1]=frame_data[1];

		 d2[0]=frame_data[2];
		 d2[1]=frame_data[3];

		 //do something you want

		 HAL_UART_Receive_IT(&huart1, frame_head, 4);

	 }

	 HAL_Delay(1);
    /* 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_SCALE2);
  /** 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 = 16;
  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_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

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

/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();

}

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart==&huart1)
	{
      if ((frame_head[0]==0xA4)&&(frame_head[1]==0x03)&&(frame_head[2]==0x14)&&(frame_head[3]==0x08))
      {
    	  rd_flag = 1;
      }
      else
      {
    	  HAL_UART_Receive_IT(&huart1, frame_head, 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 */


–End–

版权声明:本文为CSDN博主「PegasusYu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hwytree/article/details/122622720

STM32获取GY-25A倾角传感器串口输出数据

GY-25A模块是新型的倾角传感器模块,具有X和Y两轴模拟角度输出和串口角度输出的功能。这里介绍STM32获取GY-25A串口输出的角度数据。
在这里插入图片描述

串口输出格式介绍

GY-25A默认以9600波特率输出TTL电平的串口数据,其一帧数据输出4种数据,共8个字节,如下所示:
在这里插入图片描述
其中横滚角对应模拟输出的X轴,俯仰角对应模拟输出的Y轴。

串口接收的数据帧里,前4个字节固定为16进制A4 03 14 08,其中第一个字节A4是GY-25A的访问地址, 第二个字节此次输出对应的指令,这里03是连续输出的指令,第三个指令是输出的寄存器收地址,14即为ROLL_H字节的地址,第四个指令是后面输出的字节数,08表示输出8个寄存器字节数据,也就是从ROLL_H输出到TEMP_L,在数据字节输出后还会输出1个字节,为前面输出的字节的累加和的低8位。如一帧数据为:A4 03 14 08 BB 36 02 01 FF 7E 0D 92 D3 。

GY-25A输出的这部分数据,采用放大100倍和补码方式表示。如16进制数据为02 01, 02是高字节,最高位为0,因此为正数,不做补码处理。02 01对应十进制数513, 将513除以100得到5.13,即当前的角度为5.13度。如16进制数据为BB 36,最高位为1,因此为负数,进行补码处理,得到其代表的负数为-17610,将-17610除以100得到-176.10,即当前的角度为-176.10度。

横滚角翻转特性

芯片的横滚角度变化关系如下面所示:
在这里插入图片描述
在这里插入图片描述
需要注意,在芯片朝下模块与水平面平行时,芯片X轴微动,会有180度输出和-180度输出的跳变!
以上为横滚角X轴的输出特性。

俯仰角翻转特性

芯片的俯仰角度变化关系如下面所示:
在这里插入图片描述
在这里插入图片描述
由横滚角和俯仰角的输出特性可以看出,横滚角是360度分辨特性,俯仰角是180度分辨特性,与名称来历相符。

另外两个输出数据即航向角和温度,数据输出格式也是一样,这里不做介绍。也可以通过串口指令,控制GY-25A的工作方式,将连续输出模式改为查询模式,可以查看数据手册进行操作。

STM32串口程序

这里以STM32F401CCU6开发板介绍串口获取GY-25A默认输出数据的方式。主要的逻辑设计为:

  1. 通过中断接收四个字节,并判断是否为帧头A4 03 14 08,如果不是,重新接收4个字节,重新判断帧头。
  2. 通过中断接收四个字节,并判断是否为帧头A4 03 14 08,如果是,通过轮询方式接收9个字节,前8个字节为有效数据,最后一个字节为校验字节。收完9个字节后,重新启动4个字节的中断接收。
    如果一开始接收的帧头错误,最多滑动3帧后就可以接收到正确的帧头,这一点可以自己分析。

通过STM32CUBEIDE建立HAL库工程做介绍:
首先建立工程并配置时钟,普通时序,采用内部时钟即可。
在这里插入图片描述
设置UART串口:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后生成工程初始代码:
在这里插入图片描述

编写代码实现数据接收:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 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"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* 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 ---------------------------------------------------------*/
UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */
uint8_t frame_head[4];
uint8_t frame_data[9];
uint8_t d1[2];
uint8_t d2[2];

uint8_t rd_flag = 0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(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();
  /* USER CODE BEGIN 2 */
  HAL_UART_Receive_IT(&huart1, frame_head, 4);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	 if(rd_flag==1)
	 {
		 rd_flag = 0;
		 HAL_UART_Receive(&huart1, frame_data, 9, 5000);

		 d1[0]=frame_data[0];
		 d1[1]=frame_data[1];

		 d2[0]=frame_data[2];
		 d2[1]=frame_data[3];

		 //do something you want

		 HAL_UART_Receive_IT(&huart1, frame_head, 4);

	 }

	 HAL_Delay(1);
    /* 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_SCALE2);
  /** 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 = 16;
  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_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

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

/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();

}

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart==&huart1)
	{
      if ((frame_head[0]==0xA4)&&(frame_head[1]==0x03)&&(frame_head[2]==0x14)&&(frame_head[3]==0x08))
      {
    	  rd_flag = 1;
      }
      else
      {
    	  HAL_UART_Receive_IT(&huart1, frame_head, 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 */


–End–

版权声明:本文为CSDN博主「PegasusYu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hwytree/article/details/122622720

生成海报
点赞 0

PegasusYu

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

STM32获取GY-25A倾角传感器串口输出数据

STM32获取GY-25A倾角传感器串口输出数据 GY-25A模块是新型的倾角传感器模块,具有X和Y两轴模拟角度输出和串口角度输出的功能。这里介绍STM32获取GY-25A串口输出的角度数据。 串口输出格式介绍 GY-25

pwm电机调速的原理介绍与代码实现

1、pwm实现调速的原理与介绍 PWM(Pulse Width Modulation)脉冲宽度调制。 1)占空比 pwm占空比就是一个脉冲周期内有效电平在整个周期所占的比例。 通过调节PWM的占空比就能调节IO口上电压的持续

【STM32Cube笔记】2-STM32Cube安装教程

【STM32Cube笔记】系列文章目录 1-基于STM32的VSCode入门级教程前言 2-STM32Cube安装教程 3-STM32CubeIDE汉化 4-STM32Cube配置时钟设置 5-跑马灯引脚配置 6-Cortex-M7内核基本配