├── HAL_HMC5883L.h ├── HMC5883L.c ├── HMC5883L.chm ├── HMC5883L.h └── README.txt /HAL_HMC5883L.h: -------------------------------------------------------------------------------- 1 | //HMC5883L I2C library for ARM STM32F103xx Microcontrollers - Header file has defines 2 | // to choose I2C peripheral, speed & pins. 3 | // 24/05/2012 by Harinadha Reddy Chintalapalli 4 | // Changelog: 5 | // 2012-05-24 - initial release. 6 | /* ============================================================================================ 7 | HMC5883L device I2C library code for ARM STM32F103xx is placed under the MIT license 8 | Copyright (c) 2012 Harinadha Reddy Chintalapalli 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | ================================================================================================ 28 | */ 29 | 30 | /* Define to prevent recursive inclusion*/ 31 | #ifndef __HAL_HMC5883L_H 32 | #define __HAL_HMC5883L_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | /* Includes */ 39 | #include "stm32f10x.h" 40 | 41 | /** 42 | * @addtogroup HMC5883L_I2C_Define 43 | * @{ 44 | */ 45 | 46 | #define HMC5883L_I2C I2C2 47 | #define HMC5883L_I2C_RCC_Periph RCC_APB1Periph_I2C2 48 | #define HMC5883L_I2C_Port GPIOB 49 | #define HMC5883L_I2C_SCL_Pin GPIO_Pin_10 50 | #define HMC5883L_I2C_SDA_Pin GPIO_Pin_11 51 | #define HMC5883L_I2C_RCC_Port RCC_APB2Periph_GPIOB 52 | #define HMC5883L_I2C_Speed 100000 53 | 54 | /** 55 | *@} 56 | *//* end of group HMC5883L_I2C_Define */ 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif /* __HAL___HMC5883L_H */ 63 | 64 | /******************* (C) COPYRIGHT 2012 Harinadha Reddy Chintalapalli *****END OF FILE****/ 65 | -------------------------------------------------------------------------------- /HMC5883L.c: -------------------------------------------------------------------------------- 1 | //HMC5883L I2C library for ARM STM32F103xx Microcontrollers - Main header file 2 | //Has bit, byte and buffer I2C R/W functions 3 | // 24/05/2012 by Harinadha Reddy Chintalapalli 4 | // Changelog: 5 | // 2012-05-24 - initial release. Thanks to Jeff Rowberg for his AVR/Arduino 6 | // based development which inspired me & taken as reference to develop this. 7 | /* ============================================================================================ 8 | HMC5883L device I2C library code for ARM STM32F103xx is placed under the MIT license 9 | Copyright (c) 2012 Harinadha Reddy Chintalapalli 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy 12 | of this software and associated documentation files (the "Software"), to deal 13 | in the Software without restriction, including without limitation the rights 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | copies of the Software, and to permit persons to whom the Software is 16 | furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in 19 | all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | THE SOFTWARE. 28 | ================================================================================================ 29 | */ 30 | #include "HMC5883L.h" 31 | #include "stm32f10x_i2c.h" 32 | 33 | uint8_t HMC5883Lmode; 34 | 35 | /** @defgroup HMC5883L_Library 36 | * @{ 37 | */ 38 | 39 | /** Power on and prepare for general usage. 40 | * This will prepare the magnetometer with default settings, ready for single- 41 | * use mode (very low power requirements). Default settings include 8-sample 42 | * averaging, 15 Hz data output rate, normal measurement bias, a,d 1090 gain (in 43 | * terms of LSB/Gauss). Be sure to adjust any settings you need specifically 44 | * after initialization, especially the gain settings if you happen to be seeing 45 | * a lot of -4096 values (see the datasheet for mor information). 46 | */ 47 | void HMC5883L_Initialize() 48 | { 49 | // write CONFIG_A register 50 | 51 | uint8_t tmp = (HMC5883L_AVERAGING_8 << (HMC5883L_CRA_AVERAGE_BIT - HMC5883L_CRA_AVERAGE_LENGTH + 1)) 52 | | (HMC5883L_RATE_15 << (HMC5883L_CRA_RATE_BIT - HMC5883L_CRA_RATE_LENGTH + 1)) 53 | | (HMC5883L_BIAS_NORMAL << (HMC5883L_CRA_BIAS_BIT - HMC5883L_CRA_BIAS_LENGTH + 1)); 54 | HMC5883L_I2C_ByteWrite(HMC5883L_DEFAULT_ADDRESS, &tmp, HMC5883L_RA_CONFIG_A); 55 | 56 | // write CONFIG_B register 57 | HMC5883L_SetGain(HMC5883L_GAIN_1090); 58 | 59 | // write MODE register 60 | HMC5883L_SetMode(HMC5883L_MODE_SINGLE); 61 | } 62 | 63 | /** Verify the I2C connection. 64 | * Make sure the device is connected and responds as expected. 65 | * @return True if connection is valid, false otherwise 66 | */ 67 | bool HMC5883L_TestConnection() 68 | { 69 | uint8_t tmp[3] = { 0 }; 70 | HMC5883L_I2C_BufferRead(HMC5883L_DEFAULT_ADDRESS, tmp, HMC5883L_RA_ID_A, 3); 71 | return (tmp[0] == 'H' && tmp[1] == '4' && tmp[2] == '3') ? TRUE : FALSE; 72 | } 73 | // CONFIG_A register 74 | 75 | /** Get number of samples averaged per measurement. 76 | * @return Current samples averaged per measurement (0-3 for 1/2/4/8 respectively) 77 | * @see HMC5883L_AVERAGING_8 78 | * @see HMC5883L_RA_CONFIG_A 79 | * @see HMC5883L_CRA_AVERAGE_BIT 80 | * @see HMC5883L_CRA_AVERAGE_LENGTH 81 | */ 82 | uint8_t HMC5883L_GetSampleAveraging() 83 | { 84 | uint8_t tmp; 85 | HMC5883L_ReadBits(HMC5883L_DEFAULT_ADDRESS, HMC5883L_RA_CONFIG_A, HMC5883L_CRA_AVERAGE_BIT, HMC5883L_CRA_AVERAGE_LENGTH, &tmp); 86 | return tmp; 87 | } 88 | 89 | /** Set number of samples averaged per measurement. 90 | * @param averaging New samples averaged per measurement setting(0-3 for 1/2/4/8 respectively) 91 | * @see HMC5883L_RA_CONFIG_A 92 | * @see HMC5883L_CRA_AVERAGE_BIT 93 | * @see HMC5883L_CRA_AVERAGE_LENGTH 94 | */ 95 | void HMC5883L_SetSampleAveraging(uint8_t averaging) 96 | { 97 | HMC5883L_WriteBits(HMC5883L_DEFAULT_ADDRESS, HMC5883L_RA_CONFIG_A, HMC5883L_CRA_AVERAGE_BIT, HMC5883L_CRA_AVERAGE_LENGTH, averaging); 98 | } 99 | 100 | /** \code 101 | * Get data output rate value. 102 | * The Table below shows all selectable output rates in continuous measurement 103 | * mode. All three channels shall be measured within a given output rate. Other 104 | * output rates with maximum rate of 160 Hz can be achieved by monitoring DRDY 105 | * interrupt pin in single measurement mode. 106 | * 107 | * Value | Typical Data Output Rate (Hz) 108 | * ------+------------------------------ 109 | * 0 | 0.75 110 | * 1 | 1.5 111 | * 2 | 3 112 | * 3 | 7.5 113 | * 4 | 15 (Default) 114 | * 5 | 30 115 | * 6 | 75 116 | * 7 | Not used 117 | * \endcode 118 | * @return Current rate of data output to registers 119 | * @see HMC5883L_RATE_15 120 | * @see HMC5883L_RA_CONFIG_A 121 | * @see HMC5883L_CRA_RATE_BIT 122 | * @see HMC5883L_CRA_RATE_LENGTH 123 | */ 124 | uint8_t HMC5883L_GetDataRate() 125 | { 126 | uint8_t tmp; 127 | HMC5883L_ReadBits(HMC5883L_DEFAULT_ADDRESS, HMC5883L_RA_CONFIG_A, HMC5883L_CRA_RATE_BIT, HMC5883L_CRA_RATE_LENGTH, &tmp); 128 | return tmp; 129 | } 130 | 131 | /** Set data output rate value. 132 | * @param rate Rate of data output to registers 133 | * @see HMC5883L_SetDataRate() 134 | * @see HMC5883L_RATE_15 135 | * @see HMC5883L_RA_CONFIG_A 136 | * @see HMC5883L_CRA_RATE_BIT 137 | * @see HMC5883L_CRA_RATE_LENGTH 138 | */ 139 | void HMC5883L_SetDataRate(uint8_t rate) 140 | { 141 | HMC5883L_WriteBits(HMC5883L_DEFAULT_ADDRESS, HMC5883L_RA_CONFIG_A, HMC5883L_CRA_RATE_BIT, HMC5883L_CRA_RATE_LENGTH, rate); 142 | } 143 | 144 | /** Get measurement bias value. 145 | * @return Current bias value (0-2 for normal/positive/negative respectively) 146 | * @see HMC5883L_BIAS_NORMAL 147 | * @see HMC5883L_RA_CONFIG_A 148 | * @see HMC5883L_CRA_BIAS_BIT 149 | * @see HMC5883L_CRA_BIAS_LENGTH 150 | */ 151 | uint8_t HMC5883L_GetMeasurementBias() 152 | { 153 | uint8_t tmp; 154 | HMC5883L_ReadBits(HMC5883L_DEFAULT_ADDRESS, HMC5883L_RA_CONFIG_A, HMC5883L_CRA_BIAS_BIT, HMC5883L_CRA_BIAS_LENGTH, &tmp); 155 | return tmp; 156 | } 157 | 158 | /** Set measurement bias value. 159 | * @param bias New bias value (0-2 for normal/positive/negative respectively) 160 | * @see HMC5883L_BIAS_NORMAL 161 | * @see HMC5883L_RA_CONFIG_A 162 | * @see HMC5883L_CRA_BIAS_BIT 163 | * @see HMC5883L_CRA_BIAS_LENGTH 164 | */ 165 | void HMC5883L_SetMeasurementBias(uint8_t bias) 166 | { 167 | HMC5883L_WriteBits(HMC5883L_DEFAULT_ADDRESS, HMC5883L_RA_CONFIG_A, HMC5883L_CRA_BIAS_BIT, HMC5883L_CRA_BIAS_LENGTH, bias); 168 | } 169 | 170 | // CONFIG_B register 171 | 172 | /** \code 173 | * Get magnetic field gain value. 174 | * The table below shows nominal gain settings. Use the "Gain" column to convert 175 | * counts to Gauss. Choose a lower gain value (higher GN#) when total field 176 | * strength causes overflow in one of the data output registers (saturation). 177 | * The data output range for all settings is 0xF800-0x07FF (-2048 - 2047). 178 | * 179 | * Value | Field Range | Gain (LSB/Gauss) 180 | * ------+-------------+----------------- 181 | * 0 | +/- 0.88 Ga | 1370 182 | * 1 | +/- 1.3 Ga | 1090 (Default) 183 | * 2 | +/- 1.9 Ga | 820 184 | * 3 | +/- 2.5 Ga | 660 185 | * 4 | +/- 4.0 Ga | 440 186 | * 5 | +/- 4.7 Ga | 390 187 | * 6 | +/- 5.6 Ga | 330 188 | * 7 | +/- 8.1 Ga | 230 189 | * \endcode 190 | * @return Current magnetic field gain value 191 | * @see HMC5883L_GAIN_1090 192 | * @see HMC5883L_RA_CONFIG_B 193 | * @see HMC5883L_CRB_GAIN_BIT 194 | * @see HMC5883L_CRB_GAIN_LENGTH 195 | */ 196 | uint8_t HMC5883L_GetGain() 197 | { 198 | uint8_t tmp; 199 | HMC5883L_ReadBits(HMC5883L_DEFAULT_ADDRESS, HMC5883L_RA_CONFIG_B, HMC5883L_CRB_GAIN_BIT, HMC5883L_CRB_GAIN_LENGTH, &tmp); 200 | return tmp; 201 | } 202 | 203 | /** Set magnetic field gain value. 204 | * @param gain New magnetic field gain value 205 | * @see HMC5883L_GetGain() 206 | * @see HMC5883L_RA_CONFIG_B 207 | * @see HMC5883L_CRB_GAIN_BIT 208 | * @see HMC5883L_CRB_GAIN_LENGTH 209 | */ 210 | void HMC5883L_SetGain(uint8_t gain) 211 | { 212 | // use this method to guarantee that bits 4-0 are set to zero, which is a 213 | // requirement specified in the datasheet; 214 | uint8_t tmp = gain << (HMC5883L_CRB_GAIN_BIT - HMC5883L_CRB_GAIN_LENGTH + 1); 215 | HMC5883L_I2C_ByteWrite(HMC5883L_DEFAULT_ADDRESS, &tmp, HMC5883L_RA_CONFIG_B); 216 | } 217 | 218 | // MODE register 219 | 220 | /** Get measurement mode. 221 | * In continuous-measurement mode, the device continuously performs measurements 222 | * and places the result in the data register. RDY goes high when new data is 223 | * placed in all three registers. After a power-on or a write to the mode or 224 | * configuration register, the first measurement set is available from all three 225 | * data output registers after a period of 2/fDO and subsequent measurements are 226 | * available at a frequency of fDO, where fDO is the frequency of data output. 227 | * 228 | * When single-measurement mode (default) is selected, device performs a single 229 | * measurement, sets RDY high and returned to idle mode. Mode register returns 230 | * to idle mode bit values. The measurement remains in the data output register 231 | * and RDY remains high until the data output register is read or another 232 | * measurement is performed. 233 | * 234 | * @return Current measurement mode 235 | * @see HMC5883L_MODE_CONTINUOUS 236 | * @see HMC5883L_MODE_SINGLE 237 | * @see HMC5883L_MODE_IDLE 238 | * @see HMC5883L_RA_MODE 239 | * @see HMC5883L_MODEREG_BIT 240 | * @see HMC5883L_MODEREG_LENGTH 241 | */ 242 | uint8_t HMC5883L_GetMode() 243 | { 244 | uint8_t tmp; 245 | HMC5883L_ReadBits(HMC5883L_DEFAULT_ADDRESS, HMC5883L_RA_MODE, HMC5883L_MODEREG_BIT, HMC5883L_MODEREG_LENGTH, &tmp); 246 | return tmp; 247 | } 248 | 249 | /** Set measurement mode. 250 | * @param newMode New measurement mode 251 | * @see HMC5883L_GetMode() 252 | * @see HMC5883L_MODE_CONTINUOUS 253 | * @see HMC5883L_MODE_SINGLE 254 | * @see HMC5883L_MODE_IDLE 255 | * @see HMC5883L_RA_MODE 256 | * @see HMC5883L_MODEREG_BIT 257 | * @see HMC5883L_MODEREG_LENGTH 258 | */ 259 | void HMC5883L_SetMode(uint8_t newMode) 260 | { 261 | // use this method to guarantee that bits 7-2 are set to zero, which is a 262 | // requirement specified in the datasheet; 263 | uint8_t tmp = HMC5883Lmode << (HMC5883L_MODEREG_BIT - HMC5883L_MODEREG_LENGTH + 1); 264 | HMC5883L_I2C_ByteWrite(HMC5883L_DEFAULT_ADDRESS, &tmp, HMC5883L_RA_MODE); 265 | HMC5883Lmode = newMode; // track to tell if we have to clear bit 7 after a read 266 | } 267 | 268 | // DATA* registers 269 | 270 | /** Get 3-axis heading measurements. 271 | * In the event the ADC reading overflows or underflows for the given channel, 272 | * or if there is a math overflow during the bias measurement, this data 273 | * register will contain the value -4096. This register value will clear when 274 | * after the next valid measurement is made. Note that this method automatically 275 | * clears the appropriate bit in the MODE register if Single mode is active. 276 | * @param x 16-bit signed integer container for X,Y,Z-axis heading 277 | * @see HMC5883L_RA_DATAX_H 278 | */ 279 | void HMC5883L_GetHeading(s16* Mag) 280 | { 281 | uint8_t tmpbuff[6] = { 0 }; 282 | HMC5883L_I2C_BufferRead(HMC5883L_DEFAULT_ADDRESS, tmpbuff, HMC5883L_RA_DATAX_H, 6); 283 | 284 | uint8_t tmp = HMC5883L_MODE_SINGLE << (HMC5883L_MODEREG_BIT - HMC5883L_MODEREG_LENGTH + 1); 285 | 286 | if (HMC5883Lmode == HMC5883L_MODE_SINGLE) 287 | HMC5883L_I2C_ByteWrite(HMC5883L_DEFAULT_ADDRESS, &tmp, HMC5883L_RA_MODE); 288 | for (int i = 0; i < 3; i++) 289 | Mag[i] = ((s16) ((u16) tmpbuff[2 * i] << 8) + tmpbuff[2 * i + 1]); 290 | } 291 | 292 | // STATUS register 293 | 294 | /** Get data output register lock status. 295 | * This bit is set when this some but not all for of the six data output 296 | * registers have been read. When this bit is set, the six data output registers 297 | * are locked and any new data will not be placed in these register until one of 298 | * three conditions are met: one, all six bytes have been read or the mode 299 | * changed, two, the mode is changed, or three, the measurement configuration is 300 | * changed. 301 | * @return Data output register lock status 302 | * @see HMC5883L_RA_STATUS 303 | * @see HMC5883L_STATUS_LOCK_BIT 304 | */ 305 | bool HMC5883L_GetLockStatus() 306 | { 307 | uint8_t tmp; 308 | HMC5883L_ReadBit(HMC5883L_DEFAULT_ADDRESS, HMC5883L_RA_STATUS, HMC5883L_STATUS_LOCK_BIT, &tmp); 309 | return tmp == 0x01 ? TRUE : FALSE; 310 | } 311 | 312 | /** Get data ready status. 313 | * This bit is set when data is written to all six data registers, and cleared 314 | * when the device initiates a write to the data output registers and after one 315 | * or more of the data output registers are written to. When RDY bit is clear it 316 | * shall remain cleared for 250 us. DRDY pin can be used as an alternative to 317 | * the status register for monitoring the device for measurement data. 318 | * @return Data ready status 319 | * @see HMC5883L_RA_STATUS 320 | * @see HMC5883L_STATUS_READY_BIT 321 | */ 322 | bool HMC5883L_GetReadyStatus() 323 | { 324 | uint8_t tmp; 325 | HMC5883L_ReadBit(HMC5883L_DEFAULT_ADDRESS, HMC5883L_RA_STATUS, HMC5883L_STATUS_READY_BIT, &tmp); 326 | return tmp == 0x01 ? TRUE : FALSE; 327 | } 328 | 329 | /** Write multiple bits in an 8-bit device register. 330 | * @param slaveAddr I2C slave device address 331 | * @param regAddr Register regAddr to write to 332 | * @param bitStart First bit position to write (0-7) 333 | * @param length Number of bits to write (not more than 8) 334 | * @param data Right-aligned value to write 335 | */ 336 | void HMC5883L_WriteBits(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data) 337 | { 338 | uint8_t tmp; 339 | HMC5883L_I2C_BufferRead(slaveAddr, &tmp, regAddr, 1); 340 | uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); 341 | data <<= (bitStart - length + 1); // shift data into correct position 342 | data &= mask; // zero all non-important bits in data 343 | tmp &= ~(mask); // zero all important bits in existing byte 344 | tmp |= data; // combine data with existing byte 345 | HMC5883L_I2C_ByteWrite(slaveAddr, &tmp, regAddr); 346 | } 347 | 348 | /** write a single bit in an 8-bit device register. 349 | * @param slaveAddr I2C slave device address 350 | * @param regAddr Register regAddr to write to 351 | * @param bitNum Bit position to write (0-7) 352 | * @param value New bit value to write 353 | */ 354 | void HMC5883L_WriteBit(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data) 355 | { 356 | uint8_t tmp; 357 | HMC5883L_I2C_BufferRead(slaveAddr, &tmp, regAddr, 1); 358 | tmp = (data != 0) ? (tmp | (1 << bitNum)) : (tmp & ~(1 << bitNum)); 359 | HMC5883L_I2C_ByteWrite(slaveAddr, &tmp, regAddr); 360 | } 361 | 362 | /** Read multiple bits from an 8-bit device register. 363 | * @param slaveAddr I2C slave device address 364 | * @param regAddr Register regAddr to read from 365 | * @param bitStart First bit position to read (0-7) 366 | * @param length Number of bits to read (not more than 8) 367 | * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05) 368 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in readTimeout) 369 | */ 370 | void HMC5883L_ReadBits(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data) 371 | { 372 | uint8_t tmp; 373 | HMC5883L_I2C_BufferRead(slaveAddr, &tmp, regAddr, 1); 374 | uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); 375 | tmp &= mask; 376 | tmp >>= (bitStart - length + 1); 377 | *data = tmp; 378 | } 379 | 380 | /** Read a single bit from an 8-bit device register. 381 | * @param slaveAddr I2C slave device address 382 | * @param regAddr Register regAddr to read from 383 | * @param bitNum Bit position to read (0-7) 384 | * @param data Container for single bit value 385 | * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in readTimeout) 386 | */ 387 | void HMC5883L_ReadBit(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data) 388 | { 389 | uint8_t tmp; 390 | HMC5883L_I2C_BufferRead(slaveAddr, &tmp, regAddr, 1); 391 | *data = tmp & (1 << bitNum); 392 | } 393 | 394 | /** 395 | * @brief Initializes the I2C peripheral used to drive the HMC5883L 396 | * @param None 397 | * @retval None 398 | */ 399 | void HMC5883L_I2C_Init() 400 | { 401 | I2C_InitTypeDef I2C_InitStructure; 402 | GPIO_InitTypeDef GPIO_InitStructure; 403 | 404 | /* Enable I2C and GPIO clocks */ 405 | RCC_APB1PeriphClockCmd(HMC5883L_I2C_RCC_Periph, ENABLE); 406 | RCC_APB2PeriphClockCmd(HMC5883L_I2C_RCC_Port, ENABLE); 407 | 408 | /* Configure I2C pins: SCL and SDA */ 409 | GPIO_InitStructure.GPIO_Pin = HMC5883L_I2C_SCL_Pin | HMC5883L_I2C_SDA_Pin; 410 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 411 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; 412 | GPIO_Init(HMC5883L_I2C_Port, &GPIO_InitStructure); 413 | 414 | /* I2C configuration */ 415 | I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; 416 | I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; 417 | I2C_InitStructure.I2C_OwnAddress1 = HMC5883L_DEFAULT_ADDRESS; // HMC5883L 7-bit adress = 0x1E; 418 | I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; 419 | I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; 420 | I2C_InitStructure.I2C_ClockSpeed = HMC5883L_I2C_Speed; 421 | 422 | /* Apply I2C configuration after enabling it */ 423 | I2C_Init(HMC5883L_I2C, &I2C_InitStructure); 424 | 425 | I2C_Cmd(HMC5883L_I2C, ENABLE); 426 | } 427 | 428 | /** 429 | * @brief Writes one byte to the HMC5883L. 430 | * @param slaveAddr : slave address HMC5883L_DEFAULT_ADDRESS 431 | * @param pBuffer : pointer to the buffer containing the data to be written to the HMC5883L. 432 | * @param WriteAddr : address of the register in which the data will be written 433 | * @retval None 434 | */ 435 | void HMC5883L_I2C_ByteWrite(u8 slaveAddr, u8* pBuffer, u8 WriteAddr) 436 | { 437 | // ENTR_CRT_SECTION(); 438 | 439 | /* Send START condition */ 440 | I2C_GenerateSTART(HMC5883L_I2C, ENABLE); 441 | 442 | /* Test on EV5 and clear it */ 443 | while (!I2C_CheckEvent(HMC5883L_I2C, I2C_EVENT_MASTER_MODE_SELECT)); 444 | 445 | /* Send HMC5883 address for write */ 446 | I2C_Send7bitAddress(HMC5883L_I2C, slaveAddr, I2C_Direction_Transmitter); 447 | 448 | /* Test on EV6 and clear it */ 449 | while (!I2C_CheckEvent(HMC5883L_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); 450 | 451 | /* Send the HMC5883L internal address to write to */ 452 | I2C_SendData(HMC5883L_I2C, WriteAddr); 453 | 454 | /* Test on EV8 and clear it */ 455 | while (!I2C_CheckEvent(HMC5883L_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); 456 | 457 | /* Send the byte to be written */ 458 | I2C_SendData(HMC5883L_I2C, *pBuffer); 459 | 460 | /* Test on EV8 and clear it */ 461 | while (!I2C_CheckEvent(HMC5883L_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); 462 | 463 | /* Send STOP condition */ 464 | I2C_GenerateSTOP(HMC5883L_I2C, ENABLE); 465 | // EXT_CRT_SECTION(); 466 | } 467 | 468 | /** 469 | * @brief Reads a block of data from the HMC5883L. 470 | * @param slaveAddr : slave address HMC5883L_DEFAULT_ADDRESS 471 | * @param pBuffer : pointer to the buffer that receives the data read from the HMC5883L. 472 | * @param ReadAddr : HMC5883L's internal address to read from. 473 | * @param NumByteToRead : number of bytes to read from the HMC5883L ( NumByteToRead >1 only for the Magnetometer reading). 474 | * @retval None 475 | */ 476 | void HMC5883L_I2C_BufferRead(u8 slaveAddr, u8* pBuffer, u8 ReadAddr, u16 NumByteToRead) 477 | { 478 | // ENTR_CRT_SECTION(); 479 | 480 | /* While the bus is busy */ 481 | while (I2C_GetFlagStatus(HMC5883L_I2C, I2C_FLAG_BUSY)); 482 | 483 | /* Send START condition */ 484 | I2C_GenerateSTART(HMC5883L_I2C, ENABLE); 485 | 486 | /* Test on EV5 and clear it */ 487 | while (!I2C_CheckEvent(HMC5883L_I2C, I2C_EVENT_MASTER_MODE_SELECT)); 488 | 489 | /* Send HMC5883L_Magn address for write */ // Send HMC5883L address for write 490 | I2C_Send7bitAddress(HMC5883L_I2C, slaveAddr, I2C_Direction_Transmitter); 491 | 492 | /* Test on EV6 and clear it */ 493 | while (!I2C_CheckEvent(HMC5883L_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); 494 | 495 | /* Clear EV6 by setting again the PE bit */ 496 | I2C_Cmd(HMC5883L_I2C, ENABLE); 497 | 498 | /* Send the HMC5883L's internal address to write to */ 499 | I2C_SendData(HMC5883L_I2C, ReadAddr); 500 | 501 | /* Test on EV8 and clear it */ 502 | while (!I2C_CheckEvent(HMC5883L_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); 503 | 504 | /* Send STRAT condition a second time */ 505 | I2C_GenerateSTART(HMC5883L_I2C, ENABLE); 506 | 507 | /* Test on EV5 and clear it */ 508 | while (!I2C_CheckEvent(HMC5883L_I2C, I2C_EVENT_MASTER_MODE_SELECT)); 509 | 510 | /* Send HMC5883L address for read */ 511 | I2C_Send7bitAddress(HMC5883L_I2C, slaveAddr, I2C_Direction_Receiver); 512 | 513 | /* Test on EV6 and clear it */ 514 | while (!I2C_CheckEvent(HMC5883L_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); 515 | 516 | /* While there is data to be read */ 517 | while (NumByteToRead) 518 | { 519 | if (NumByteToRead == 1) 520 | { 521 | /* Disable Acknowledgement */ 522 | I2C_AcknowledgeConfig(HMC5883L_I2C, DISABLE); 523 | 524 | /* Send STOP Condition */ 525 | I2C_GenerateSTOP(HMC5883L_I2C, ENABLE); 526 | } 527 | 528 | /* Test on EV7 and clear it */ 529 | if (I2C_CheckEvent(HMC5883L_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED)) 530 | { 531 | /* Read a byte from the HMC5883L */ 532 | *pBuffer = I2C_ReceiveData(HMC5883L_I2C); 533 | 534 | /* Point to the next location where the byte read will be saved */ 535 | pBuffer++; 536 | 537 | /* Decrement the read bytes counter */ 538 | NumByteToRead--; 539 | } 540 | } 541 | 542 | /* Enable Acknowledgement to be ready for another reception */ 543 | I2C_AcknowledgeConfig(HMC5883L_I2C, ENABLE); 544 | // EXT_CRT_SECTION(); 545 | } 546 | 547 | /** 548 | * @} 549 | *//* end of group HMC5883L_Library */ 550 | -------------------------------------------------------------------------------- /HMC5883L.chm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Harinadha/STM32_HMC5883Llib/ce5aa988df8b2affd7483747c89449194fc71766/HMC5883L.chm -------------------------------------------------------------------------------- /HMC5883L.h: -------------------------------------------------------------------------------- 1 | //HMC5883L I2C library for ARM STM32F103xx Microcontrollers - Main header file 2 | //Has bit, byte and buffer I2C R/W functions 3 | // 24/05/2012 by Harinadha Reddy Chintalapalli 4 | // Changelog: 5 | // 2012-05-24 - initial release. Thanks to Jeff Rowberg for his AVR/Arduino 6 | // based development which inspired me & taken as reference to develop this. 7 | /* ============================================================================================ 8 | HMC5883L device I2C library code for ARM STM32F103xx is placed under the MIT license 9 | Copyright (c) 2012 Harinadha Reddy Chintalapalli 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy 12 | of this software and associated documentation files (the "Software"), to deal 13 | in the Software without restriction, including without limitation the rights 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | copies of the Software, and to permit persons to whom the Software is 16 | furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in 19 | all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | THE SOFTWARE. 28 | ================================================================================================ 29 | */ 30 | 31 | #ifndef _HMC5883L_H_ 32 | #define _HMC5883L_H_ 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | /* Includes */ 39 | #include "HAL_HMC5883L.h" 40 | 41 | #define HMC5883L_ADDRESS 0x1E // this device only has one address 42 | #define HMC5883L_DEFAULT_ADDRESS (HMC5883L_ADDRESS<<1) 43 | 44 | #define HMC5883L_RA_CONFIG_A 0x00 45 | #define HMC5883L_RA_CONFIG_B 0x01 46 | #define HMC5883L_RA_MODE 0x02 47 | #define HMC5883L_RA_DATAX_H 0x03 48 | #define HMC5883L_RA_DATAX_L 0x04 49 | #define HMC5883L_RA_DATAY_H 0x05 50 | #define HMC5883L_RA_DATAY_L 0x06 51 | #define HMC5883L_RA_DATAZ_H 0x07 52 | #define HMC5883L_RA_DATAZ_L 0x08 53 | #define HMC5883L_RA_STATUS 0x09 54 | #define HMC5883L_RA_ID_A 0x0A 55 | #define HMC5883L_RA_ID_B 0x0B 56 | #define HMC5883L_RA_ID_C 0x0C 57 | 58 | #define HMC5883L_CRA_AVERAGE_BIT 6 59 | #define HMC5883L_CRA_AVERAGE_LENGTH 2 60 | #define HMC5883L_CRA_RATE_BIT 4 61 | #define HMC5883L_CRA_RATE_LENGTH 3 62 | #define HMC5883L_CRA_BIAS_BIT 1 63 | #define HMC5883L_CRA_BIAS_LENGTH 2 64 | 65 | #define HMC5883L_AVERAGING_1 0x00 66 | #define HMC5883L_AVERAGING_2 0x01 67 | #define HMC5883L_AVERAGING_4 0x02 68 | #define HMC5883L_AVERAGING_8 0x03 69 | 70 | #define HMC5883L_RATE_0P75 0x00 71 | #define HMC5883L_RATE_1P5 0x01 72 | #define HMC5883L_RATE_3 0x02 73 | #define HMC5883L_RATE_7P5 0x03 74 | #define HMC5883L_RATE_15 0x04 75 | #define HMC5883L_RATE_30 0x05 76 | #define HMC5883L_RATE_75 0x06 77 | 78 | #define HMC5883L_BIAS_NORMAL 0x00 79 | #define HMC5883L_BIAS_POSITIVE 0x01 80 | #define HMC5883L_BIAS_NEGATIVE 0x02 81 | 82 | #define HMC5883L_CRB_GAIN_BIT 7 83 | #define HMC5883L_CRB_GAIN_LENGTH 3 84 | 85 | #define HMC5883L_GAIN_1370 0x00 86 | #define HMC5883L_GAIN_1090 0x01 87 | #define HMC5883L_GAIN_820 0x02 88 | #define HMC5883L_GAIN_660 0x03 89 | #define HMC5883L_GAIN_440 0x04 90 | #define HMC5883L_GAIN_390 0x05 91 | #define HMC5883L_GAIN_330 0x06 92 | #define HMC5883L_GAIN_220 0x07 93 | 94 | #define HMC5883L_MODEREG_BIT 1 95 | #define HMC5883L_MODEREG_LENGTH 2 96 | 97 | #define HMC5883L_MODE_CONTINUOUS 0x00 98 | #define HMC5883L_MODE_SINGLE 0x01 99 | #define HMC5883L_MODE_IDLE 0x02 100 | 101 | #define HMC5883L_STATUS_LOCK_BIT 1 102 | #define HMC5883L_STATUS_READY_BIT 0 103 | 104 | void HMC5883L_Initialize(); 105 | bool HMC5883L_TestConnection(); 106 | 107 | // CONFIG_A register 108 | uint8_t HMC5883L_GetSampleAveraging(); 109 | void HMC5883L_SetSampleAveraging(uint8_t averaging); 110 | uint8_t HMC5883L_GetDataRate(); 111 | void HMC5883L_SetDataRate(uint8_t rate); 112 | uint8_t HMC5883L_GetMeasurementBias(); 113 | void HMC5883L_SetMeasurementBias(uint8_t bias); 114 | 115 | // CONFIG_B register 116 | uint8_t HMC5883L_GetGain(); 117 | void HMC5883L_SetGain(uint8_t gain); 118 | 119 | // MODE register 120 | uint8_t HMC5883L_GetMode(); 121 | void HMC5883L_SetMode(uint8_t mode); 122 | 123 | // DATA* registers 124 | void HMC5883L_GetHeading(s16* Mag); 125 | // STATUS register 126 | bool HMC5883L_GetLockStatus(); 127 | bool HMC5883L_GetReadyStatus(); 128 | 129 | void HMC5883L_WriteBits(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data); 130 | void HMC5883L_WriteBit(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data); 131 | void HMC5883L_ReadBits(uint8_t slaveAddr, uint8_t regAddr , uint8_t bitStart, uint8_t length, uint8_t *data); 132 | void HMC5883L_ReadBit(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data); 133 | 134 | void HMC5883L_I2C_Init(); 135 | void HMC5883L_I2C_ByteWrite(u8 slaveAddr, u8* pBuffer, u8 WriteAddr); 136 | void HMC5883L_I2C_BufferRead(u8 slaveAddr,u8* pBuffer, u8 ReadAddr, u16 NumByteToRead); 137 | 138 | #ifdef __cplusplus 139 | } 140 | #endif 141 | 142 | #endif /* _HMC5883L_H_ */ 143 | 144 | /******************* (C) COPYRIGHT 2012 Harinadha Reddy Chintalapalli *****END OF FILE****/ 145 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | ============================================================================ 2 | For More details, visit: http://harinadha.wordpress.com 3 | ============================================================================ 4 | 5 | The HMC5883L I2C Device Library provides simple and intuitive interfaces to HMC5883L I2C device on ARM 32-bit STM32F103xx family of microcontrollers.It has the I2C bit- and byte-level communication for complete coverage of all functionality described by HMC5883L documentation. 6 | 7 | The code is written primarily to support the HMC5883L I2C device implementation, but it may be useful to extend it to other I2C devices. 8 | 9 | Documentation is created using Doxygen-style comments placed in each definition file, based on the information available in device's datasheet. This documentation will be available in HTML format on the http://harinadha.wordpress.com website, which also holds helpful information for some problems i faced in implementing this library. 10 | 11 | This library depends on only the following header files from STM32F10xFWLib v3.3.0: 12 | 13 | stm32f10x.h 14 | stm32f10x_i2c.h 15 | 16 | Want a library for a device that isn't up on the repository? Request it, or fork the code and contribute! Better yet, send me a device on a breakout board to test the code during development. No guarantees on how fast I can get it done, but I'd love to make good consistent and well-documented library for ARM STM32F103xx platform. 17 | --------------------------------------------------------------------------------