文章目录

  • 0.相关基础知识介绍
    • 0.1六轴、九轴传感器有什么区别?
  • 1.JY901模块简介
    • 1.1 产品概述
    • 1.2 性能参数
    • 1.3 实物图和接线
  • 2.软件和使用说明书
  • 3.串口通信JY901
    • 3.1 cubemx工程配置
    • 3.2代码编写
      • 3.2.1 DMA空闲中断的开启
      • 3.2.2 添加JY901.h
      • 3.2.3 重定义需要的结构体和JY901数据结构体
      • 3.2.4 接收结构体初始化
      • 3.2.5 数据解算
    • 3.3现象观测
  • 4.I2C通信JY901

0.相关基础知识介绍

IMU模块中6轴、9轴包含哪些模块?

欧拉角、旋转矩阵、四元数合辑
这个确实复杂,如果以后有机会接触到飞控,再好好看看。

0.1六轴、九轴传感器有什么区别?

加速度传感器(即加速计)、角速度传感器(即陀螺仪)、磁感应传感器(即电子罗盘)。这三类传感器测量的数据在空间坐标系中都可以被分解为X,Y,Z三个方向轴的力,因此也常常被称为3轴加速度计、3轴陀螺仪、3轴磁力计。

加速度传感器(即加速计) 检测横向加速
角速度传感器(即陀螺仪) 检测角度旋转和平衡
磁感应传感器(即电子罗盘) 获取磁场数据
气压传感器 获取海拔高度的数据

6轴 : 三轴(XYZ)加速度计 + 三轴(XYZ)陀螺仪(也叫角速度传感器)
9轴 : 6轴 + 三轴(XYZ)磁场传感器

1.JY901模块简介

以下内容来自JY901使用说明书V4.4,仅摘录了需要注意的内容。

1.1 产品概述

模块内部自带电压稳定电路, 工作电压 3.3v~5v, 引脚电平兼容 3.3V/5V 的嵌入式系统,连接方便。
模块内部集成了姿态解算器, 配合动态卡尔曼滤波算法, 能够在动态环境下准确输出模块的当前姿态, 姿态测量精度静态 0.05 度, 动态 0.1 度, 稳定性极高。
支持串口和 IIC 两种数字接口。 方便用户选择最佳的连接方式。 串口速率
2400bps~921600bps 可调, IIC 接口支持全速 400K 速率。(本博客采用串口通信)

1.2 性能参数

1、 电压: 3.3V~5V
2、 电流: <25mA
3、 测量维度: 加速度: 3 维角速度: 3 维; 磁场: 3 维;角度: 3 维, 气压:1 维(JY-901B);GPS: 3 维(接 GPS 模块)
4、 量程: 加速度:±2/4/8/16 g(可选)角速度:±250/500/1000/2000 °/s(可选) ;角度 X,Z 轴±180°, Y 轴±90°。
5、 数据输出内容: 时间、 加速度、 角速度、 角度、 磁场、 端口状态、 气压(JY-901B) 、高度(JY-901B) 、 经纬度(需连接 GPS) 、 地速(需连接 GPS) 。
6、 数据接口: 串口(TTL 电平, 波特率支持 2400、 4800、 9600(默认) 、 19200、 38400、57600、 115200、 230400、 460800、 921600) , I2C(最大支持高速 IIC 速率 400K)
7.扩展口功能: 模拟输入(0~VCC) 、 数字输入、 数字输出、 PWM 输出(周期 1us-65535us,分辨率 1us)

1.3 实物图和接线


串口通信接线如下:

JY901 单片机
VCC 3.3V 或 5V
RX TX
TX RX
GND GND


IIC通信接线如下:

JY901 单片机
VCC 3.3V 或 5V
SCL I2C 时钟线
SDA I2C 数据线
GND GND


注意: 为了能在 IIC总线上面挂接多个模块, 模块的 IIC 总线是开漏输出的, MCU 在连接模块时需要将 IIC 总线通过一个 4.7K 的电阻上拉到 VCC。
注意: VCC 为 3.3V, 要另外接电源供电。 直接用模块上面的电源供电, 可能会产生压降, 使模块实际电压没有3.3~5V。

2.软件和使用说明书

上位机软件
提取码:nu3h
JY901使用说明书
提取码:apmd

3.串口通信JY901

3.1 cubemx工程配置

利用DMA空闲中断通信。
1.开启串口1并开启对应的中断


2.添加DMA通道

3.2代码编写

参考博客:
STM32 Cubemax(十) ——JY901陀螺仪数据的读取与简单数据处理

3.2.1 DMA空闲中断的开启

1.在usatr.c文件中添加DMA空闲中断

/* USER CODE BEGIN 0 */
extern User_USART JY901_data;//数据变量声明
/* USER CODE END 0 *//* USER CODE BEGIN USART1_Init 2 */__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);  HAL_UART_Receive_DMA(&huart1,JY901_data.RxBuffer,RXBUFFER_LEN);  /* USER CODE END USART1_Init 2 */

2.在stm32f4xxx_it.c文件中编写中断服务程序

/* USER CODE BEGIN PV */
extern User_USART JY901_data;
/* USER CODE END PV *//*** @brief This function handles USART1 global interrupt.*/
void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 */uint32_t temp_flag = 0;uint32_t temp;temp_flag = __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE);if((temp_flag!=RESET))                                                              {__HAL_UART_CLEAR_IDLEFLAG(&huart1);temp = huart1.Instance->SR;                                         temp = huart1.Instance->DR;                                         HAL_UART_DMAStop(&huart1);                                      temp = hdma_usart1_rx.Instance->NDTR;   //F1的板子 temp = hdma_usart3_rx.Instance->CNDTR;              JY901_data.Rx_len = RXBUFFER_LEN-temp;                 JY901_Process();                    //按照自己需求改写这个函数                      JY901_data.Rx_flag = 1;                                            }HAL_UART_Receive_DMA(&huart1,JY901_data.RxBuffer,RXBUFFER_LEN);/* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(&huart1);/* USER CODE BEGIN USART1_IRQn 1 *//* USER CODE END USART1_IRQn 1 */
}

3.2.2 添加JY901.h

淘宝客服提供。

#ifndef __JY901_H
#define __JY901_H#define SAVE           0x00
#define CALSW       0x01
#define RSW             0x02
#define RRATE           0x03
#define BAUD            0x04
#define AXOFFSET    0x05
#define AYOFFSET    0x06
#define AZOFFSET    0x07
#define GXOFFSET    0x08
#define GYOFFSET    0x09
#define GZOFFSET    0x0a
#define HXOFFSET    0x0b
#define HYOFFSET    0x0c
#define HZOFFSET    0x0d
#define D0MODE      0x0e
#define D1MODE      0x0f
#define D2MODE      0x10
#define D3MODE      0x11
#define D0PWMH      0x12
#define D1PWMH      0x13
#define D2PWMH      0x14
#define D3PWMH      0x15
#define D0PWMT      0x16
#define D1PWMT      0x17
#define D2PWMT      0x18
#define D3PWMT      0x19
#define IICADDR     0x1a
#define LEDOFF      0x1b
#define GPSBAUD     0x1c#define YYMM                0x30
#define DDHH                0x31
#define MMSS                0x32
#define MS                  0x33
#define AX                  0x34
#define AY                  0x35
#define AZ                  0x36
#define GX                  0x37
#define GY                  0x38
#define GZ                  0x39
#define HX                  0x3a
#define HY                  0x3b
#define HZ                  0x3c
#define Roll                0x3d
#define Pitch               0x3e
#define Yaw                 0x3f
#define TEMP                0x40
#define D0Status        0x41
#define D1Status        0x42
#define D2Status        0x43
#define D3Status        0x44
#define PressureL       0x45
#define PressureH       0x46
#define HeightL         0x47
#define HeightH         0x48
#define LonL                0x49
#define LonH                0x4a
#define LatL                0x4b
#define LatH                0x4c
#define GPSHeight   0x4d
#define GPSYAW      0x4e
#define GPSVL               0x4f
#define GPSVH               0x50
#define q0          0x51
#define q1          0x52
#define q2          0x53
#define q3          0x54#define DIO_MODE_AIN 0
#define DIO_MODE_DIN 1
#define DIO_MODE_DOH 2
#define DIO_MODE_DOL 3
#define DIO_MODE_DOPWM 4
#define DIO_MODE_GPS 5      struct STime
{unsigned char ucYear;unsigned char ucMonth;unsigned char ucDay;unsigned char ucHour;unsigned char ucMinute;unsigned char ucSecond;unsigned short usMiliSecond;
};
struct SAcc//加速度
{short a[3];short T;
};
struct SGyro//角速度
{short w[3];short T;
};
struct SAngle//角度
{short Angle[3];short T;
};
struct SMag//磁场输出
{short h[3];short T;
};struct SDStatus//端口状态数据输出
{short sDStatus[4];
};struct SPress//气压高度
{long lPressure;long lAltitude;
};struct SLonLat//经纬度
{long lLon;long lLat;
};struct SGPSV
{short sGPSHeight;short sGPSYaw;long lGPSVelocity;
};
struct SQ //四元数
{ short q[4];
};#endif

3.2.3 重定义需要的结构体和JY901数据结构体

typedef struct
{float angle[3];
}Angle;typedef struct
{float a[3];
}Acc;typedef struct
{float w[3];
}SGyro;typedef struct//四元数
{ float q[4];
}SQ;typedef struct//磁场输出
{float h[3];
}SMag;typedef struct//气压高度
{float lPressure;float lAltitude;
}SPress;typedef struct//经纬度
{float lLon;float lLat;
}SLonLat;
typedef struct User_USART
{uint8_t Rx_flag;                                           uint8_t Rx_len;                                             uint8_t frame_head;                 //帧头uint8_t RxBuffer[RXBUFFER_LEN];     //接收缓冲Angle angle;                      //角度Acc acc;                                //加速度SGyro w;                               //角速度SMag h;                                    //磁场SPress lPressure;         //气压SPress lAltitude;         //高度SLonLat lLon;                       //经度SLonLat lLat;                       //维度SQ q;                                   //四元数
}User_USART;

3.2.4 接收结构体初始化

void User_USART_Init(User_USART *Data)
{for(uint16_t i=0; i < RXBUFFER_LEN; i++) Data->RxBuffer[i] = 0;Data->frame_head = 0x55;Data->Rx_flag = 0;Data->Rx_len = 0;
}

3.2.5 数据解算

#define RXBUFFER_LEN 99      //接收9类数据,一共99位User_USART JY901_data;
struct SAcc         stcAcc;
struct SGyro        stcGyro;
struct SAngle   stcAngle;
struct SMag     stcMag;
struct SPress   stcPress;
struct SLonLat  stcLonLat;
struct SQ stcQ;void JY901_Process()
{if(JY901_data.Rx_len < RXBUFFER_LEN) return;    //如果位数不对for(uint8_t i=0;i<9;i++){if(JY901_data.RxBuffer[i*11]!= JY901_data.frame_head) return;   //如果帧头不对switch(JY901_data.RxBuffer[i*11+1]){case 0x51: memcpy(&stcAcc,&JY901_data.RxBuffer[2 + i*11],8);for(uint8_t j = 0; j < 3; j++) JY901_data.acc.a[j] = (float)stcAcc.a[j]/32768*16;break;case 0x52:  memcpy(&stcGyro,&JY901_data.RxBuffer[2 + i*11],8);for(uint8_t j = 0; j < 3; j++) JY901_data.w.w[j] = (float)stcGyro.w[j]/32768*2000;break;case 0x53:            memcpy(&stcAngle,&JY901_data.RxBuffer[2 + i*11],8);for(uint8_t j = 0; j < 3; j++) JY901_data.angle.angle[j] = (float)stcAngle.Angle[j]/32768*180;break;case 0x54:   //磁场解算memcpy(&stcMag,&JY901_data.RxBuffer[2 + i*11],8);for(uint8_t j = 0; j < 3; j++) JY901_data.h.h[j] = (float)stcMag.h[j];break;case 0x55:   //D0-D3端口状态break;case 0x56: //气压高度memcpy(&stcPress,&JY901_data.RxBuffer[2 + i*11],8);          JY901_data.lPressure.lPressure = (float)stcPress.lPressure;JY901_data.lPressure.lAltitude = (float)stcPress.lAltitude/100;break;case 0x57:    //经纬度memcpy(&stcLonLat.lLat,&JY901_data.RxBuffer[2 + i*11],8);JY901_data.lLon.lLat = (float)stcLonLat.lLat/10000000+(double)(stcLonLat.lLat % 10000000)/1e5; JY901_data.lLon.lLat = (float)stcLonLat.lLon/10000000+(double)(stcLonLat.lLon % 10000000)/1e5;break;case 0x58:    //GPSbreak;case 0x59:   //四元数memcpy(&stcQ,&JY901_data.RxBuffer[2 + i*11],8);for(uint8_t j = 0; j < 4; j++) JY901_data.q.q[j] = (float)stcQ.q[j]/32768;      break;  }}
}

3.3现象观测

打开上位机软件,勾选需要测试的数据。


可以看到JY901读取到的数据,作为参考量。

在debug模式,读取到的数据。

4.I2C通信JY901

JY901的I2C通信的排针没有焊,以后抽空更。
I2C通信也可参见该博客。
STM32 CubeMx(六)I2C同步串行通信与EEPROM 24C02的读写

STM32应用(七)JY901九轴姿态模块(串口DMA空闲中断和I2C通信)相关推荐

  1. stm32的串口DMA空闲中断接收不等长数据,stm32F1的usart1-DMA-IDLE收发

    stm32的DMA收发原理,和stm32F4 + USART2 +DMA +IDLE使用,见另一篇:https://blog.csdn.net/Mark_md/article/details/1072 ...

  2. stm32的串口DMA空闲中断接收不等长数据,stm32F4的usart2-DMA-IDLE收发

    1. 串口为什么要使用DMA?好处? 提高系统实时性:stm32单片机的串口没有FIFO,使用字节中断的方式去接收,会频繁进入中断,影响系统实时性.好在stm32的串口可以级联DMA使用,在大数据量连 ...

  3. 学习 STM32之九轴姿态传感器(BWT901CL)串口通信读取数据

    由于个人应用到3轴传感器,所以买了直接买了一个9轴的,用于学习STM32Core平台串口2连接维特智能串口Normal协议,然后通过串口1直接打印数据,接收传感器数据和与传感器进行通信:需要看产品文档 ...

  4. 使用扩展卡尔曼滤波(EKF)进行AHRS九轴姿态融合

    AHRS九轴姿态融合 EKF滤波 卡尔曼滤波 在做九轴姿态融合的过程中,这里介绍一种融合算法,基于EKF的九轴姿态融合算法: 首先表明,该算法并非自己想到的,算法原理参考了这篇论文:Dale E. S ...

  5. 移动端点对点获取WeMos D1上搭载的JY-901九轴振动加速度传感器加速度数据

    1 介绍 暑假里老师给布置了个任务,希望能够避开云端,使用移动端来获取 WeMos D1 上传感器的数据. 那么这里大致的思路就是: 通过串口获取传感器的数据: 在WeMos D1上开启服务以供移动端 ...

  6. 微型四轴飞行器(5)九轴姿态融合算法A

    1 概述 所谓的九轴姿态融合就是将通过传感器获得的3轴加速度.3轴角速度.3轴磁场数据,在相应的算法处理后能够得到飞行器的姿态信息(欧拉角).输入输出如下图 在惯性导航领域的欧拉角分别表示的是航向角( ...

  7. arduino调试BNO080高精准度九轴传感器模块

    arduino调试BNO080高精准度九轴传感器模块 原文链接:https://www.yourcee.com/newsinfo/2925867.html 1.简介 2.原理图 3.使用前准备 4.接 ...

  8. K_A14_003 基于STM32等单片机驱动APDS9960手势运动模块 串口与OLED0.96双显示

    K_A14_003 基于STM32等单片机驱动APDS9960手势运动模块 串口与OLED0.96双显示 一.资源说明 二.基本参数 参数 引脚说明 三.驱动说明 时序 对应程序: 四.部分代码说明 ...

  9. K_A14_012基于STM32等单片机驱动GY-25倾斜度角度模块 串口与OLED0.96双显示

    K_A14_012基于STM32等单片机驱动GY-25倾斜度角度模块 串口与OLED0.96双显示 一.资源说明 二.基本参数 参数 引脚说明 三.驱动说明 对应程序: 四.部分代码说明 1.接线引脚 ...

最新文章

  1. 伍六七带你学算法——被忽视的数学公式
  2. 使用Python、OpenCVImageMagick工具箱制作GIF动画
  3. RIPv1和v2综合实验(CCNP阶段)
  4. BZOJ 4422 Cow Confinement (线段树、DP、扫描线、差分)
  5. java 拦截所有路径_Java或Web中解决所有路径问题
  6. 【linux】使用swap文件恢复非正常关闭的文件
  7. PHP自学3——在html的table标签中显示用户提交表单
  8. nginx-zabbix监控脚本
  9. Java静态变量注入配置值,工具类使用@Value将信息注入到静态变量中
  10. 微服务架构最强讲解,那叫一个通俗易懂!
  11. linux阻止程序,Linux:阻止某些应用程序/主机名的IPv6
  12. 均匀线阵常规波束形成 matlab程序,波束形成Matlab程序
  13. 脚本精灵for+android,脚本精灵 v3.0.8
  14. 【踩坑记录】.bss段;.bss段到底占不占目标文件的空间,有没有记录对应信息。
  15. java-php-python-ssm演唱会购票系统计算机毕业设计
  16. 记录,Cents 7 更改home和root的中文路径
  17. 【pandas】变形(长宽表变换)
  18. 长江雨课堂考试半自动答题python脚本
  19. 【简单】求英文句子的平均单词长度
  20. 物联网设备网络接入方式

热门文章

  1. 服务器经常被攻击怎么办?这7个重要因素要做好!
  2. Python程序员必备——手把手教你配置最漂亮的PyCharm界面
  3. python第一天----爬取优美图库的图片
  4. 德硕ABeam三位顾问获得SAP认证,企业数字转型有保障
  5. IIS6 日志删除脚本(t00ls)
  6. 详解JS中的TDZ(暂时性死区)
  7. 身份证上男女识别--非线性问题02
  8. 网站SEO其实很简单,新手必看!!!
  9. hdu4489-The-King-s-Ups-and-Downs
  10. STM32F103C8T6 点亮LED灯