基于CUBEMX和STM32C8T6的同轴麦轮小车制作(二)——HAL库接受jy61p陀螺仪数据,并解决数据溢出卡死问题。

基于CUBEMX和STM32C8T6的同轴麦轮小车制作(二)——HAL库接受jy61p陀螺仪数据,并解决数据溢出卡死问题

本文利用STM32C8T6中的串口1于JY61P实时通信,并用串口2将其角度打印出来,期间遇到了串口数据溢出卡死的问题,在编写ORE错误回调函数后得到有效解决,其分为CUBEMX基本配置、函数编写、效果展示3个部分。

一、CUBEMX基本配置

1.配置串口1、2,此处要注意串口1的波特率要和JY61P的一致(默认是9600,具体可以在上位机中调节),开启串口1的接收中断。

基于CUBEMX和STM32C8T6的同轴麦轮小车制作(二)——HAL库接受jy61p陀螺仪数据,并解决数据溢出卡死问题。
基于CUBEMX和STM32C8T6的同轴麦轮小车制作(二)——HAL库接受jy61p陀螺仪数据,并解决数据溢出卡死问题。

2.配置时钟,Debug

基于CUBEMX和STM32C8T6的同轴麦轮小车制作(二)——HAL库接受jy61p陀螺仪数据,并解决数据溢出卡死问题。
基于CUBEMX和STM32C8T6的同轴麦轮小车制作(二)——HAL库接受jy61p陀螺仪数据,并解决数据溢出卡死问题。
基于CUBEMX和STM32C8T6的同轴麦轮小车制作(二)——HAL库接受jy61p陀螺仪数据,并解决数据溢出卡死问题。

二、程序编写

(1)在main头文件中定义及声明函数:

struct SAcc
{
	short a[3];
	short T;
};
struct SGyro
{
	short w[3];
	short T;
};
struct SAngle
{
	short Angle[3];
	short T;
};
void CopeSerial2Data(unsigned char ucData);
void sendcmd(uint8_t data[3]);

(2)在main中定义:

#include <string.h>
#include <stdio.h>
uint8_t rx_buff1;
struct SAcc ACC;
struct SAngle Angle;
struct SGyro Gyro;

char YAWCMD[3] = {0XFF,0XAA,0X52};
char ACCCMD[3] = {0XFF,0XAA,0X67};
char SLEEPCMD[3] = {0XFF,0XAA,0X60};
char UARTMODECMD[3] = {0XFF,0XAA,0X61};
char IICMODECMD[3] = {0XFF,0XAA,0X62};

float angle_x;
float angle_y;
float angle_z;

float acc_x;
float acc_y;
float acc_z;

float gyro_x;
float gyro_y;
float gyro_z;

(3)串口回调函数:

void HAL_UART_RxCpltCallback()
{
	CopeSerial2Data(rx_buff1);
	HAL_UART_Receive_IT(&huart1,&rx_buff1,1);
}

(4)数据处理函数:

void CopeSerial2Data(unsigned char ucData)
{
	static unsigned char ucRxBuffer[250];
	static unsigned char ucRxCnt = 0;	
	
	ucRxBuffer[ucRxCnt++]=ucData;	//将收到的数据存入缓冲区中
	if (ucRxBuffer[0]!=0x55) //数据头不对,则重新开始寻找0x55数据头
	{
		ucRxCnt=0;
		return;
	}
	if (ucRxCnt<11) {return;}//数据不满11个,则返回
	else
	{
		switch(ucRxBuffer[1])//判断数据是哪种数据,然后将其拷贝到对应的结构体中,有些数据包需要通过上位机打开对应的输出后,才能接收到这个数据包的数据
		{
			//memcpy为编译器自带的内存拷贝函数,需引用"string.h",将接收缓冲区的字符拷贝到数据结构体里面,从而实现数据的解析。
			case 0x51:	memcpy(&ACC,&ucRxBuffer[2],8);break;
			case 0x52:	memcpy(&Gyro,&ucRxBuffer[2],8);break;
			case 0x53:	memcpy(&Angle,&ucRxBuffer[2],8);break;

		}
		ucRxCnt=0;//清空缓存区
	}
}

(5)串口1发送数据:

void sendcmd(uint8_t data[3])
{
	static uint8_t tx_buff;
	for(int i=0;i<3;i++)
	{
		tx_buff = data[i];
		HAL_UART_Transmit(&huart1,&tx_buff,1,0Xff);
	}

}

(6)重定义printf:

int fputc(int ch,FILE *f)
{
    uint8_t temp[1]={ch};
    HAL_UART_Transmit(&huart2,temp,1,0xff);       
}

(7)ORE错误回调函数:

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
	if(huart->ErrorCode&HAL_UART_ERROR_ORE)
	{
		__HAL_UART_CLEAR_OREFLAG(huart);
		HAL_UART_Receive_IT(&huart1,&rx_buff1,1);
	}
  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_UART_ErrorCallback can be implemented in the user file.
   */
}

(8)数据处理

void get_data()
{
	acc_x = (float)ACC.a[0]/32768*16;
	acc_y = (float)ACC.a[1]/32768*16;
	acc_z = (float)ACC.a[2]/32768*16;
		
	gyro_x = (float)Gyro.w[0]/32768*2000;
	gyro_y = (float)Gyro.w[1]/32768*2000;
	gyro_z = (float)Gyro.w[2]/32768*2000;
		
	angle_x = (float)Angle.Angle[0]/32768*180;
	angle_y = (float)Angle.Angle[1]/32768*180;
	angle_z = (float)Angle.Angle[2]/32768*180;

}

(9)主函数:

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 */
	
	HAL_UART_Receive_IT(&huart1,&rx_buff1,1);
	HAL_Delay(1000);
	HAL_Delay(1000);
	sendcmd(ACCCMD1);
	sendcmd(YAWCMD1);
	int count = 0;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		count++;
		HAL_Delay(20);
		get_data();
		if(count == 50)
		{
			printf("angle_x = %f\n",angle_x);
			printf("angle_y = %f\n",angle_y);
			printf("angle_z = %f\n",angle_z);
			count = 0;	
		}

    /* USER CODE END WHILE */

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

三、效果展示
基于CUBEMX和STM32C8T6的同轴麦轮小车制作(二)——HAL库接受jy61p陀螺仪数据,并解决数据溢出卡死问题。

上一篇:[数学]矩阵总结


下一篇:Cocos-BCX开发入门之cli_wallet