STM32 HAL I2C读取HMC5883L磁偏角的实践
STM32 HAL I2C读取HMC5883L磁偏角的实践
- 源由
- 成果
- 代码
- 头文件 G85HAL.h
- 子文件 G85HAL.C
- 主程序调用
- 配置I2C引脚
- 参考链接
源由
用传统的方式编写I2C总线数据读取,程序代码细碎,不好维护,移植性不好。CUBE MX配置方便灵活,程序架构好,有现成的hal I2C函数可调用,仅用HAL_I2C_Mem_Write( … )和 HAL_I2C_Mem_Read(… )就实现了功能,
有车轮就不要自己再做车轮啦!
成果
两条语句就实现了HMC5883L磁偏角的读取,程序代码简洁、可靠。
重点说明:
语句1:
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)
语句2:
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)
参数:
1、I2C指针,即用I2C1 还是 I2C2…,查看CUBE MX配置
2、器件地址uint16_t DevAddress,与所读写的I2C芯片有关,查看芯片资料
3、要写入的内存地址 uint16_t MemAddress,与所读写的I2C芯片有关,查看芯片资料
4、内存地址类型,是一个地址存8bit ,还是16bit数据 , uint16_t MemAddSize,与所读写的I2C芯片有关,查看芯片资料,I2C_MEMADD_SIZE_8BIT和I2C_MEMADD_SIZE_16BIT二选一
5、对于写,是要写入的数组指针uint8_t *pData ;对于读取,是存数据的数组指针uint8_t *pData ;
6、数据 大小(要写入或读取几个字节)
7、多少时间没完成定义为超时,该语句退出
代码
头文件 G85HAL.h
#ifndef __GY85HAL_H
#define __GY85HAL_H #include "stm32f1xx_hal.h"
#include "i2c.h"#define ITG3205_Addr 0x68 //定义器件在IIC总线中的从地址,根据ALT ADDRESS地址引脚不同修改
#define HMC5883L_Addr 0x3C //磁场传感器器件地址//定义HMC5883L配置寄存器地址
#define HMC5883l_CONFIG_A 0x00
#define HMC5883l_CONFIG_B 0x01
#define HMC5883l_MODECONFIG 0x02struct HMC5883L_Data {unsigned char vtemp[12];int x_h; //x方向磁强int y_h; //y方向磁强int z_h; //z方向磁强float angle;
};//***************************************
int g85_makeuint16(int msb, int lsb) ;
void Init_HMC5883L_HAL(I2C_HandleTypeDef *hi2c1);
/**** 读取磁场角度 */
float read_hmc5883l_HAL(I2C_HandleTypeDef *hi2c1,struct HMC5883L_Data *VL_temp);#endif
子文件 G85HAL.C
#include "gy85hal.h"
#include <math.h> //***************************************
//合并两个字节函数int g85_makeuint16(int msb, int lsb)
{return ((msb & 0xFF) << 8) | (lsb & 0xFF);
}//初始化和设置HMC5883L
void Init_HMC5883L_HAL(I2C_HandleTypeDef *hi2c1)
{unsigned char cdata[3]={0x70,0x20,0X00};HAL_I2C_Mem_Write(hi2c1,HMC5883L_Addr,HMC5883l_CONFIG_A, I2C_MEMADD_SIZE_8BIT,cdata, 1, 1000); //HAL_I2C_Mem_Write(hi2c1,HMC5883L_Addr,HMC5883l_CONFIG_B, I2C_MEMADD_SIZE_8BIT, cdata+1, 1, 1000); //设置增益, HAL_I2C_Mem_Write(hi2c1,HMC5883L_Addr,HMC5883l_MODECONFIG, I2C_MEMADD_SIZE_8BIT, cdata+2, 1, 1000); //设置测量模式,连续测量模式
}/**** 读取HMC5883L的磁场角度 */
float read_hmc5883l_HAL(I2C_HandleTypeDef *hi2c1,struct HMC5883L_Data *VL_temp)
{float fangle;int x,y; //用这个库函数,一次读6个字节少,了许多指令的调用 HAL_I2C_Mem_Read(hi2c1, HMC5883L_Addr, 0x03, I2C_MEMADD_SIZE_8BIT, VL_temp->vtemp, 6, 1000); VL_temp->x_h = g85_makeuint16(VL_temp->vtemp[0], VL_temp->vtemp[1]); VL_temp->y_h = g85_makeuint16(VL_temp->vtemp[4], VL_temp->vtemp[5]);VL_temp->z_h = g85_makeuint16(VL_temp->vtemp[2], VL_temp->vtemp[3]);if(VL_temp->x_h>0x7fff) VL_temp->x_h -= 0xffff; //做下预备处理if(VL_temp->y_h>0x7fff) VL_temp->y_h -= 0xffff; y= VL_temp->y_h; x= VL_temp->x_h;if(x == 0) {fangle =180; if(y>0) fangle =0;}if( x < 0) fangle =90+atan((y+0.001)/x)*57.3; //加0.001是为了强制进行浮点数运算,且对精度影响很小if( x > 0) fangle =270+atan((y+0.001)/x)*57.3;VL_temp->angle =fangle;return fangle;}
主程序调用
int main(void)
{/* USER CODE BEGIN 1 */Count1ms=0;CanInteruptFlag=0;int icount=0;int x,y;double fangle,gtan; int i =0;struct HMC5883L_Data HMC_temp;/* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM1_Init();MX_USART1_UART_Init();MX_CRC_Init();MX_IWDG_Init();MX_I2C1_Init();Init_HMC5883L_HAL(&hi2c1);/* USER CODE BEGIN 2 */ /* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */ while (1){HAL_IWDG_Refresh(&hiwdg); //复位看门狗 //在1ms中断中,每过1ms,Count1ms加1if(Count1ms > 500){Count1ms = 0; HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13); //指示程序在运行fangle = read_hmc5883l_HAL(&hi2c1,&HMC_temp); //调用子程序printf("%d %d ",HMC_temp.y_h,HMC_temp.x_h); //从串口送出读到的数据,供调试测试用printf("%0.2f \n\r ",fangle);}// for(icount=0;icount<6;icount++) printf("%d ",HMC_temp.vtemp[icount]);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}
配置I2C引脚
串口收到的数据,比较稳定,每列为Y值,第二列为X值,第三列为折算出来磁偏角(度)
参考链接
[链接]https://www.freesion.com/article/57631089788/ [VL53L0X TOF激光测距的 STM32 HAL库驱动代码] (感谢作者的分享))
STM32 HAL I2C读取HMC5883L磁偏角的实践相关推荐
- STM32 HAL I2C(IIC)通信的序列传输(restart condition)
STM32 HAL I2C(IIC)通信的序列(Seq)传输函数(restart condition) neozng1@hnu.edu.cn 文章目录 STM32 HAL I2C(IIC)通信的序列( ...
- 【51单片机快速入门指南】4.4:I2C 读取HMC5883L / QMC5883L 磁力计
目录 硬知识 简介 操作模式 HMC5883L 连续测量模式 单次测量模式 闲置模式 QMC5883L 连续测量模式 待命模式 主要差异 寄存器 寄存器列表 HMC5883L QMC5883L 配置寄 ...
- arduino i2c 如何写16位寄存器_基于STM32使用I2C读取传感器数据
撑腰会儿:I2C通信协议介绍zhuanlan.zhihu.com 上文介绍了I2C协议的基本结构,今天,使用STM32和LM75A温度传感器来实现I2C读取信息. 首先,为了使用I2C读取传感器测量 ...
- STM8/STM32硬件I2C读取APDS9930程序代码
STM的硬件I2C一直被各种吐槽,实际上只是用起来比较复杂而已,难点主要是在作为Master时的数据接收上,作为Slave时的数据发送没难度,正常用.重点是要真正掌握它里面设计的那个Data shif ...
- STM32单片机硬件I2C读取AHT10温湿度传感器数据
STM32使用硬件IIC读取AHT10温湿度传感器的数据并显示在0.96寸OLED屏上. 我用的单片机是STM32F103C8T6,程序用的是ST标准库写的. STM32使用硬件I2C读取SHTC3温 ...
- STM32使用模拟I2C读取硒翔30mL流量传感器
使用模拟I2C读取硒翔30mL/min流量传感器 该工程使用某些采样次数和时间不同会采集到的报文有问题. 我建议是可以换个次数和时间调下. 如果报文有问题的话 就修改延时就好了,延时指的是I2C每发送 ...
- STM32基于HAL工程读取DHT11数据
STM32基于HAL工程读取DHT11数据 ✨申明:本文章仅发表在CSDN网站,任何其他网站,未注明来源,见此内容均为盗链和爬取,请多多尊重和支持原创!
- STM32 HAL 驱动I2C总线0.91寸OLED模块(基于SSD1306显示驱动芯片)
STM32 HAL 驱动I2C总线0.91寸OLED模块(基于SSD1306显示驱动芯片) 基于SSD1306驱动芯片的OLED模块有多种型号,有0.91英寸,0.96英寸等等.OLED采用单色显示方 ...
- stm32软件模拟I2C读取ADXL345三轴加速度值
最近做一个实验室里的小项目,需要用stm32来读取ADXL345三轴加速度的值,本来硬件I2C都调好了,可是后来和实验室合作的一个公司给的板子却没把硬件I2C的端口给引出来,太伤心了,我又得重新调一下 ...
- stm32 hal库 AS5600磁编码器IIC通信读取角度
stm32 hal库 AS5600磁编码器IIC通信读取角度 下载
最新文章
- 【Quartz】实现接口封装化(二)
- .net thread操作串口_听说你不知道 RT-Thread 有个 ringbuffer
- Visio绘制时序图
- Java黑皮书课后题第7章:**7.19(是否排好序了?)编写以下方法,如果参数中的list数组已经排好序了则返回true。编写一个测试程序,提示用户输入一个列表,显示该列表是否已经排好序
- MFC界面编程新思路--模仿MATLAB式的界面
- spring mvc学习(25):Eclipse设置代码自动提示
- redis配置文件的介绍
- (130)FPGA面试题-FPGA设计中波特率和比特率的区别
- (16)System Verilog禁止类中所有变量随机化
- 深入理解ButterKnife源码并掌握原理(二)
- loss 加权_Multi-Similarity Loss使用通用对加权进行深度度量学习-CVPR2019
- Android 分贝测试仪功能,挥泪整理面经
- 学计算机穿格子衬衫的男人,教你成为穿格子衬衫的帅气理工男
- 【数据挖掘】二手车交易价格预测(三)数据分析
- 刷卡机显示服务器连接失败,pos密码错误_POS机常见故障代码解释
- vscode复制代码到wps中怎么不带黑色背景
- Unity导航小地图制作
- “最难就业季“中的大学生就业:本硕过半有着落 高职生成香饽饽
- msp430中如何连续对位进行取反_如何选择护膝的尺码,手把手教你
- 基于Bootstrap的下拉框多选 Bootstrap Multiselect 插件使用