【STM32】陀螺仪JY61p串口读取数据代码分享
·
陀螺仪配置:
打开维特官方的上位机,对JY61p进行配置。(需要陀螺仪和电脑连接)

陀螺仪数据发送给单片机规则:



思路:
将陀螺仪发送的数据分类存入数组,数组大小为9个uint8类型,8位数据位,1位完成位。通过判断完成位来处理数据。代码移植时需使用自己的串口初始化函数(代码中为USART3_Init),和串口中断服务函数(代码中为USART3_IQRHandler) 。

代码 :
头文件JY61p.h
#ifndef __JY61P_H_
#define __JY61P_H_
/**** 头文件 ****/
#include "usart.h"
/**** 宏定义 ****/
typedef struct Time_Param
{
__IO u16 year; // 年
__IO u8 month; // 月
__IO u8 day; // 日
__IO u8 hour; // 时
__IO u8 minute; // 分
__IO u8 sec; // 秒
__IO u16 Ms; // 毫秒
}Time_Param;
/**** 函数 ****/
void JY61p_Init(void);
void JY61p_GetTime(Time_Param* p);
void JY61p_GetAcc(float* Ax, float* Ay, float* Az);
void JY61p_GetAngleSpeed(float* Wx, float* Wy, float* Wz);
void JY61p_GetAngle(float* Roll, float* Pitch, float* Yaw);
void JY61p_Get4Elements(float* Q0, float* Q1, float* Q2, float* Q3);
#endif // __JY61P_H_
源文件JY61p.c
#include "JY61p.h"
u8 JY61p_TimeData[9]; // 8位时间原始数据 1位完成位
u8 JY61p_AccData[9]; // 8位加速度原始数据 1位完成位
u8 JY61p_AngleSpeedData[9]; // 8位角速度原始数据 1位完成位
u8 JY61p_AngleData[9];// 8位角度原始数据 1位完成位
u8 JY61p_4Elements[9];// 8位四元素原始数据 1位完成位
void JY61p_Init(void)
{
USART3_Init(); // 使用自己的串口初始化波特率按陀螺仪配置的来
}
/***********************************************************
*@fuction : JY61p_GetPack
*@brief : JY61p 获取数据包
*@param : 数据
*@return : None
*@author : HongScholar
*@date : 2025.03.22
***********************************************************/
void JY61p_GetPack(u8* DR)
{
static u8 sta =0;// 数据包进程
static u8 p =0; // 数据帧
static u8 type = 0xff; // 数据类型
if(sta == 0)
{
if(*DR == 0x55) // 帧头
sta =1;
}
else if(sta == 1)
{
if(*DR == 0x50)
type = 0, sta = 2;// 时间
else if(*DR == 0x51)
type = 1, sta = 2;// 加速度
else if(*DR == 0x52)
type = 2, sta = 2;// 角速度
else if(*DR == 0x53)
type = 3, sta = 2;// 角度
else if(*DR == 0x59)
type = 9, sta = 2;// 四元数
else
sta=0;
}
else if(sta == 2)
{
switch(type) // 选择数据类型存储空间
{
/* 时间输入*/
case 0: JY61p_TimeData[p++] = *DR;
if(p == 7)
{
p=0; type =0xff; sta =3;
JY61p_TimeData[8] = 1;// 完成
}
break;
/* 加速度输入*/
case 1: JY61p_AccData[p++] = *DR;
if(p == 7)
{
p=0; type =0; sta =3;
JY61p_AccData[8] = 1;// 完成
}
break;
/* 角速度输入*/
case 2: JY61p_AngleSpeedData[p++] = *DR;
if(p == 7)
{
p=0; type =0; sta =3;
JY61p_AngleSpeedData[8] = 1;// 完成
}
break;
/* 角度输入*/
case 3: JY61p_AngleData[p++] = *DR;
if(p == 7)
{
p=0; type =0; sta =3;
JY61p_AngleData[8] = 1;// 完成
}
break;
/* 四元数*/
case 9: JY61p_4Elements[p++] = *DR;
if(p == 7)
{
p=0; type =0; sta =3;
JY61p_4Elements[8] = 1;// 完成
}
break;
default: sta =0;
}
}
else if(sta == 3)
{
// if(*DR != SUM) // 校验
// {
//
// }
sta = 0;
}
}
/**
* @brief USART3 的中断服务函数
*/
void USART3_IRQHandler(void)
{
if(USART_GetITStatus(USART3, USART_IT_RXNE))
{
/* 获取数据流*/
JY61p_GetPack((u8*)&(USART3->DR));
USART_ClearITPendingBit(USART3, USART_IT_RXNE);
}
}
/***********************************************************
*@fuction : JY61p_GetTime
*@brief : JY61p 获取时间
*@param : 时间
*@return : None
*@author : HongScholar
*@date : 2025.03.22
***********************************************************/
void JY61p_GetTime(Time_Param* p)
{
if(JY61p_TimeData[8])
{
p->year = JY61p_TimeData[0] +2000;// 年
p->month = JY61p_TimeData[1]; // 月
p->day = JY61p_TimeData[2]; // 日
p->hour = JY61p_TimeData[3]; // 时
p->minute = JY61p_TimeData[4]; // 分
p->sec = JY61p_TimeData[5]; // 秒
p->Ms = JY61p_TimeData[7] <<8 | JY61p_TimeData[6]; // 毫秒
JY61p_TimeData[8] = 0;
}
}
/***********************************************************
*@fuction : JY61p_GetAcc
*@brief : JY61p 获取加速度, 范围: 0.00 m/s^2 ~ 16.00g m/s^2
*@param : 加速度x\y\z方向, 温度
*@return : None
*@author : HongScholar
*@date : 2025.03.22
***********************************************************/
void JY61p_GetAcc(float* Ax, float* Ay, float* Az)
{
if(JY61p_AccData[8])
{
*Ax = ((JY61p_AccData[1]<<8) | JY61p_AccData[0]) /32768.00f *16 *9.8f; // x加速度
*Ay = ((JY61p_AccData[3]<<8) | JY61p_AccData[2]) /32768.00f *16 *9.8f; // y加速度
*Az = ((JY61p_AccData[5]<<8) | JY61p_AccData[4]) /32768.00f *16 *9.8f; // z加速度
// *T = ((JY61p_AccData[7]<<8) | JY61p_AccData[6]) /100.00f; // 温度
JY61p_AccData[8] = 0;
}
}
/***********************************************************
*@fuction : JY61p_GetAngleSpeed
*@brief : JY61p 获取角加速度 范围: 0.00度/s ~ 2000.00度/s
*@param : 角加速度x\y\z方向, 温度
*@return : None
*@author : HongScholar
*@date : 2025.03.22
***********************************************************/
void JY61p_GetAngleSpeed(float* Wx, float* Wy, float* Wz)
{
if(JY61p_AngleSpeedData[8])
{
*Wx = ((JY61p_AngleSpeedData[1]<<8) | JY61p_AngleSpeedData[0]) /32768.00f *2000; // x加速度
*Wy = ((JY61p_AngleSpeedData[3]<<8) | JY61p_AngleSpeedData[2]) /32768.00f *2000; // y加速度
*Wz = ((JY61p_AngleSpeedData[5]<<8) | JY61p_AngleSpeedData[4]) /32768.00f *2000; // z加速度
// *T = ((JY61p_AngleSpeedData[7]<<8) | JY61p_AngleSpeedData[6]) /100.00f; // 温度
JY61p_AngleSpeedData[8] = 0;
}
}
/***********************************************************
*@fuction : JY61p_GetAngle
*@brief : JY61p 获取角度值, 范围: -180.00°~ 180.00°
*@param : 滚转角, 俯仰角, 偏航角, 温度
*@return : None
*@author : HongScholar
*@date : 2025.03.22
***********************************************************/
void JY61p_GetAngle(float* Roll, float* Pitch, float* Yaw)
{
if(JY61p_AngleData[8])
{
*Roll = ((JY61p_AngleData[1]<<8) | JY61p_AngleData[0]) /32768.00f*180; // 滚转角 x
*Pitch = ((JY61p_AngleData[3]<<8) | JY61p_AngleData[2]) /32768.00f*180; // 俯仰角 y
*Yaw = ((JY61p_AngleData[5]<<8) | JY61p_AngleData[4]) /32768.00f*180; // 偏航角 z
// *Temp = ((JY61p_AngleData[7]<<8) | JY61p_AngleData[6]) /100.00f; // 温度
if(*Roll >180) *Roll -=360.00f;
if(*Pitch >180) *Pitch -=360.00f;
if(*Yaw >180) *Yaw -=360.00f;
*Roll = -*Roll;
*Pitch = -*Pitch;
*Yaw = - *Yaw;
JY61p_AngleData[8] = 0;
}
}
/***********************************************************
*@fuction : JY61p_Get4Elements
*@brief : JY61p 获取四元数, 范围: 0~1, 精度0.00
*@param : 四元数
*@return : None
*@author : HongScholar
*@date : 2025.03.22
***********************************************************/
void JY61p_Get4Elements(float* Q0, float* Q1, float* Q2, float* Q3)
{
if(JY61p_4Elements[8])
{
*Q0 = ((JY61p_4Elements[1]<<8) | JY61p_4Elements[0]) /32768.00f;
*Q1 = ((JY61p_4Elements[3]<<8) | JY61p_4Elements[2]) /32768.00f;
*Q2 = ((JY61p_4Elements[5]<<8) | JY61p_4Elements[4]) /32768.00f;
*Q3 = ((JY61p_4Elements[7]<<8) | JY61p_4Elements[6]) /32768.00f;
JY61p_4Elements[8] = 0;
}
}
Main.c
#include "OLED.h"
#include "JY61p.h"
extern u8 JY61p_TimeData[9]; // 8位时间原始数据 1位完成位
extern u8 JY61p_AccData[9]; // 8位加速度原始数据 1位完成位
extern u8 JY61p_AngleSpeedData[9]; // 8位角速度原始数据 1位完成位
extern u8 JY61p_AngleData[9];// 8位角度原始数据 1位完成位
extern u8 JY61p_4Elements[9];// 8位四元素原始数据 1位完成位
void text(void)
{
Time_Param t;
float ax, ay, az;
float wx, wy, wz;
float roll, pitch, yaw;
float q0, q1, q2, q3;
/* JY61p原始数据*/
// OLED_ShowHexNum(1,1, JY61p_TimeData[0], 2); OLED_ShowHexNum(1,4, JY61p_TimeData[4], 2);
// OLED_ShowHexNum(2,1, JY61p_TimeData[1], 2); OLED_ShowHexNum(2,4, JY61p_TimeData[5], 2);
// OLED_ShowHexNum(3,1, JY61p_TimeData[2], 2); OLED_ShowHexNum(3,4, JY61p_TimeData[6], 2);
// OLED_ShowHexNum(4,1, JY61p_TimeData[3], 2); OLED_ShowHexNum(4,4, JY61p_TimeData[7], 2);
/* 时间读取*/
JY61p_GetTime(&t);
// OLED_ShowNum(1,1,t.year,4);
// OLED_ShowString(1,5,".");
// OLED_ShowNum(1,6,t.month,2);
// OLED_ShowString(1,8,".");
// OLED_ShowNum(1,9,t.day,2);
// OLED_ShowString(1,11,".");
// OLED_ShowNum(2,1,t.hour,2);
// OLED_ShowString(2,3,".");
// OLED_ShowNum(2,4,t.minute,2);
// OLED_ShowString(2,6,".");
// OLED_ShowNum(2,7,t.sec,2);
// OLED_ShowString(2,9,".");
// OLED_ShowNum(2,10,t.Ms,3);
/* JY61p原始数据*/
// OLED_ShowHexNum(1,1, JY61p_AccData[0], 2); OLED_ShowHexNum(1,4, JY61p_AccData[4], 2);
// OLED_ShowHexNum(2,1, JY61p_AccData[1], 2); OLED_ShowHexNum(2,4, JY61p_AccData[5], 2);
// OLED_ShowHexNum(3,1, JY61p_AccData[2], 2); OLED_ShowHexNum(3,4, JY61p_AccData[6], 2);
// OLED_ShowHexNum(4,1, JY61p_AccData[3], 2); OLED_ShowHexNum(4,4, JY61p_AccData[7], 2);
/* 加速度读取*/
JY61p_GetAcc(&ax, &ay, &az);
// OLED_ShowFloat(1,2,ax, 3, 2);
// OLED_ShowFloat(2,2,ay, 3, 2);
// OLED_ShowFloat(3,2,az, 3, 2);
/* JY61p原始数据*/
// OLED_ShowHexNum(1,1, JY61p_AngleSpeedData[0], 2); OLED_ShowHexNum(1,4, JY61p_AngleSpeedData[4], 2);
// OLED_ShowHexNum(2,1, JY61p_AngleSpeedData[1], 2); OLED_ShowHexNum(2,4, JY61p_AngleSpeedData[5], 2);
// OLED_ShowHexNum(3,1, JY61p_AngleSpeedData[2], 2); OLED_ShowHexNum(3,4, JY61p_AngleSpeedData[6], 2);
// OLED_ShowHexNum(4,1, JY61p_AngleSpeedData[3], 2); OLED_ShowHexNum(4,4, JY61p_AngleSpeedData[7], 2);
/* 角速度读取*/
JY61p_GetAngleSpeed(&wx, &wy, &wz);
// OLED_ShowFloat(1,2,wx, 3, 2);
// OLED_ShowFloat(2,2,wy, 3, 2);
// OLED_ShowFloat(3,2,wz, 3, 2);
/* JY61p原始数据*/
// OLED_ShowHexNum(1,1, JY61p_AngleData[0], 2); OLED_ShowHexNum(1,4, JY61p_AngleData[4], 2);
// OLED_ShowHexNum(2,1, JY61p_AngleData[1], 2); OLED_ShowHexNum(2,4, JY61p_AngleData[5], 2);
// OLED_ShowHexNum(3,1, JY61p_AngleData[2], 2); OLED_ShowHexNum(3,4, JY61p_AngleData[6], 2);
// OLED_ShowHexNum(4,1, JY61p_AngleData[3], 2); OLED_ShowHexNum(4,4, JY61p_AngleData[7], 2);
/* 角度读取*/
JY61p_GetAngle(&roll, &pitch, &yaw);
OLED_ShowFloat(1,2,roll, 3, 2);
OLED_ShowFloat(2,2,pitch, 3, 2);
OLED_ShowFloat(3,2,yaw, 3, 2);
/* JY61p原始数据*/
// OLED_ShowHexNum(1,1, JY61p_4Elements[0], 2); OLED_ShowHexNum(1,4, JY61p_4Elements[4], 2);
// OLED_ShowHexNum(2,1, JY61p_4Elements[1], 2); OLED_ShowHexNum(2,4, JY61p_4Elements[5], 2);
// OLED_ShowHexNum(3,1, JY61p_4Elements[2], 2); OLED_ShowHexNum(3,4, JY61p_4Elements[6], 2);
// OLED_ShowHexNum(4,1, JY61p_4Elements[3], 2); OLED_ShowHexNum(4,4, JY61p_4Elements[7], 2);
/* 四元数读取*/
JY61p_Get4Elements(&q0, &q1, &q2, &q3);
// OLED_ShowFloat(1,2,q0, 3, 2);
// OLED_ShowFloat(2,2,q1, 3, 2);
// OLED_ShowFloat(3,2,q2, 3, 2);
// OLED_ShowFloat(4,2,q3, 3, 2);
}
int main(void)
{
OLED_Init();
JY61p_Init();
while(1)
{
text();
}
}
嵌入式很有趣,希望你也是,敬请期待...
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)