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磁偏角的实践相关推荐

  1. STM32 HAL I2C(IIC)通信的序列传输(restart condition)

    STM32 HAL I2C(IIC)通信的序列(Seq)传输函数(restart condition) neozng1@hnu.edu.cn 文章目录 STM32 HAL I2C(IIC)通信的序列( ...

  2. 【51单片机快速入门指南】4.4:I2C 读取HMC5883L / QMC5883L 磁力计

    目录 硬知识 简介 操作模式 HMC5883L 连续测量模式 单次测量模式 闲置模式 QMC5883L 连续测量模式 待命模式 主要差异 寄存器 寄存器列表 HMC5883L QMC5883L 配置寄 ...

  3. arduino i2c 如何写16位寄存器_基于STM32使用I2C读取传感器数据

    撑腰会儿:I2C通信协议介绍​zhuanlan.zhihu.com 上文介绍了I2C协议的基本结构,今天,使用STM32和LM75A温度传感器来实现I2C读取信息. 首先,为了使用I2C读取传感器测量 ...

  4. STM8/STM32硬件I2C读取APDS9930程序代码

    STM的硬件I2C一直被各种吐槽,实际上只是用起来比较复杂而已,难点主要是在作为Master时的数据接收上,作为Slave时的数据发送没难度,正常用.重点是要真正掌握它里面设计的那个Data shif ...

  5. STM32单片机硬件I2C读取AHT10温湿度传感器数据

    STM32使用硬件IIC读取AHT10温湿度传感器的数据并显示在0.96寸OLED屏上. 我用的单片机是STM32F103C8T6,程序用的是ST标准库写的. STM32使用硬件I2C读取SHTC3温 ...

  6. STM32使用模拟I2C读取硒翔30mL流量传感器

    使用模拟I2C读取硒翔30mL/min流量传感器 该工程使用某些采样次数和时间不同会采集到的报文有问题. 我建议是可以换个次数和时间调下. 如果报文有问题的话 就修改延时就好了,延时指的是I2C每发送 ...

  7. STM32基于HAL工程读取DHT11数据

    STM32基于HAL工程读取DHT11数据 ✨申明:本文章仅发表在CSDN网站,任何其他网站,未注明来源,见此内容均为盗链和爬取,请多多尊重和支持原创!

  8. STM32 HAL 驱动I2C总线0.91寸OLED模块(基于SSD1306显示驱动芯片)

    STM32 HAL 驱动I2C总线0.91寸OLED模块(基于SSD1306显示驱动芯片) 基于SSD1306驱动芯片的OLED模块有多种型号,有0.91英寸,0.96英寸等等.OLED采用单色显示方 ...

  9. stm32软件模拟I2C读取ADXL345三轴加速度值

    最近做一个实验室里的小项目,需要用stm32来读取ADXL345三轴加速度的值,本来硬件I2C都调好了,可是后来和实验室合作的一个公司给的板子却没把硬件I2C的端口给引出来,太伤心了,我又得重新调一下 ...

  10. stm32 hal库 AS5600磁编码器IIC通信读取角度

    stm32 hal库 AS5600磁编码器IIC通信读取角度 下载

最新文章

  1. 【Quartz】实现接口封装化(二)
  2. .net thread操作串口_听说你不知道 RT-Thread 有个 ringbuffer
  3. Visio绘制时序图
  4. Java黑皮书课后题第7章:**7.19(是否排好序了?)编写以下方法,如果参数中的list数组已经排好序了则返回true。编写一个测试程序,提示用户输入一个列表,显示该列表是否已经排好序
  5. MFC界面编程新思路--模仿MATLAB式的界面
  6. spring mvc学习(25):Eclipse设置代码自动提示
  7. redis配置文件的介绍
  8. (130)FPGA面试题-FPGA设计中波特率和比特率的区别
  9. (16)System Verilog禁止类中所有变量随机化
  10. 深入理解ButterKnife源码并掌握原理(二)
  11. loss 加权_Multi-Similarity Loss使用通用对加权进行深度度量学习-CVPR2019
  12. Android 分贝测试仪功能,挥泪整理面经
  13. 学计算机穿格子衬衫的男人,教你成为穿格子衬衫的帅气理工男
  14. 【数据挖掘】二手车交易价格预测(三)数据分析
  15. 刷卡机显示服务器连接失败,pos密码错误_POS机常见故障代码解释
  16. vscode复制代码到wps中怎么不带黑色背景
  17. Unity导航小地图制作
  18. “最难就业季“中的大学生就业:本硕过半有着落 高职生成香饽饽
  19. msp430中如何连续对位进行取反_如何选择护膝的尺码,手把手教你
  20. 基于Bootstrap的下拉框多选 Bootstrap Multiselect 插件使用

热门文章

  1. 协调端到端的供应链管理——SCM
  2. 「案例分析」生鲜行业B2B供应链平台开发案例
  3. 组件上传之AspUpload使用方法
  4. Java serialVersionUID
  5. [SDOI2016]征途
  6. 最简单的易班打卡脚本
  7. Mac下修改HD3000显存到1GB
  8. SOC厂商--全志瑞芯微
  9. Mari 仿制图章 Clone Stamp的使用
  10. 看完这篇解决你99%的运维安全陋习,快别踩坑了!