可拖拽编程网站开发,高质量发展服务业,怎样做网站建设的程序,怀化做网站的公司目录 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接… 目录 RM3100接线HAL库I2C函数HAL_I2C_Mem_ReadHAL_I2C_Mem_WriteHAL_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
hi2ci2cx比如 hi2c1 DevAddress:左移一位的传感器设备地址比如RM3100原来是0x20要输入(0x201)即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_TransmitpData写成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 data0;
HAL_StatusTypeDef status HAL_I2C_Mem_Read(RM3100_I2C,RM3100_ADDRESS,ADDR_HSHAKE,I2C_MEMADD_SIZE_8BIT,data, 1, 1000);uint8_t data0;
uint8_t addr_hshakeADDR_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 0x201 //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.huint8_t RM3100ReadID(void){uint8_t data0;uint8_t addr_hshakeADDR_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 dataPOLL_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 cResult0x80;
// 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_requestPOLL_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,hz0;while (1){RM3100_GetData(hx, hy, hz);printf(RM3100 hx: %d, hy: %d, hz: %d\r\n, hx, hy, hz);HAL_Delay(8);}
}其他功能没写后面慢慢补上
最终效果