这里以iSentek公司产出的IST8310型号的磁力计为例,尺寸为 3.0 * 3.0 * 1.0mm,支持快速 I2C 通信,可达 400kHz,14 位磁场数据,测量范围可达1600uT(x,y-axis)和 2500uT(z-axis), 最高 200Hz 输出频率

同时这里的磁力计是安装在大疆公司出产的RoboMaster开发板C型,单片机芯片是STM32F407IGH6,其外围电路已经设计好,只需要读取磁力计数据即可。

本篇不会介绍SPI、I2C等嵌入式通信协议,需要有一定嵌入式开发基础的同学来看

文末附代码

零、数据手册分析

第一章讲了IST8310的特性,I2C通信,最高支持400kHz通信速率,14位或者16位自适应数据输出等特性

第二章讲了内部结构

第三章讲了电气特性

第四章讲了如何联系他们

然后数据手册就没了。。。在大疆的开发手册中找到了寄存器的手册,如下:

一、CubeMX配置

点开I2C配置选项, 下图是配好的:

观察IST8310的数据手册,发现其支持最大400kHz的I2C通信速率,也就是快速I2C模式,所以第一行I2C Speed Mode我们选Fast Mode

同时不要忘记了在C板中I2C3的两个IO口分别是PA8和PC9(一般来说都是这两个)

之后观察大疆和IST8310的数据手册,发现控制IST8310重启的是PG6的GPIO口,低电平为重启,所以我们将其设置为高电平上拉输出模式

因为我们读取IST8310的程序运行在1kHz的freertos线程中,无需使用中断方式,所以我们不配置中断口

二、数据读取

总代码附在文末,这里放一些核心函数

IST8310初始化:

void IST8310_INIT(ist8310_data_t* ist8310_data) {memset(ist8310_data, 0, sizeof(ist8310_data_t));ist8310_data->meg_error = IST8310_NO_ERROR;// 把磁力计重启HAL_GPIO_WritePin(IST8310_GPIOx, IST8310_GPIOp, GPIO_PIN_RESET);HAL_Delay(50);HAL_GPIO_WritePin(IST8310_GPIOx, IST8310_GPIOp, GPIO_PIN_SET);HAL_Delay(50);// 基础配置// 不使能中断,直接读取WriteSingleDataFromIST8310(IST8310_CNTL2_ADDR, IST8310_STAT2_NONE_ALL);// 平均采样四次WriteSingleDataFromIST8310(IST8310_AVGCNTL_ADDR, IST8310_AVGCNTL_FOURTH);// 200Hz的输出频率WriteSingleDataFromIST8310(IST8310_CNTL1_ADDR, IST8310_CNTL1_CONTINUE);ist8310_data->meg_error |= VerifyMegId(&ist8310_data->chip_id);
}

读取单个数据:

uint8_t ReadSingleDataFromIST8310(uint8_t addr) {uint8_t data;HAL_I2C_Mem_Read(&IST8310_I2C, (IST8310_I2C_ADDR << 1), addr, I2C_MEMADD_SIZE_8BIT, &data, 1, 10);return data;
}

读取多个数据:

void ReadMultiDataFromIST8310(uint8_t addr, uint8_t* data, uint8_t len) {HAL_I2C_Mem_Read(&IST8310_I2C, (IST8310_I2C_ADDR << 1), addr, I2C_MEMADD_SIZE_8BIT, data, len, 10);
}

写入单个数据:

void WriteSingleDataFromIST8310(uint8_t addr, uint8_t data) {HAL_I2C_Mem_Write(&IST8310_I2C, (IST8310_I2C_ADDR << 1), addr, I2C_MEMADD_SIZE_8BIT, &data, 1, 10);
}

写入多个数据:

void WriteMultiDataFromIST8310(uint8_t addr, uint8_t* data, uint8_t len) {HAL_I2C_Mem_Write(&IST8310_I2C, (IST8310_I2C_ADDR << 1), addr, I2C_MEMADD_SIZE_8BIT, data, len, 10);
}

这里会发现一个比较有意思的事情,就是这里的地址都左移了一位,是因为根据I2C协议,[7:0]的一个字节的数据,前七位是地址,后一位是代表读或者写的位,这样子就需要把地址左移

读取磁力计数据:

void ReadIST8310Data(ist8310_raw_data_t* meg_data) {uint8_t buf[6];int16_t temp_ist8310_data = 0;ReadMultiDataFromIST8310(IST8310_DATA_XL_ADDR, buf, 6);temp_ist8310_data = (int16_t)((buf[1] << 8) | buf[0]);meg_data->x = MAG_SEN * temp_ist8310_data;temp_ist8310_data = (int16_t)((buf[3] << 8) | buf[2]);meg_data->y = MAG_SEN * temp_ist8310_data;temp_ist8310_data = (int16_t)((buf[5] << 8) | buf[4]);meg_data->z = MAG_SEN * temp_ist8310_data;
}

这里乘了一个系数MAG_SEN,它的值是0.3,是将读取到的数据转化为单位为uT的磁场值

下面就是源码,把IST8310_INIT()函数放在程序开始的地方,然后剩下的读取函数放在不断执行的线程里,就可以得到磁力计数据了

ist8310.c

/*** @Author         : Minghang Li* @Date           : 2022-12-03 14:29* @LastEditTime   : 2022-12-03 16:52* @Note           :* @Copyright(c)   : Minghang Li Copyright*/
#include "ist8310.h"#include <string.h>#include "i2c.h"
#include "ist8310reg.h"void IST8310_INIT(ist8310_data_t* ist8310_data) {memset(ist8310_data, 0, sizeof(ist8310_data_t));ist8310_data->meg_error = IST8310_NO_ERROR;// 把磁力计重启HAL_GPIO_WritePin(IST8310_GPIOx, IST8310_GPIOp, GPIO_PIN_RESET);HAL_Delay(50);HAL_GPIO_WritePin(IST8310_GPIOx, IST8310_GPIOp, GPIO_PIN_SET);HAL_Delay(50);// 基础配置// 不使能中断,直接读取WriteSingleDataFromIST8310(IST8310_CNTL2_ADDR, IST8310_STAT2_NONE_ALL);// 平均采样四次WriteSingleDataFromIST8310(IST8310_AVGCNTL_ADDR, IST8310_AVGCNTL_FOURTH);// 200Hz的输出频率WriteSingleDataFromIST8310(IST8310_CNTL1_ADDR, IST8310_CNTL1_CONTINUE);ist8310_data->meg_error |= VerifyMegId(&ist8310_data->chip_id);
}uint8_t ReadSingleDataFromIST8310(uint8_t addr) {uint8_t data;HAL_I2C_Mem_Read(&IST8310_I2C, (IST8310_I2C_ADDR << 1), addr, I2C_MEMADD_SIZE_8BIT, &data, 1, 10);return data;
}void WriteSingleDataFromIST8310(uint8_t addr, uint8_t data) {HAL_I2C_Mem_Write(&IST8310_I2C, (IST8310_I2C_ADDR << 1), addr, I2C_MEMADD_SIZE_8BIT, &data, 1, 10);
}void ReadMultiDataFromIST8310(uint8_t addr, uint8_t* data, uint8_t len) {HAL_I2C_Mem_Read(&IST8310_I2C, (IST8310_I2C_ADDR << 1), addr, I2C_MEMADD_SIZE_8BIT, data, len, 10);
}void WriteMultiDataFromIST8310(uint8_t addr, uint8_t* data, uint8_t len) {HAL_I2C_Mem_Write(&IST8310_I2C, (IST8310_I2C_ADDR << 1), addr, I2C_MEMADD_SIZE_8BIT, data, len, 10);
}void ReadIST8310Data(ist8310_raw_data_t* meg_data) {uint8_t buf[6];int16_t temp_ist8310_data = 0;ReadMultiDataFromIST8310(IST8310_DATA_XL_ADDR, buf, 6);temp_ist8310_data = (int16_t)((buf[1] << 8) | buf[0]);meg_data->x = MAG_SEN * temp_ist8310_data;temp_ist8310_data = (int16_t)((buf[3] << 8) | buf[2]);meg_data->y = MAG_SEN * temp_ist8310_data;temp_ist8310_data = (int16_t)((buf[5] << 8) | buf[4]);meg_data->z = MAG_SEN * temp_ist8310_data;
}ist8310_error_e VerifyMegId(uint8_t* id) {*id = ReadSingleDataFromIST8310(IST8310_CHIP_ID_ADDR);if (*id != IST8310_CHIP_ID_VAL) {return MEG_ID_ERROR;} else {return IST8310_NO_ERROR;}
}

ist8310.h

/*** @Author         : Minghang Li* @Date           : 2022-12-03 14:29* @LastEditTime   : 2022-12-03 16:49* @Note           :* @Copyright(c)   : Minghang Li Copyright*/
#pragma once#include <stdint.h>typedef struct ist8310_raw_data_t {float x;float y;float z;
} ist8310_raw_data_t;typedef enum ist8310_error_e {IST8310_NO_ERROR = 0x00,MEG_ID_ERROR = 0x01,
} ist8310_error_e;typedef struct ist8310_data_t {uint8_t chip_id;ist8310_raw_data_t meg_data;ist8310_error_e meg_error;
} ist8310_data_t;/*-----整形向uT转换-----*/
#define MAG_SEN 0.3f/*-----I2C接口定义-----*/
#define IST8310_I2C_ADDR 0x0E
#define IST8310_I2C hi2c3/*-----GPIO口定义-----*/
#define IST8310_GPIOx GPIOG
#define IST8310_GPIOp GPIO_PIN_6void IST8310_INIT(ist8310_data_t* ist8310_data);// 基础读取函数
uint8_t ReadSingleDataFromIST8310(uint8_t addr);
void WriteSingleDataFromIST8310(uint8_t addr, uint8_t data);
void ReadMultiDataFromIST8310(uint8_t addr, uint8_t* data, uint8_t len);
void WriteMultiDataFromIST8310(uint8_t addr, uint8_t* data, uint8_t len);// 功能函数
void ReadIST8310Data(ist8310_raw_data_t* meg_data);// 校验函数
ist8310_error_e VerifyMegId(uint8_t* id);

ist8310reg.h

/*** @Author         : Minghang Li* @Date           : 2022-12-03 15:27* @LastEditTime   : 2022-12-03 16:53* @Note           :* @Copyright(c)   : Minghang Li Copyright*/
#pragma once/*-----IST8310寄存器地址-----*/
#define IST8310_CHIP_ID_ADDR 0x00
#define IST8310_CHIP_ID_VAL 0x10#define IST8310_STAT1_ADDR 0x02#define IST8310_DATA_XL_ADDR 0x03
#define IST8310_DATA_XH_ADDR 0x04
#define IST8310_DATA_YL_ADDR 0x05
#define IST8310_DATA_YH_ADDR 0x06
#define IST8310_DATA_ZL_ADDR 0x07
#define IST8310_DATA_ZH_ADDR 0x08#define IST8310_STAT2_ADDR 0x09#define IST8310_CNTL1_ADDR 0x0A
#define IST8310_CNTL1_SLEEP 0x00
#define IST8310_CNTL1_SINGLE 0x01
#define IST8310_CNTL1_CONTINUE 0x0B#define IST8310_CNTL2_ADDR 0x0B
#define IST8310_STAT2_NONE_ALL 0x00#define IST8310_SELF_CHECK_ADDR 0x0C#define IST8310_TEMPL_ADDR 0x1C
#define IST8310_TEMPH_ADDR 0x1D#define IST8310_AVGCNTL_ADDR 0x41
#define IST8310_AVGCNTL_TWICE 0x09
#define IST8310_AVGCNTL_FOURTH 0x12

效果如下:

【超详细】磁力计数据读取--以IST8310为例相关推荐

  1. 一份超详细的数据科学路线图!

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:魔王.陈萍,来源:机器之心 从头开始学习数据科学的免费资源. 如何 ...

  2. 学习pandas全套代码【超详细】数据查看、输入输出、选取、集成、清洗、转换、重塑、数学和统计方法、排序

    大家早上好,本人姓吴,如果觉得文章写得还行的话也可以叫我吴老师.欢迎大家跟我一起走进数据分析的世界,一起学习! 感兴趣的朋友可以关注我的数据分析专栏,里面有许多优质的文章跟大家分享哦. 本篇博客将会给 ...

  3. (超详细)大数据Hadoop之HDFS组件

    一. HDFS简介 1.1 HDFS的概述 在Hadoop生态圈中,HDFS属于底层基础,负责存储文件. 1.2 HDFS产生背景 HDFS全称为Hadoop Distributed File Sys ...

  4. (超详细)大数据Hadoop之MapReduce组件

    一.MapReduce 简介 1.1 MapReduce的概述 在Hadoop生态圈中,MapReduce属于核心,负责进行分布式计算. MapReduce 核心功能是将用户编写的业务逻辑代码和自带默 ...

  5. 超详细:Java 读取 Windows 共享文件夹中的文件,并下载到本地电脑中

    目录 JCIFS 介绍 SMB协议 设置共享文件夹(这里我们选择有密码的方式进行共享) 是否设置密码 创建 smb 协议 测试 使用代码将文件夹里的文件下载到本地 项目常常需要有访问共享文件夹的需求, ...

  6. 好程序员大数据教程分享超详细大数据学习路线

    随着信息产业的迅猛发展,大数据应用逐渐落地,行业人才需求量逐年扩大.大数据成为目前最具前景的高薪行业之一,大数据分析工程师.大数据开发工程师等大数据人才也成为市场紧缺型人才,薪资一涨再涨. 很多人想要 ...

  7. MySQL的查询(超详细附带数据供练习)

    0. 准备数据 -- 创建数据库 create database db_python charset=utf8;-- 使用数据库 use db_python;-- students表 create t ...

  8. 2021年超全超详细的最新大数据开发面试题,附答案解析

    版本 时间 描述 V1.0 2020-12-18 创建 V1.2 2021-01-17 新增 spark 面试题 V1.3 2021-01-18 新增 kafka 面试题 V1.4 2021-01-2 ...

  9. MySQL数据库面试题(超详细)

    一.数据库基础知识 为什么要使用数据库 数据保存在内存 优点: 存取速度快 缺点: 数据不能永久保存 数据保存在文件 优点: 数据永久保存 缺点:1)速度比内存操作慢,频繁的IO操作. 2)查询数据不 ...

最新文章

  1. python程序员在公司都是做什么的-在一家公司呆了 10 年的程序员,最后都怎么了?...
  2. 远程桌面与本地桌面实现文件传输
  3. 有的人在25岁时就死了,但在75岁时才被埋葬:周鸿祎
  4. JAva入门 活着_java基础回顾
  5. (10)C#偷懒的开始永无止境的循环?
  6. 这 10 个云计算错误,会让你的业务一蹶不振!
  7. linux中的码字软件,码字写作软件下载
  8. c语言 b的作用,在C语言中各个标点符号的作用
  9. t-sql 调用作业
  10. 手机越“清理”越卡顿,清理软件“坑”过你吗?
  11. KITTI Odometry数据集处理:将全局pose转换为帧间pose转换
  12. 哈佛php公开课,哈佛公开课
  13. 在子窗体中点击超级链接,关闭子窗体并刷新打开它的父窗体
  14. webrtc VAD 算法
  15. 数据库(Mysql)的事物详解
  16. 基于android的校园社区平台
  17. 如何与ChatGPT交流,获得你想要的答案?正确提问是关键
  18. 使用fastboot命令刷机
  19. 《计算方法》笔记之(二)线性代数方程组之Gauss消去法
  20. 传感器与测试技术-基于MATLAB的二阶系统固有频率和阻尼测量方法

热门文章

  1. Qt LINK : fatal error LNK1104: 无法打开文件“xxx.lib”
  2. 常用公共类代码一之数据库的连接
  3. 关于字符串旋转问题的一些心得
  4. 广度优先搜索:迷宫问题
  5. Java 引用变量和实体变量
  6. 循环冗余校验码CRC原理和实例
  7. Flutter中获取监听屏幕方向、锁定屏幕方向
  8. vijos1196吃糖果游戏
  9. Linear Discriminant Analysis (LDA)
  10. 循环语句:for 语句详解