STM32模拟I2C协议获取HMC5883L电子罗盘磁角度数据 (HAL)

article/2025/10/13 17:37:36

STM32模拟I2C协议获取HMC5883L电子罗盘磁角度数据(HAL)

HMC5883L 传感器采用霍尼韦尔各向异性磁阻(AMR)技术,应用于罗盘和三轴磁场角度检测领域,常用于水平物体转动的角度识别。HMC5883L 采用I2C总线接口,2.16~3.6V供电范围,带有校准测试功能。

HMC5883L的硬件连接

在这里插入图片描述
HMC5883L的硬件连接有5个管脚,除了VCC和GND,以及I2C的SCK和SDA,还有一根INT中断线,用于向MCU报告数据可读取。

HMC5883L的寄存器说明

HMC5883L有如下的一些寄存器,按作用分为4种:
在这里插入图片描述

地址00~02用于配置测试过程中的采样平均次数,数据输出率,测量配置(对应正常或自检测试),增益配置,测量模式(正常或自检测试)。
地址03~08存放测试结果数据,每轴16位,用两个字节存放,注意这6个地址对应的顺序是 X轴–Z轴–Y轴,而不是 X轴–Y轴–Z轴。
地址09是状态的读寄存器,可以通过读取状态获得结果数据是否可读取,替代的方式使用HMC5883L输出的上升沿硬件中断线。
地址10~12存放一些识别码,一般用于读出比较,验证I2C总线访问是否成功。

STM32工程基本配置

这里以STM32G030F6P6以及STM32CUBEIDE开发平台为例,通过模拟I2C访问HMC5883L的方式,实现地磁角度的识别,实现的功能有:

  1. 写读HMC5883L内部寄存器
  2. 配置HMC5883L为正常工作模式,并获取地磁角度数据
  3. 配置HMC5883L为自检工作模式,实现自检校准系数的应用
  4. 实现HMC5883L的温度校准系数的生成和应用

首先建立基本工程并配置时钟:
在这里插入图片描述
配置UART2串口用于打印输出:
在这里插入图片描述
任选三个GPIO用于接口HMC5883L,这里用:
PA0: INT
PA4: SCK
PA5: SDA
PA0配置为上升沿触发中断管脚并使能中断:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
I2C配置为Open-drain模式:
在这里插入图片描述
在这里插入图片描述
保存并生成初始工程代码:
在这里插入图片描述
注意如果代码编译后空间不够,参考 STM32 region `FLASH‘ overflowed by xxx bytes 问题解决

STM32工程组件代码

  1. 工程里会使用printf打印输出,相关的代码部分说明参考 STM32 UART串口printf函数应用及浮点打印代码空间节省 (HAL)

  2. 模拟I2C的实现部分要用到微秒级延时函数,相关的代码部分说明参考 STM32 HAL us delay(微秒延时)的指令延时实现方式及优化
    I2C基本访问的代码如下:

void I2C_Init(void)
{SCL_OUT_H;SDA_OUT_H;PY_Delay_us_t(2000000); //Provide device stability time}void I2C_Start(void)
{PY_Delay_us_t(us_num) ;SDA_OUT_H;SCL_OUT_H;PY_Delay_us_t(us_num/2) ;SDA_OUT_L;PY_Delay_us_t(us_num/2) ;SCL_OUT_L;
}void I2C_Stop(void)
{SCL_OUT_L;PY_Delay_us_t(us_num) ;SDA_OUT_L;PY_Delay_us_t(us_num) ;SCL_OUT_H;PY_Delay_us_t(us_num) ;SDA_OUT_H;PY_Delay_us_t(us_num) ;
}void I2C_Write_Ack(void)
{PY_Delay_us_t(us_num/2) ;SDA_OUT_L;PY_Delay_us_t(us_num/2) ;SCL_OUT_H;PY_Delay_us_t(us_num) ;SCL_OUT_L;SDA_OUT_H;}uint8_t I2C_Read_Ack(void)
{uint8_t status=0;SCL_OUT_L;PY_Delay_us_t(us_num/2) ;SDA_OUT_H;PY_Delay_us_t(us_num/2) ;status = SDA_IN;SCL_OUT_H;PY_Delay_us_t(us_num) ;SCL_OUT_L;SDA_OUT_L;return status;}void I2C_Send_Byte(uint8_t txd){for(uint8_t i=0;i<8;i++){PY_Delay_us_t(us_num/2) ;if((txd&0x80)>>7) SDA_OUT_H;else SDA_OUT_L;txd<<=1;PY_Delay_us_t(us_num/2) ;SCL_OUT_H;PY_Delay_us_t(us_num) ;SCL_OUT_L;}SDA_OUT_L;
}uint8_t I2C_Read_Byte(unsigned char rdack)
{uint8_t rxd=0;for(uint8_t i=0;i<8;i++ ){SCL_OUT_L;PY_Delay_us_t(us_num/2) ;SDA_OUT_H;PY_Delay_us_t(us_num/2) ;SCL_OUT_H;rxd<<=1;if(SDA_IN) rxd++;PY_Delay_us_t(us_num) ;}SCL_OUT_L;SDA_OUT_H;if (rdack) I2C_Write_Ack();return rxd;
}

3. HMC5883L的访问操作代码:

#define CRA 0x00
#define CRB 0x01
#define MR 0x02
#define DOXMR 0x03
#define DOXLR 0x04
#define DOZMR 0x05
#define DOZLR 0x06
#define DOYMR 0x07
#define DOYLR 0x08
#define SR 0x09
#define IRA 0x0A
#define IRB 0x0B
#define IRC 0x0C#define SelfTest_EN 1
uint8_t SF=0;  //Self Test Flagvoid PY_HMC5883L_WriteReg(uint8_t WrAddr, uint8_t data)
{uint8_t daddr;daddr = 0x3c; //HMC5883L device address (0x1E<<1)I2C_Start();I2C_Send_Byte(daddr);I2C_Read_Ack();I2C_Send_Byte(WrAddr);I2C_Read_Ack();I2C_Send_Byte(data);I2C_Read_Ack();I2C_Stop();}uint8_t PY_HMC5883L_ReadReg(uint8_t RdAddr)
{uint8_t RegValue = 0;uint8_t daddr;daddr = 0x3c; //HMC5883L device address (0x1E<<1)I2C_Start();I2C_Send_Byte(daddr);I2C_Read_Ack();I2C_Send_Byte(RdAddr);I2C_Read_Ack();I2C_Start();I2C_Send_Byte(daddr+1);I2C_Read_Ack();RegValue=I2C_Read_Byte(0);I2C_Stop();return RegValue;
}/*Note:
To minimize the communication between the master and this device, the address pointer updated automatically without master intervention.
This automatic address pointer update has two additional features. First when address 12 or higher is accessed the pointer updates to address 00 and secondly when address 08 is reached, the pointer rolls back to address 03. Logically, the address pointer operation functions as shown below.
If (address pointer = 08) then address pointer = 03
Else if (address pointer >= 12) then address pointer = 0
Else (address pointer) = (address pointer) + 1
*/
int XD, YD, ZD;
uint16_t Angle;
double XFactor = 1.0,  YFactor = 1.0,  ZFactor = 1.0; //Correction factor coming for self test process
double XFactor_T = 1.0,  YFactor_T = 1.0,  ZFactor_T = 1.0; //Correction factor coming for self test process for temperature impact
void PY_HMC5883L_ReadData(void)
{uint8_t data[6];uint16_t x, y, z;double angle;uint8_t daddr;daddr = 0x3c; //HMC5883L device address (0x1E<<1)I2C_Start();I2C_Send_Byte(daddr);I2C_Read_Ack();I2C_Send_Byte(0x03);I2C_Read_Ack();I2C_Start();I2C_Send_Byte(daddr+1);I2C_Read_Ack();data[0]=I2C_Read_Byte(1);data[1]=I2C_Read_Byte(1);data[2]=I2C_Read_Byte(1);data[3]=I2C_Read_Byte(1);data[4]=I2C_Read_Byte(1);data[5]=I2C_Read_Byte(0);I2C_Stop();x = (((uint16_t)data[0])<<8)|((uint16_t)data[1]);z = (((uint16_t)data[2])<<8)|((uint16_t)data[3]);y = (((uint16_t)data[4])<<8)|((uint16_t)data[5]);if((x>>15)!=0) XD = -(0x10000-x);else XD = x;if((y>>15)!=0) YD = -(0x10000-y);else YD = y;if((z>>15)!=0) ZD = -(0x10000-z);else ZD = z;angle = atan2((double)YD*YFactor*YFactor_T,(double)XD*XFactor*XFactor_T);if(angle<0) angle += 6.28318530718 ; //Converted to range: 0 ~ 2πAngle = angle*(360/6.2831853071);    //Converted to °
}/*
SELF TEST OPERATION
To check the HMC5883L for proper operation, a self test feature in incorporated in which the sensor offset straps are excited to create a nominal field strength (bias field) to be measured. To implement this self test, the least significant bits (MS1 and MS0) of configuration register A are changed from 00 to 01.
Then, by placing the mode register into single-measurement mode (0x01), two data acquisition cycles will be made on each magnetic vector. The first acquisition will be a set pulse followed shortly by measurement data of the external field. The second acquisition will have the offset strap excited (about 10 mA) in the positive bias mode for X, Y, and Z axes to create about a ±1.1 gauss self test field plus the external field. The first acquisition values will be subtracted from the second acquisition, and the net measurement will be placed into the data output registers.
If the configuration register B is left at the factory default value of 0x40, values around +951 ADC LSB (1.16 Ga * 820 LSB/Ga) will be placed in the X and Y data output registers and around +886 (1.08 Ga * 1820 LSB/Ga) in Z data output register. To leave the self test mode, change MS1 and MS0 bit of the configuration register A back to 00. Also change the mode register if single-measurement mode is not the intended mode of operation.
*/
void PY_HMC5883L_SELF_TEST(void)
{SF=1;XFactor = 1.0; YFactor = 1.0; ZFactor = 1.0;PY_HMC5883L_WriteReg(CRA, 0X71);//samples average: 8; data output rate: 15Hz; measure mode: self test of positive biasPY_HMC5883L_WriteReg(CRB, 0X20);//gain: ± 1.3 GaPY_HMC5883L_WriteReg(MR, 0X01); //Single-Measurement ModeHAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);
}/*
Alternatively, the built-in self test can be used to periodically compensate the scaling errors due to temperature variations.
A compensation factor can be found by comparing the self test outputs with the ones obtained at a known temperature.
For example, if the self test output is 1130 at room temperature and 1150 at the current temperature then a scale factor of
(1130/1150) should be applied to all current magnetic readings. A temperature sensor is not required using this method.*/
int XD_T0, YD_T0, ZD_T0;
int XD_T1, YD_T1, ZD_T1;
void PY_HMC5883L_T0Param(void)
{SF=2;XFactor_T = 1.0; YFactor_T = 1.0; ZFactor_T = 1.0;PY_HMC5883L_WriteReg(CRA, 0X71);//samples average: 8; data output rate: 15Hz; measure mode: self test of positive biasPY_HMC5883L_WriteReg(CRB, 0X20);//gain: ± 1.3 GaPY_HMC5883L_WriteReg(MR, 0X01); //Single-Measurement ModeHAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);while(SF!=0) PY_Delay_us_t(1000);PY_HMC5883L_WriteReg(CRA, 0X70);//samples average: 8; data output rate: 15Hz; measure mode: normalPY_HMC5883L_WriteReg(CRB, 0X20);//gain: ± 1.3 GaPY_HMC5883L_WriteReg(MR, 0X00);//continuous-measurement modeHAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);
}void PY_HMC5883L_T1Param(void)
{SF=3;XFactor_T = 1.0; YFactor_T = 1.0; ZFactor_T = 1.0;PY_HMC5883L_WriteReg(CRA, 0X71);//samples average: 8; data output rate: 15Hz; measure mode: self test of positive biasPY_HMC5883L_WriteReg(CRB, 0X20);//gain: ± 1.3 GaPY_HMC5883L_WriteReg(MR, 0X01); //Single-Measurement ModeHAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);while(SF!=0) PY_Delay_us_t(1000);PY_HMC5883L_WriteReg(CRA, 0X70);//samples average: 8; data output rate: 15Hz; measure mode: normalPY_HMC5883L_WriteReg(CRB, 0X20);//gain: ± 1.3 GaPY_HMC5883L_WriteReg(MR, 0X00);//continuous-measurement modeHAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);
}void PY_HMC5883L_Init(void)
{uint8_t Reg[13];Reg[0] = PY_HMC5883L_ReadReg(CRA);Reg[1] = PY_HMC5883L_ReadReg(CRB);Reg[2] = PY_HMC5883L_ReadReg(MR);Reg[3] = PY_HMC5883L_ReadReg(DOXMR);Reg[4] = PY_HMC5883L_ReadReg(DOXLR);Reg[5] = PY_HMC5883L_ReadReg(DOZMR);Reg[6] = PY_HMC5883L_ReadReg(DOZLR);Reg[7] = PY_HMC5883L_ReadReg(DOYMR);Reg[8] = PY_HMC5883L_ReadReg(DOYLR);Reg[9] = PY_HMC5883L_ReadReg(SR);Reg[10] = PY_HMC5883L_ReadReg(IRA); //data = 0x48Reg[11] = PY_HMC5883L_ReadReg(IRB); //data = 0x34Reg[12] = PY_HMC5883L_ReadReg(IRC); //data = 0x33if(!((Reg[10]==0x48)&&(Reg[11]==0x34)&&(Reg[12]==0x33))){printf("HMC5883 I2C access failure!\r\n");printf("HMC5883 regs: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n", Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], Reg[5], Reg[6], Reg[7], Reg[8], Reg[9], Reg[10], Reg[11], Reg[12]);return PY_HMC5883L_Init();}else{printf("HMC5883 I2C access OK!\r\n");printf("HMC5883 regs: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n", Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], Reg[5], Reg[6], Reg[7], Reg[8], Reg[9], Reg[10], Reg[11], Reg[12]);if(SelfTest_EN){PY_HMC5883L_SELF_TEST();while(SF!=0) PY_Delay_us_t(1000);}PY_HMC5883L_WriteReg(CRA, 0X70);//samples average: 8; data output rate: 15Hz; measure mode: normalPY_HMC5883L_WriteReg(CRB, 0X20);//gain: ± 1.3 GaPY_HMC5883L_WriteReg(MR, 0X00);//continuous-measurement modeHAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);}
}

而在GPIO的中断函数里做读取和处理:

void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{const float cr = 1.1*1090;  //1.1Gauss * 1090LSB/Gaussif (GPIO_Pin==GPIO_PIN_0){PY_HMC5883L_ReadData();HAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);if(SF==1){printf("\r\n\r\nSelf-Test X: %d ; Y: %d ; Z: %d\r\n\r\n", XD, YD, ZD);XFactor = cr/XD;YFactor = cr/YD;ZFactor = cr/ZD;SF = 0;}else if(SF==2){XD_T0 = XD;YD_T0 = YD;ZD_T0 = ZD;printf("\r\n\r\nT0 parameter test and set done!\r\n\r\n", XD, YD, ZD);SF = 0;}else if(SF==3){XD_T1 = XD;YD_T1 = YD;ZD_T1 = ZD;printf("\r\n\r\nT1 parameter test and set done!\r\n\r\n", XD, YD, ZD);XFactor_T = XD_T0/XD_T1;YFactor_T = YD_T0/YD_T1;ZFactor_T = ZD_T0/ZD_T1;SF = 0;}else{printf("Normal-Test X: %d ; Y: %d ; Z: %d ==> Angle(0~359): %d\r\n", XD, YD, ZD, Angle);}}
}

STM32工程完整代码

完整的工程代码如下:

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2022 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/*Written by Pegasus Yu in 2022*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <math.h>
#include "usart.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
__IO float usDelayBase;
void PY_usDelayTest(void)
{__IO uint32_t firstms, secondms;__IO uint32_t counter = 0;firstms = HAL_GetTick()+1;secondms = firstms+1;while(uwTick!=firstms) ;while(uwTick!=secondms) counter++;usDelayBase = ((float)counter)/1000;
}void PY_Delay_us_t(uint32_t Delay)
{__IO uint32_t delayReg;__IO uint32_t usNum = (uint32_t)(Delay*usDelayBase);delayReg = 0;while(delayReg!=usNum) delayReg++;
}void PY_usDelayOptimize(void)
{__IO uint32_t firstms, secondms;__IO float coe = 1.0;firstms = HAL_GetTick();PY_Delay_us_t(1000000) ;secondms = HAL_GetTick();coe = ((float)1000)/(secondms-firstms);usDelayBase = coe*usDelayBase;
}void PY_Delay_us(uint32_t Delay)
{__IO uint32_t delayReg;__IO uint32_t msNum = Delay/1000;__IO uint32_t usNum = (uint32_t)((Delay%1000)*usDelayBase);if(msNum>0) HAL_Delay(msNum);delayReg = 0;while(delayReg!=usNum) delayReg++;
}
/* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define us_num 10#define SCL_OUT_H HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)
#define SCL_OUT_L HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET)
#define SDA_OUT_H HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET)
#define SDA_OUT_L HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET)
#define SDA_IN HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5)#define INT_IN HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6)void I2C_Init(void)
{SCL_OUT_H;SDA_OUT_H;PY_Delay_us_t(2000000); //Provide device stability time}void I2C_Start(void)
{PY_Delay_us_t(us_num) ;SDA_OUT_H;SCL_OUT_H;PY_Delay_us_t(us_num/2) ;SDA_OUT_L;PY_Delay_us_t(us_num/2) ;SCL_OUT_L;
}void I2C_Stop(void)
{SCL_OUT_L;PY_Delay_us_t(us_num) ;SDA_OUT_L;PY_Delay_us_t(us_num) ;SCL_OUT_H;PY_Delay_us_t(us_num) ;SDA_OUT_H;PY_Delay_us_t(us_num) ;
}void I2C_Write_Ack(void)
{PY_Delay_us_t(us_num/2) ;SDA_OUT_L;PY_Delay_us_t(us_num/2) ;SCL_OUT_H;PY_Delay_us_t(us_num) ;SCL_OUT_L;SDA_OUT_H;}uint8_t I2C_Read_Ack(void)
{uint8_t status=0;SCL_OUT_L;PY_Delay_us_t(us_num/2) ;SDA_OUT_H;PY_Delay_us_t(us_num/2) ;status = SDA_IN;SCL_OUT_H;PY_Delay_us_t(us_num) ;SCL_OUT_L;SDA_OUT_L;return status;}void I2C_Send_Byte(uint8_t txd){for(uint8_t i=0;i<8;i++){PY_Delay_us_t(us_num/2) ;if((txd&0x80)>>7) SDA_OUT_H;else SDA_OUT_L;txd<<=1;PY_Delay_us_t(us_num/2) ;SCL_OUT_H;PY_Delay_us_t(us_num) ;SCL_OUT_L;}SDA_OUT_L;
}uint8_t I2C_Read_Byte(unsigned char rdack)
{uint8_t rxd=0;for(uint8_t i=0;i<8;i++ ){SCL_OUT_L;PY_Delay_us_t(us_num/2) ;SDA_OUT_H;PY_Delay_us_t(us_num/2) ;SCL_OUT_H;rxd<<=1;if(SDA_IN) rxd++;PY_Delay_us_t(us_num) ;}SCL_OUT_L;SDA_OUT_H;if (rdack) I2C_Write_Ack();return rxd;
}#define CRA 0x00
#define CRB 0x01
#define MR 0x02
#define DOXMR 0x03
#define DOXLR 0x04
#define DOZMR 0x05
#define DOZLR 0x06
#define DOYMR 0x07
#define DOYLR 0x08
#define SR 0x09
#define IRA 0x0A
#define IRB 0x0B
#define IRC 0x0C#define SelfTest_EN 1
uint8_t SF=0;  //Self Test Flagvoid PY_HMC5883L_WriteReg(uint8_t WrAddr, uint8_t data)
{uint8_t daddr;daddr = 0x3c; //HMC5883L device address (0x1E<<1)I2C_Start();I2C_Send_Byte(daddr);I2C_Read_Ack();I2C_Send_Byte(WrAddr);I2C_Read_Ack();I2C_Send_Byte(data);I2C_Read_Ack();I2C_Stop();}uint8_t PY_HMC5883L_ReadReg(uint8_t RdAddr)
{uint8_t RegValue = 0;uint8_t daddr;daddr = 0x3c; //HMC5883L device address (0x1E<<1)I2C_Start();I2C_Send_Byte(daddr);I2C_Read_Ack();I2C_Send_Byte(RdAddr);I2C_Read_Ack();I2C_Start();I2C_Send_Byte(daddr+1);I2C_Read_Ack();RegValue=I2C_Read_Byte(0);I2C_Stop();return RegValue;
}/*Note:
To minimize the communication between the master and this device, the address pointer updated automatically without master intervention.
This automatic address pointer update has two additional features. First when address 12 or higher is accessed the pointer updates to address 00 and secondly when address 08 is reached, the pointer rolls back to address 03. Logically, the address pointer operation functions as shown below.
If (address pointer = 08) then address pointer = 03
Else if (address pointer >= 12) then address pointer = 0
Else (address pointer) = (address pointer) + 1
*/
int XD, YD, ZD;
uint16_t Angle;
double XFactor = 1.0,  YFactor = 1.0,  ZFactor = 1.0; //Correction factor coming for self test process
double XFactor_T = 1.0,  YFactor_T = 1.0,  ZFactor_T = 1.0; //Correction factor coming for self test process for temperature impact
void PY_HMC5883L_ReadData(void)
{uint8_t data[6];uint16_t x, y, z;double angle;uint8_t daddr;daddr = 0x3c; //HMC5883L device address (0x1E<<1)I2C_Start();I2C_Send_Byte(daddr);I2C_Read_Ack();I2C_Send_Byte(0x03);I2C_Read_Ack();I2C_Start();I2C_Send_Byte(daddr+1);I2C_Read_Ack();data[0]=I2C_Read_Byte(1);data[1]=I2C_Read_Byte(1);data[2]=I2C_Read_Byte(1);data[3]=I2C_Read_Byte(1);data[4]=I2C_Read_Byte(1);data[5]=I2C_Read_Byte(0);I2C_Stop();x = (((uint16_t)data[0])<<8)|((uint16_t)data[1]);z = (((uint16_t)data[2])<<8)|((uint16_t)data[3]);y = (((uint16_t)data[4])<<8)|((uint16_t)data[5]);if((x>>15)!=0) XD = -(0x10000-x);else XD = x;if((y>>15)!=0) YD = -(0x10000-y);else YD = y;if((z>>15)!=0) ZD = -(0x10000-z);else ZD = z;angle = atan2((double)YD*YFactor*YFactor_T,(double)XD*XFactor*XFactor_T);if(angle<0) angle += 6.28318530718 ; //Converted to range: 0 ~ 2πAngle = angle*(360/6.2831853071);    //Converted to °
}/*
SELF TEST OPERATION
To check the HMC5883L for proper operation, a self test feature in incorporated in which the sensor offset straps are excited to create a nominal field strength (bias field) to be measured. To implement this self test, the least significant bits (MS1 and MS0) of configuration register A are changed from 00 to 01.
Then, by placing the mode register into single-measurement mode (0x01), two data acquisition cycles will be made on each magnetic vector. The first acquisition will be a set pulse followed shortly by measurement data of the external field. The second acquisition will have the offset strap excited (about 10 mA) in the positive bias mode for X, Y, and Z axes to create about a ±1.1 gauss self test field plus the external field. The first acquisition values will be subtracted from the second acquisition, and the net measurement will be placed into the data output registers.
If the configuration register B is left at the factory default value of 0x40, values around +951 ADC LSB (1.16 Ga * 820 LSB/Ga) will be placed in the X and Y data output registers and around +886 (1.08 Ga * 1820 LSB/Ga) in Z data output register. To leave the self test mode, change MS1 and MS0 bit of the configuration register A back to 00. Also change the mode register if single-measurement mode is not the intended mode of operation.
*/
void PY_HMC5883L_SELF_TEST(void)
{SF=1;XFactor = 1.0; YFactor = 1.0; ZFactor = 1.0;PY_HMC5883L_WriteReg(CRA, 0X71);//samples average: 8; data output rate: 15Hz; measure mode: self test of positive biasPY_HMC5883L_WriteReg(CRB, 0X20);//gain: ± 1.3 GaPY_HMC5883L_WriteReg(MR, 0X01); //Single-Measurement ModeHAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);
}/*
Alternatively, the built-in self test can be used to periodically compensate the scaling errors due to temperature variations.
A compensation factor can be found by comparing the self test outputs with the ones obtained at a known temperature.
For example, if the self test output is 1130 at room temperature and 1150 at the current temperature then a scale factor of
(1130/1150) should be applied to all current magnetic readings. A temperature sensor is not required using this method.*/
int XD_T0, YD_T0, ZD_T0;
int XD_T1, YD_T1, ZD_T1;
void PY_HMC5883L_T0Param(void)
{SF=2;XFactor_T = 1.0; YFactor_T = 1.0; ZFactor_T = 1.0;PY_HMC5883L_WriteReg(CRA, 0X71);//samples average: 8; data output rate: 15Hz; measure mode: self test of positive biasPY_HMC5883L_WriteReg(CRB, 0X20);//gain: ± 1.3 GaPY_HMC5883L_WriteReg(MR, 0X01); //Single-Measurement ModeHAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);while(SF!=0) PY_Delay_us_t(1000);PY_HMC5883L_WriteReg(CRA, 0X70);//samples average: 8; data output rate: 15Hz; measure mode: normalPY_HMC5883L_WriteReg(CRB, 0X20);//gain: ± 1.3 GaPY_HMC5883L_WriteReg(MR, 0X00);//continuous-measurement modeHAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);
}void PY_HMC5883L_T1Param(void)
{SF=3;XFactor_T = 1.0; YFactor_T = 1.0; ZFactor_T = 1.0;PY_HMC5883L_WriteReg(CRA, 0X71);//samples average: 8; data output rate: 15Hz; measure mode: self test of positive biasPY_HMC5883L_WriteReg(CRB, 0X20);//gain: ± 1.3 GaPY_HMC5883L_WriteReg(MR, 0X01); //Single-Measurement ModeHAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);while(SF!=0) PY_Delay_us_t(1000);PY_HMC5883L_WriteReg(CRA, 0X70);//samples average: 8; data output rate: 15Hz; measure mode: normalPY_HMC5883L_WriteReg(CRB, 0X20);//gain: ± 1.3 GaPY_HMC5883L_WriteReg(MR, 0X00);//continuous-measurement modeHAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);
}void PY_HMC5883L_Init(void)
{uint8_t Reg[13];Reg[0] = PY_HMC5883L_ReadReg(CRA);Reg[1] = PY_HMC5883L_ReadReg(CRB);Reg[2] = PY_HMC5883L_ReadReg(MR);Reg[3] = PY_HMC5883L_ReadReg(DOXMR);Reg[4] = PY_HMC5883L_ReadReg(DOXLR);Reg[5] = PY_HMC5883L_ReadReg(DOZMR);Reg[6] = PY_HMC5883L_ReadReg(DOZLR);Reg[7] = PY_HMC5883L_ReadReg(DOYMR);Reg[8] = PY_HMC5883L_ReadReg(DOYLR);Reg[9] = PY_HMC5883L_ReadReg(SR);Reg[10] = PY_HMC5883L_ReadReg(IRA); //data = 0x48Reg[11] = PY_HMC5883L_ReadReg(IRB); //data = 0x34Reg[12] = PY_HMC5883L_ReadReg(IRC); //data = 0x33if(!((Reg[10]==0x48)&&(Reg[11]==0x34)&&(Reg[12]==0x33))){printf("HMC5883 I2C access failure!\r\n");printf("HMC5883 regs: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n", Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], Reg[5], Reg[6], Reg[7], Reg[8], Reg[9], Reg[10], Reg[11], Reg[12]);return PY_HMC5883L_Init();}else{printf("HMC5883 I2C access OK!\r\n");printf("HMC5883 regs: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n", Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], Reg[5], Reg[6], Reg[7], Reg[8], Reg[9], Reg[10], Reg[11], Reg[12]);if(SelfTest_EN){PY_HMC5883L_SELF_TEST();while(SF!=0) PY_Delay_us_t(1000);}PY_HMC5883L_WriteReg(CRA, 0X70);//samples average: 8; data output rate: 15Hz; measure mode: normalPY_HMC5883L_WriteReg(CRB, 0X20);//gain: ± 1.3 GaPY_HMC5883L_WriteReg(MR, 0X00);//continuous-measurement modeHAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);}
}
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart2;/* USER CODE BEGIN PV */
uint8_t TStatsu = 0;
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* 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_USART2_UART_Init();/* USER CODE BEGIN 2 */PY_usDelayTest();PY_usDelayOptimize();I2C_Init();PY_HMC5883L_Init();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){PY_Delay_us_t(1);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;RCC_OscInitStruct.PLL.PLLN = 8;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/*** @brief USART2 Initialization Function* @param None* @retval None*/
static void MX_USART2_UART_Init(void)
{/* USER CODE BEGIN USART2_Init 0 *//* USER CODE END USART2_Init 0 *//* USER CODE BEGIN USART2_Init 1 *//* USER CODE END USART2_Init 1 */huart2.Instance = USART2;huart2.Init.BaudRate = 115200;huart2.Init.WordLength = UART_WORDLENGTH_8B;huart2.Init.StopBits = UART_STOPBITS_1;huart2.Init.Parity = UART_PARITY_NONE;huart2.Init.Mode = UART_MODE_TX_RX;huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart2.Init.OverSampling = UART_OVERSAMPLING_16;huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;if (HAL_UART_Init(&huart2) != HAL_OK){Error_Handler();}/* USER CODE BEGIN USART2_Init 2 *//* USER CODE END USART2_Init 2 */}/*** @brief GPIO Initialization Function* @param None* @retval None*/
static void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOA_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4|GPIO_PIN_5, GPIO_PIN_SET);/*Configure GPIO pin : PA0 */GPIO_InitStruct.Pin = GPIO_PIN_0;GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;GPIO_InitStruct.Pull = GPIO_PULLDOWN;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/*Configure GPIO pins : PA4 PA5 */GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* EXTI interrupt init*/HAL_NVIC_SetPriority(EXTI0_1_IRQn, 1, 0);HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);}/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{const float cr = 1.1*1090;  //1.1Gauss * 1090LSB/Gaussif (GPIO_Pin==GPIO_PIN_0){PY_HMC5883L_ReadData();HAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);if(SF==1){printf("\r\n\r\nSelf-Test X: %d ; Y: %d ; Z: %d\r\n\r\n", XD, YD, ZD);XFactor = cr/XD;YFactor = cr/YD;ZFactor = cr/ZD;SF = 0;}else if(SF==2){XD_T0 = XD;YD_T0 = YD;ZD_T0 = ZD;printf("\r\n\r\nT0 parameter test and set done!\r\n\r\n", XD, YD, ZD);SF = 0;}else if(SF==3){XD_T1 = XD;YD_T1 = YD;ZD_T1 = ZD;printf("\r\n\r\nT1 parameter test and set done!\r\n\r\n", XD, YD, ZD);XFactor_T = XD_T0/XD_T1;YFactor_T = YD_T0/YD_T1;ZFactor_T = ZD_T0/ZD_T1;SF = 0;}else{printf("Normal-Test X: %d ; Y: %d ; Z: %d ==> Angle(0~359): %d\r\n", XD, YD, ZD, Angle);}}
}
/* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

使用及校准说明

使用说明:
程序启动后,先读取HMC5883L的识别码,如果正确向后执行,不正确就循环打印报错信息。
根据自测使能标识,决定是否执行自检测试,如果不执行自检测试,则配置为正常模式,然后在INT管脚中断里读取数据并解析。解析的数据为360度内的角度值,报告为0到359度。如果执行自检测试,则通过计算获得校准系数用于以后的正常模式数据校准,自检后配置为正常模式。
可选进行温度一致性校准,将T1温度的值回归到基准T0温度的值。因此在传感器静止时,在T0温度时执行一次PY_HMC5883L_T0Param(), 然后在T1温度时执行一次 PY_HMC5883L_T1Param(),就实现了温度校准系数的生成和应用。

校准原理说明:
自测校准模式触发HMC5883L自动进行两次测试,第一次测试环境三轴的磁强度,然后在每轴上增加1.1高斯量,再测试三轴的磁强度,然后将结果相减得到绝对变化量,也就是对应1.1高斯的实际变量化,而1.1高斯量的理论变化量可以通过设定的增益等级对应的单位高斯变化量计算而得。从而可以得到每轴的校准系数=理论变化量/实际变化量。
在这里插入图片描述
温度校准模式可以在温度变化产生影响时,将不同温度T1的测试值回归到特定温度T0的对应值。在T0温度做自检测试得到对应1.1高斯变化的检测数值变化量,而在T1温度做自检测试也得到对应1.1高斯变化的检测数值变化量,由于温度不同产生的影响,这两个数值变化量不同,因此可以产生温度校准系数=value(T0)/value(T1), 将T1温度的检测值乘以系数,就得到如果是在T0温度做测试会得到的结果值。

测试效果

串口打印输出的效果如下:

在这里插入图片描述

校准扩展

可以基于实际环境和应用进行进一步的校准,如在设定的一些角度位如0度,45,90度,135度,180度,225度,270度,315度进行角度测试,将结果和理论值比较,从而再次产生分段校准系数。一般针对水平面运动精度就已足够。如果涉及三维运动,则要进行更复杂的转换和校准。

例程下载

STM32G030模拟I2C协议获取HMC5883L电子罗盘磁角度数据 (HAL)例程

–End–


http://chatgpt.dhexx.cn/article/9TI75Vg3.shtml

相关文章

[11]ESP32+三轴磁罗盘HMC5883L移植与调试

文章目录 一、开发笔记二、初始化与工作流程1. 设置测量模式2. 设置采样率&#xff08;默认15Hz&#xff09;3. 设置测量范围4. 校准5. 开始测量6. 自测试操作&#xff08;可选&#xff09; 三、寄存器表1. 00-配置寄存器A2. 01-配置寄存器B3. 02-模式寄存器4. 09-状态寄存器5.…

STM32 HAL I2C读取HMC5883L磁偏角的实践

STM32 HAL I2C读取HMC5883L磁偏角的实践 源由成果代码头文件 G85HAL.h子文件 G85HAL.C主程序调用配置I2C引脚参考链接 源由 用传统的方式编写I2C总线数据读取&#xff0c;程序代码细碎&#xff0c;不好维护&#xff0c;移植性不好。CUBE MX配置方便灵活&#xff0c;程序架构好…

(二十六)树莓派3B+ 获取HMC5883L的磁场数据

模块介绍 霍尼韦尔 HMC5883L 是一种表面贴装的高集成模块&#xff0c;并带有数字接口的弱磁传感器芯片&#xff0c;应用于低成本罗盘和磁场检测领域。HMC5883L 包括最先进的高分辨率 HMC118X 系列磁阻传感器&#xff0c;并附带霍尼韦尔专利的集成电路包括放大器、自动消磁驱动…

HMC5883L校准

HMC5883L 磁力计校准 (2015-02-14 11:48:21) 转载▼ 标签&#xff1a; hmc5883 磁力计 校准 分类&#xff1a; 电子技术 这里针对 HMC5883L 磁力计 的校准&#xff0c;做一个简单讲解。欢迎交流&#xff0c;新浪长沙WalkAnt。 先看看这篇文章&#xff1a;http://blo…

STC 51单片机53——电子指南针HMC5883l

#include <REG51.H> #include <math.h> //Keil library #include <stdio.h> //Keil library #include <INTRINS.H> #define uchar unsigned char #define uint unsigned int //使用的端口&#xff0c;请按照以下接线 sbit …

HMC5883l磁力计数据读取

1.数据手册地址 2.芯片介绍 设备的7位地址为0x1e&#xff0c;读地址为0x3d&#xff0c;写地址为0x3c。如图 2.主要需要配置的寄存器有3个。分别是配置寄存器A&#xff08;0x00&#xff09;&#xff0c;配置寄存器B&#xff08;0x01&#xff09;和模式寄存器&#xff08;0x03&…

ESP8266-Arduino编程实例-HMC5883L磁场传感器

HMC5883L磁场传感器 1、HMC5883L介绍 霍尼韦尔 HMC5883L 是一款表面贴装、多芯片模块,专为低场磁场传感而设计,具有数字接口,适用于低成本罗盘和磁力计等应用。 HMC5883L 包括我们先进的高分辨率 HMC118X 系列磁阻传感器和一个 ASIC,该 ASIC 包含放大、自动消磁带驱动器、…

HMC5883L电子罗盘原理及应用,全网最详细~

寄存器配置部分 HMC5883L模块具有两个配置寄存器&#xff0c;配置寄存器A用来配置该装置设置的数据输出速率和测量配置&#xff1b;配置寄存器 B 设置装置的增益。 模式寄存器则是用来设定装置的操作模式&#xff0c;有连续测量模式&#xff0c;单一测量模式和闲置模式等。具…

HMC5883L磁力计使用

一、器件简介 HMC5883L是一款三轴磁场传感器&#xff0c;电子指南针罗盘模块。采用IIC通讯协议。 二、工作原理 传统罗盘用一根被磁化的磁针来感应地球磁场&#xff0c;地球磁场与磁针之间的磁力时磁针转动&#xff0c;直至磁针的两端分别指向地球的磁南极与磁北极。电子罗盘也…

HMC5883L电子罗盘/指南针实现,附带校准方法(附STM32 源码)

HMC5883L电子罗盘/指南针实现&#xff0c;附带校准方法&#xff08;附STM32 源码&#xff09; 前言一、寄存器详解1.配置寄存器A2.配置寄存器B3.模式寄存器4.数据寄存器5.状态寄存器6.识别寄存器 二、使用步骤1.STM32CubeMX设置2.初始化3.读取原始数据 三、校准程序四、方位角计…

【STM32+cubemx】0029 HAL库开发:HMC5883L磁力计的应用(电子指南针)

今天我们来学习电子磁力计HMC5883L的使用。先介绍磁力计的基础知识&#xff0c;再给一个获取磁力计数据的例子&#xff0c;最后讲解HMC5883L磁力计的校准&#xff0c;以及一些使用中的经验。 1&#xff09;HMC5883L磁力计的基础知识 磁力计是用来测量磁场强弱&#xff08;也就…

Web 应用防火墙怎样添加域名

Web 应用防火墙是一款基于 AI 的一站式 Web 业务运营风险防护方案。沉淀了安全大数据检测能力和多年自营业务 Web 安全防护经验。通过 Web 入侵防护、0day 漏洞补丁修复、恶意访问惩罚、云备份防篡改等多维度防御策略全面防护网站的系统及业务安全。 包括四个步骤&#xff1a; …

WEB应用防火墙(WAF启明设备)

1.应用背景 网络安全形式严峻 新型0day漏洞频发 等保2.0 热点需求 行业规范 安全事件 2.产品介绍 1.工作原理 a) 桥模式串行部署于Web服务器前端&#xff0c;对应用层攻击行为进行精确识别和实时阻断&#xff0c;主动而有效的保护 Web应用不被攻击及篡改 b) 单臂代理模…

阿里云服务器接入云盾Web应用防火墙教学

什么是云盾Web应用防火墙&#xff1f; 云盾Web应用防火墙(Web Application Firewall, 简称 WAF)基于云安全大数据能力实现&#xff0c;通过防御SQL注入、XSS跨站脚本、常见Web服务器插件漏洞、木马上传、非授权核心资源访问等OWASP常见攻击&#xff0c;过滤海量恶意CC攻击&…

Web应用防火墙和普通防火墙的区别与联系

随着互联网的不断发展&#xff0c;Web应用程序的安全问题日益凸显&#xff0c;各种安全漏洞和攻击手段层出不穷。Web应用防火墙(WAF)作为保障Web应用程序安全的一种有效手段&#xff0c;正在被越来越多的企业所采用。那么&#xff0c;Web应用防火墙到底有什么用呢?web应用防火…

腾某云web应用防火墙-被ban后小技巧绕过

长这样式de 修改xff即可正常访问 &#xff08;X-Forwarded-For Header&#xff09;浏览器插件

WEB应用防火墙安全技术要求与测试评价方法

信息安全技术 WEB应用防火墙安全技术要求与测试评价方法 范围 本标准规定了WEB应用防火墙的安全功能要求、自身安全保护要求、性能要求和安全保证要求&#xff0c;并提供了相应的测试评价方法。 本标准适用于WEB应用防火墙的设计、生产、检测及采购。 规范性引用文件 下列…

开源免费的WEB应用防火墙

开源免费的WEB应用防火墙 排名不分前后 资源宝分享&#xff1a;www.httple.net 南墙waf测试linux7.6和宝塔不兼容&#xff0c;会用使用docker版waf隔离开来https://waf.uusec.com/waf-docker-community.v2.1.5.tgz 1、南墙WEB应用防火墙&#xff08;简称&#xff1a;&#x…

Saas型网站域名如何接入腾讯云的web应用防火墙?

步骤 1&#xff1a;域名添加 使用 Web 应用防火墙&#xff08;WAF&#xff09;防护您的 Web 业务前&#xff0c;需要先将防护的网站接入到 Web 应用防火墙。未完成接入前&#xff0c;您的 Web 应用防火墙防护将无法生效。本文档将指导您如何在 SaaS 型 WAF 中接入域名。 登录…

云上守护者—Web应用防火墙

说到防火墙&#xff0c;大家既熟悉又陌生。熟悉&#xff0c;是因为我们日常或多或少听过见过&#xff0c;例如Window自带防火墙。陌生&#xff0c;是因为我们不知道如何定义防火墙。 什么是防火墙&#xff1f; 应用防火墙对应在现实生活中&#xff0c;像公司大门的保安大爷&am…