当前位置: 首页 > news >正文

RM3100 stm32驱动(硬件i2c)

目录

  • RM3100接线
  • HAL库I2C函数
    • HAL_I2C_Mem_Read
    • HAL_I2C_Mem_Write
    • HAL_I2C_Master_Transmit / HAL_I2C_Master_Receive
    • 例子 HSHAKE寄存器
  • cubemx配置
  • RM3100寄存器
  • 驱动
  • 最终效果

RM3100接线

原理图
在这里插入图片描述

在这里插入图片描述
SA0 SA1接地,此时i2c设备地址为0100000,即0x20
如果SA0接高,SA1接地,地址为0100001,即0x21
如果SA0接地,SA1接高,地址为0100010,即0x22
SDA SCL正常接单片机,要上拉
I2C/SPI接高,选择I2C模式

手册下载链接

HAL库I2C函数

stm32 hal库对于i2c的操作有几个函数:

HAL_I2C_Mem_Read

hi2c:i2cx,比如 &hi2c1
DevAddress:左移一位的传感器设备地址,比如RM3100原来是0x20,要输入(0x20<<1)即0x40
MemAddress:要读取的寄存器地址,这个不用左移,按照手册里面即可,比如HSHAKE寄存器就是0x35
MemAddSize:一般I2C_MEMADD_SIZE_8BIT
后面几个正常写即可,pData传指针把读出来数据传递出来,比如HSHAKE寄存器(0x35)读出来就是0x1B

/*** @brief  Read an amount of data in blocking mode from a specific memory address* @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains*                the configuration information for the specified I2C.* @param  DevAddress Target device address: The device 7 bits address value*         in datasheet must be shifted to the left before calling the interface* @param  MemAddress Internal memory address* @param  MemAddSize Size of internal memory address* @param  pData Pointer to data buffer* @param  Size Amount of data to be sent* @param  Timeout Timeout duration* @retval HAL status*/
HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)

HAL_I2C_Mem_Write

和上面类似,不同的是pData 变成了往里面写的数据

/*** @brief  Write an amount of data in blocking mode to a specific memory address* @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains*                the configuration information for the specified I2C.* @param  DevAddress Target device address: The device 7 bits address value*         in datasheet must be shifted to the left before calling the interface* @param  MemAddress Internal memory address* @param  MemAddSize Size of internal memory address* @param  pData Pointer to data buffer* @param  Size Amount of data to be sent* @param  Timeout Timeout duration* @retval HAL status*/
HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)

HAL_I2C_Master_Transmit / HAL_I2C_Master_Receive

这俩成对用,可以看到他俩都么有MemAddress
先调用HAL_I2C_Master_Transmit,pData写成MemAddress地址,再调用HAL_I2C_Master_Receive收数据

/*** @brief  Transmits in master mode an amount of data in blocking mode.* @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains*                the configuration information for the specified I2C.* @param  DevAddress Target device address: The device 7 bits address value*         in datasheet must be shifted to the left before calling the interface* @param  pData Pointer to data buffer* @param  Size Amount of data to be sent* @param  Timeout Timeout duration* @retval HAL status*/
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
/*** @brief  Receives in master mode an amount of data in blocking mode.* @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains*                the configuration information for the specified I2C.* @param  DevAddress Target device address: The device 7 bits address value*         in datasheet must be shifted to the left before calling the interface* @param  pData Pointer to data buffer* @param  Size Amount of data to be sent* @param  Timeout Timeout duration* @retval HAL status*/
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)

例子 HSHAKE寄存器

两种写法,data即为读出来数据,应该是0x1B

uint8_t data=0;
HAL_StatusTypeDef status = HAL_I2C_Mem_Read(&RM3100_I2C,RM3100_ADDRESS,ADDR_HSHAKE,I2C_MEMADD_SIZE_8BIT,&data, 1, 1000);
uint8_t data=0;
uint8_t addr_hshake=ADDR_HSHAKE;//0x35
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&RM3100_I2C,RM3100_ADDRESS,&addr_hshake,1,1000); //addr_hshake要写成目标寄存器地址
status = HAL_I2C_Master_Receive(&RM3100_I2C,(RM3100_ADDRESS|1),&data,1,1000);

cubemx配置

正常使用I2C即可,选择fast mode,最高400k可以工作
在这里插入图片描述
需要上拉,最好硬件上也拉一下
在这里插入图片描述

RM3100寄存器

在这里插入图片描述
上面提示了对于I2C,读写地址不一样,因为有一位0/1标志着读/写,但是不用管,hal库帮我们搞好了,直接对着第二列填MemAddress即可
在这里插入图片描述

驱动

采用poll写法,参考手册5.3 5.8 5.8.2
.h文件

#ifndef __RM3100_H
#define __RM3100_H
#include "main.h"
#include "i2c.h"#define RM3100_I2C hi2c1
#define RM3100_ADDRESS 0x20<<1 //AD0 AD1都接地#define RM3100_CONVERSION_INTERVAL	10000	// Microseconds, corresponds to 100 Hz (cycle count 200 on 3 axis)
#define UTESLA_TO_GAUSS			100.0f
#define RM3100_SENSITIVITY		75.0f#define ADDR_POLL		0x00
#define ADDR_CMM		0x01
#define ADDR_CCX		0x04
#define ADDR_CCY		0x06
#define ADDR_CCZ		0x08
#define ADDR_TMRC		0x0B
#define ADDR_MX			0x24
#define ADDR_MY			0x27
#define ADDR_MZ			0x2A
#define ADDR_BIST		0x33
#define ADDR_STATUS		0x34
//#define ADDR_STATUS_READ		0xB4 //0X34|0X80
#define ADDR_HSHAKE		0x35
#define ADDR_REVID		0x36#define CCX_DEFAULT_MSB		0x00
#define CCX_DEFAULT_LSB		0xC8
#define CCY_DEFAULT_MSB		CCX_DEFAULT_MSB
#define CCY_DEFAULT_LSB		CCX_DEFAULT_LSB
#define CCZ_DEFAULT_MSB		CCX_DEFAULT_MSB
#define CCZ_DEFAULT_LSB		CCX_DEFAULT_LSB
#define CMM_DEFAULT		0x70	// No continuous mode
#define CONTINUOUS_MODE		(1 << 0)
#define POLLING_MODE		(0 << 0)
#define TMRC_DEFAULT		0x94
#define BIST_SELFTEST		0x8F
#define BIST_DEFAULT		0x00
#define BIST_XYZ_OK		((1 << 4) | (1 << 5) | (1 << 6))
#define STATUS_DRDY		(1 << 7)
#define POLL_XYZ		0x70
#define RM3100_REVID		0x22#define NUM_BUS_OPTIONS		(sizeof(bus_options)/sizeof(bus_options[0]))uint8_t RM3100ReadID(void);
uint8_t RM3100_Init(void);
uint8_t RM3100_GetData(short *x,short *y,short*z);
uint8_t RM3100_CheckDataReady(void);
#endif

.c文件

#include "RM3100.h"uint8_t RM3100ReadID(void){uint8_t data=0;uint8_t addr_hshake=ADDR_HSHAKE;
//	HAL_StatusTypeDef status = HAL_I2C_Mem_Read(&RM3100_I2C,RM3100_ADDRESS,ADDR_HSHAKE,I2C_MEMADD_SIZE_8BIT,&data, 1, 1000);HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&RM3100_I2C,RM3100_ADDRESS,&addr_hshake,1,1000); //addr_hshake要写成目标寄存器地址status = HAL_I2C_Master_Receive(&RM3100_I2C,(RM3100_ADDRESS|1),&data,1,1000);//两种写法都可以,读取0x35寄存器值,并与1b进行比较if(status!=HAL_OK){printf("RM3100 I2C Error!\r\n");return 1;}else{if(data!=0x1B){printf("RM3100 detected Error! %x\r\n",data);return 1;}else{printf("RM3100 Address = %x\r\n",data);return 0;}}
}uint8_t RM3100_Init(void){uint8_t CCR[6] = {0, 200, 0, 200, 0, 200};if(RM3100ReadID()) {return 1;}else{HAL_StatusTypeDef status = HAL_I2C_Mem_Write(&RM3100_I2C,RM3100_ADDRESS,ADDR_CCX,I2C_MEMADD_SIZE_8BIT,CCR, 6, 1000);//发送一次poll请求,开始测量uint8_t data=POLL_XYZ;HAL_StatusTypeDef status1 = HAL_I2C_Mem_Write(&RM3100_I2C,RM3100_ADDRESS,ADDR_POLL,I2C_MEMADD_SIZE_8BIT,&data, 1, 1000);if(status!=HAL_OK | status1!=HAL_OK){printf("Error!,status=%d,status1=%d\r\n",status,status1);return 1;}else{return 0;}		}
}uint8_t RM3100_CheckDataReady(void)
{uint8_t cResult;HAL_I2C_Mem_Read(&RM3100_I2C,RM3100_ADDRESS,ADDR_STATUS,I2C_MEMADD_SIZE_8BIT,&cResult,1,1000);cResult = cResult&0x80;
//	printf("%x\r\n",cResult);return cResult; 
}uint8_t RM3100_GetData(short *x,short *y,short*z){static long Mag_Data[3] = {0};uint8_t temp[9]={0};uint8_t poll_request=POLL_XYZ;if(RM3100_CheckDataReady()==0x80){//data ready//读取9个字节HAL_StatusTypeDef status = HAL_I2C_Mem_Read(&RM3100_I2C,RM3100_ADDRESS,ADDR_MX,I2C_MEMADD_SIZE_8BIT,temp, 9, 1000);Mag_Data[0]= (long)temp[0]<<16 | (long)temp[1]<<8 | temp[2];if(Mag_Data[0] >= 0x00800000) {Mag_Data[0] |= 0xff000000;}Mag_Data[1] = (long)temp[3]<<16 | (long)temp[4]<<8 | temp[5];if(Mag_Data[1] >= 0x00800000) {Mag_Data[1] |= 0xff000000;}Mag_Data[2] = (long)temp[6]<<16 | (long)temp[7]<<8 | temp[8];if(Mag_Data[2] >= 0x00800000) {Mag_Data[2] |= 0xff000000;}*y = -Mag_Data[0];*x = -Mag_Data[1];*z = -Mag_Data[2];//发送一次poll请求,开始测量HAL_StatusTypeDef status1 = HAL_I2C_Mem_Write(&RM3100_I2C,RM3100_ADDRESS,ADDR_POLL,I2C_MEMADD_SIZE_8BIT,&poll_request, 1, 1000);if(status!=HAL_OK | status1!=HAL_OK){printf("Error!,status=%d,status1=%d\r\n",status,status1);return 1;}else{return 0;}}else{printf("Data Not Ready!\r\n");return 1;}
}

主函数:

int main(void)
{//初始化……RM3100_Init();short hx,hy,hz=0;while (1){RM3100_GetData(&hx, &hy, &hz);printf("RM3100 hx: %d, hy: %d, hz: %d\r\n", hx, hy, hz);HAL_Delay(8);}
}

其他功能没写,后面慢慢补上

最终效果

在这里插入图片描述
在这里插入图片描述

相关文章:

RM3100 stm32驱动(硬件i2c)

目录 RM3100接线HAL库I2C函数HAL_I2C_Mem_ReadHAL_I2C_Mem_WriteHAL_I2C_Master_Transmit / HAL_I2C_Master_Receive例子 HSHAKE寄存器 cubemx配置RM3100寄存器驱动最终效果 RM3100接线 原理图 SA0 SA1接地&#xff0c;此时i2c设备地址为0100000&#xff0c;即0x20 如果SA0接…...

视觉学习(7) —— 接收数据和发送数据以及全局变量和浮点数

1、前提 创建一个四个字节的地址 2、发送数据 &#xff08;1&#xff09;直接发送数据 再观察地址里的值 与我们想要值不一样 输入0&#xff0c;而实际值则为 结论&#xff1a;直接输入值到地址&#xff0c;值会发生变化 &#xff08;2&#xff09;走全局变量发送数据 添加全…...

leetcode 1576. 替换所有的问号(easy)(优质解法)

链接&#xff1a;1576. 替换所有的问号 代码&#xff1a; class Solution {public String modifyString(String s) {char[] charSs.toCharArray();int lengthcharS.length;//遍历找到 &#xff1f;for(int i0;i<length;i){if(charS[i]?){//遍历 a ~ z 选择一个合适的字符来…...

Advanced IP Scanner - 网络扫描器

Advanced IP Scanner - 网络扫描器 1. Advanced IP ScannerReferences https://www.advanced-ip-scanner.com/cn/ ​ 可靠且免费的网络扫描器可以分析 LAN。该程序可扫描所有网络设备&#xff0c;使您能够访问共享文件夹和 FTP 服务器&#xff0c;(通过 RDP 和 Radmin) 远程控制…...

搜索百度百科官方创建入口,怎么创建更新公司的百度百科词条呢?

在百度搜索百度百科找到百度百科官方创建入口&#xff0c;可以上传并创建公司类的百度百科词条&#xff0c;创建词条后还可以再修改更新百科词条&#xff0c;最终完善好的百度百科词条将会在百度上获得大量曝光。那么百度百科可以怎么创建&#xff0c;下面洛希爱做百科网把十多…...

大数据与人工智能|全面数字化战略与企业数字化转型(第1节 )

要点一&#xff1a;培养跨学科思维 在分析时&#xff0c;需要采用多学科的思维方式 结果不重要&#xff0c;重要的是如何提炼现象、分析问题和得出结论的过程。 1. 介绍了锤子精神和多学科思维方式的重要性。指出了只从自身学科出发解决问题的局限性。 2. 提倡跨学科思维方式&a…...

【四】【C语言\动态规划】地下城游戏、按摩师、打家劫舍 II,三道题目深度解析

动态规划 动态规划就像是解决问题的一种策略&#xff0c;它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题&#xff0c;并将每个小问题的解保存起来。这样&#xff0c;当我们需要解决原始问题的时候&#xff0c;我们就可以直接利…...

【大数据存储与处理】开卷考试总复习笔记

文章目录 实验部分一、 HBase 的基本操作1. HBase Shell入门2. HBase创建数据库表3. HBase数据操作4. HBase删除数据库表5. HBase Python基本编程 before二、 HBase 过滤器操作1.创建表和插入数据2.行键过滤器3.列族与列过滤器4.值过滤器5.其他过滤器6.python hbase 过滤器编程…...

HTML 实操试题(一)

创建一个包含标题、段落和链接的基本HTML文档&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><ti…...

创龙瑞芯微RK3568设备树1(修改设备树GPIO和串口)

前言 最近一直在搞3568的东西&#xff0c;涉及到底层的设备树修改&#xff0c;驱动编写等等&#xff0c;忙的焦头烂额的&#xff0c;也没时间往下面写东西了。今天差不多底层的东西快弄完了&#xff0c;把最近的感悟给大家分享下&#xff0c;并且加入点设备树的基础知识。给刚刚…...

R语言【dplyr】——filter保留符合筛选条件的行,以数据的行为单位,创建子集

Package dplyr version 1.1.4 Parameters filter(.data, ..., .by NULL, .preverse FALSE) 参数【.data】&#xff1a;一个数据集&#xff08;data frame&#xff09;&#xff0c;数据集扩展&#xff08;比如&#xff1a;tibble&#xff09;&#xff0c;或者 lazy data fra…...

几种串口扩展电路

一、IIC串口扩展电路 LCT200 是一款可以通过 I2C 接口通讯&#xff0c;拓展 2 路独立串口的通讯芯片&#xff0c;同时也支持通过 2 路串口读写 I2C 接口的数据。LCT200 的封装为 TSSOP-20。 主要功能&#xff1a;⚫ 通过对 I2C 接口读写实现拓展 2 路独立串口功能 ⚫ 通过读写…...

实战10 角色管理

目录 1、角色后端接口 2、角色列表查询 2.1 效果图 2.2页面原型代码 2.3 角色api代码 role.js 2.4 查询角色列表代码 4、 新增和编辑角色 5、删除角色 6、分配权限 6.1 分配权限思路 6.2 分配权限回显接口 6.3 分配权限回显前端实现 6.4分配权限后端接口 6.4.1 R…...

Lua的底层原理与C#交互原理浅析【更新中】

目录 lua底层原理浅析 table底层原理浅析 Lua表的C语言定义 原理和实现 userdata lua和C#的交互机制&#xff08;更新中&#xff09; 基本介绍 Lua 与 C/C 的数据交互 Lua 调用 C/C 函数 C/C 调用 Lua 函数 基元类型传递 对象类型传递 Lua 调用 C# 总结 网上有很…...

鸿蒙项目二—— 注册和登录

此部分和上篇文章是连续剧 &#xff0c;如果需要&#xff0c;请查看 一、注册 import http from ohos.net.http; Entry Component struct Reg {// 定义数据&#xff1a;State username: string "";State userpass: string "";State userpass2: string …...

Dijkstra(迪杰斯特拉)算法总结

知识概览 Dijkstra算法适用于解决所有边权都是正数的最短路问题。Dijkstra算法分为朴素的Dijkstra算法和堆优化版的Dijkstra算法。朴素的Dijkstra算法时间复杂度为&#xff0c;适用于稠密图。堆优化版的Dijkstra算法时间复杂度为&#xff0c;适用于稀疏图。稠密图的边数m和是一…...

设计模式?!

如何解决复杂性 链接&#xff1a;不同的设计模式实例代码&#xff08;更新中&#xff09; 分解 人们面对复杂性有一个常见的做法&#xff1a;即分而治之&#xff0c;将大问题分解为多个小问题&#xff0c;将复杂问题分解为多个简单问题。 抽象 更高层次来讲&#xff0c;人们处…...

Pytorch项目,肺癌检测项目之三

成功获取到数据之后&#xff0c;我们需要将数据放到Pytorch里面去处理&#xff0c;我们需要将其转换成Dataset数据集&#xff0c;方便去使用相同的API。要转换成Dataset数据集需要实现两个方法&#xff0c;方法一&#xff1a; 方法二&#xff1a; 运行比较慢的话&#xff0c…...

深圳鼎信|输电线路防山火视频监控预警装置:森林火灾来袭,安全不留白!

受线路走廊制约和环保要求影响&#xff0c;输电线路大多建立在高山上&#xff0c;不仅可以减少地面障碍物和人类活动的干扰&#xff0c;还能提高线路的抗灾能力和可靠性。但同时也会面临其它的难题&#xff0c;例如森林火灾预防。今天&#xff0c;深圳鼎信智慧将从不同角度分析…...

【Bash/Shell】知识总结

文章目录 1. 总体认识1.1. Shell概述1.2. 第一个Shell脚本1.3. 注释 2. 变量2.1. 定义变量2.2. 使用变量2.3. 只读变量2.4. 删除变量2.5. 变量类型2.5.1. 字符串变量2.5.2. 整数变量2.5.3. 数组变量2.5.4. 环境变量2.5.5. 特殊变量 3. 输出3.1. echo命令3.2. printf命令 4. 运算…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...