/**
******************************************************************************
* @file QMC5883L.c
* @author Yangzhiqiang@qst
* @version V1.0
* @date 2020-5-27
* @brief QMC5883L
******************************************************************************
* @attention
*
*
******************************************************************************
*/
#include "QMC5883L.h"
#include "PT32x007x.h"
#include "string.h"
#define QMC5883_ADDR (0x1A)//0x0D //0x1a
#define fabs(x) (x < 0 ? -x : x)
void delay_us(uint32_t delay)
{
uint32_t i,j,k;
for(i=0;i<delay;i++)
{
for(j=0;j<100;j++)
{
k++;
}
}
}
//---------------------------------------
/**
* @brief IIC写函数
* @param pBuffer:需要写入的数据
* @param WriteAddr:从机地址
* @param NumByteToWrite:需要写入的数据长度
* @retval 无
*/
void Acce_Write_Byte(unsigned int WriteAddr, u8 data)
{
// int i;
/******************等待从机ready***************/
I2C_GenerateEvent(I2C,I2C_Event_Start,DISABLE);
I2C->CCR |= I2C_CCR_SI | I2C_CCR_ACK;
I2C_Cmd(I2C,DISABLE);
I2C_Cmd(I2C,ENABLE);
// printf("%s %d\r\n", __func__, __LINE__) ;
I2C_GenerateEvent(I2C,I2C_Event_Start,ENABLE);
while(I2C_GetFlagStatus(I2C,I2C_FLAG_StartOk)!= SET);
I2C_SendAddr(I2C, QMC5883_ADDR);//器件地址,写
while(I2C_GetFlagStatus(I2C,I2C_FLAG_MASGetAckW)!=SET);
// printf("%s %d\r\n", __func__, __LINE__) ;
I2C_SendData(I2C,WriteAddr);//发送要写的字地址
while(I2C_GetFlagStatus(I2C,I2C_FLAG_MDSGetAck)!=SET);
I2C_SendData(I2C, data);
while(I2C_GetFlagStatus(I2C,I2C_FLAG_MDSGetAck) != SET);
/******************发送停止位***************/
I2C_GenerateEvent(I2C,I2C_Event_Stop,ENABLE);
}
//uint8_t I2C_EE_Read(u8* pBuffer,u16 ReadAddr, u16 DeviceAddr, u16 data_size)
uint8_t Acce_Read_Byte(u16 ReadAddr)
{
// int i;
uint8_t date = 0 ;
/******************等待从机ready***************/
//printf("---%s %d---\n", __func__, __LINE__) ;
I2C_GenerateEvent(I2C,I2C_Event_Start,ENABLE);
while(I2C_GetFlagStatus(I2C,I2C_FLAG_StartOk)!= SET);
// printf("---%s %d---\n", __func__, __LINE__) ;
I2C_SendAddr(I2C, QMC5883_ADDR);//器件地址,写
while(I2C_GetFlagStatus(I2C,I2C_FLAG_MASGetAckW)!=SET);
I2C_SendData(I2C,ReadAddr);//发送要读的页地址
while(I2C_GetFlagStatus(I2C,I2C_FLAG_MDSGetAck)!=SET);
I2C_GenerateEvent(I2C,I2C_Event_Stop,ENABLE);
/******************接收数据***************/
I2C_GenerateEvent(I2C,I2C_Event_Start,ENABLE);
while(I2C_GetFlagStatus(I2C,I2C_FLAG_StartOk)!= SET);
I2C_SendAddr(I2C, QMC5883_ADDR + 1);//器件地址,读
while(I2C_GetFlagStatus(I2C,I2C_FLAG_MASGetAckR)!=SET);
I2C->CCR=I2C_CCR_ACK|I2C_CCR_SI;//主机发送NACK
while(I2C_GetFlagStatus(I2C,I2C_FLAG_MDGSendNack) != SET);
date = I2C_ReceiveData(I2C);
/******************发送停止位***************/
I2C_GenerateEvent(I2C,I2C_Event_Stop,ENABLE);
return date ;
}
//---------------------------------------
uint8_t QMC5883_ReadReg(uint8_t Reg)
{
u8 RegVal = 0;
RegVal = Acce_Read_Byte(Reg);
return RegVal;
}
void QMC5883_WriteReg(uint8_t Reg,uint8_t Val)
{
Acce_Write_Byte(Reg, Val);
}
uint8_t QMC5883_InitConfig(void)
{
uint8_t Temp;
QMC5883_WriteReg(0x0B, 0x01);
QMC5883_WriteReg(0x20, 0x40);
QMC5883_WriteReg(0x21, 0x01);
QMC5883_WriteReg(0x09, 0x1D);/****OSR=512,RNG=+/-2G,ODR=200Hz,MODE= continuous*******/
//QMC5883 initial cost a lot time.
Temp = QMC5883_ReadReg(0x0d);
printf(" read id=0x%x\r\n", Temp) ;
while(Temp != 0x1D)
{
return 0;
}
return Temp;
}
uint8_t QMC5883_GetData(float *Magnet)
{
uint8_t Buff[6], i;
uint8_t Temp;
int16_t MagnetRawAd[3];
Temp = QMC5883_ReadReg(0x06);
if(Temp == 0)
{
return 0;
}
Buff[0] =Acce_Read_Byte(0x00); delay_us(200) ;
Buff[1] =Acce_Read_Byte(0x01); delay_us(200) ;
Buff[2] =Acce_Read_Byte(0x02); delay_us(200) ;
Buff[3] =Acce_Read_Byte(0x03); delay_us(200) ;
Buff[4] =Acce_Read_Byte(0x04); delay_us(200) ;
Buff[5] =Acce_Read_Byte(0x05); delay_us(200) ;
MagnetRawAd[0] = (int16_t)((Buff[1] << 8) | Buff[0]);
MagnetRawAd[1] = (int16_t)((Buff[3] << 8) | Buff[2]);
MagnetRawAd[2] = (int16_t)((Buff[5] << 8) | Buff[4]);
// Magnet[0] = -(float)MagnetRawAd[0] / 12000.f;
// Magnet[1] = (float)MagnetRawAd[1] / 12000.f;
// Magnet[2] = -(float)MagnetRawAd[2] / 12000.f;
// Magnet[0] = -(float)MagnetRawAd[0] / 120.f;
// Magnet[1] = (float)MagnetRawAd[1] / 120.f;
// Magnet[2] = -(float)MagnetRawAd[2] / 120.f;
Magnet[0] = (float)MagnetRawAd[0] / 30.f;
Magnet[1] = -(float)MagnetRawAd[1] / 30.f;
Magnet[2] = -(float)MagnetRawAd[2] / 30.f;
printf("x=%.2f y=%.2f z=%.2f\n", Magnet[0], Magnet[1], Magnet[2]) ;
return 1;
}
#ifndef __QMC5883L_H
#define __QMC5883L_H
#include "PT32x007x.h"
#include <stdbool.h>
#include <string.h>
// Registers
#define QMC5883L_REG_CONF1 0x09
#define QMC5883L_REG_CONF2 0x0A
// data output rates for 5883L
#define QMC5883L_ODR_10HZ (0x00 << 2)
#define QMC5883L_ODR_50HZ (0x01 << 2)
#define QMC5883L_ODR_100HZ (0x02 << 2)
#define QMC5883L_ODR_200HZ (0x03 << 2)
// Sensor operation modes
#define QMC5883L_MODE_STANDBY 0x00
#define QMC5883L_MODE_CONTINUOUS 0x01
#define QMC5883L_RNG_2G (0x00 << 4)
#define QMC5883L_RNG_8G (0x01 << 4)
#define QMC5883L_OSR_512 (0x00 << 6)
#define QMC5883L_OSR_256 (0x01 << 6)
#define QMC5883L_OSR_128 (0x10 << 6)
#define QMC5883L_OSR_64 (0x11 << 6)
#define QMC5883L_RST 0x80
#define QMC5883L_REG_DATA_OUTPUT_X 0x00
#define QMC5883L_REG_STATUS 0x06
#define QMC5883L_REG_ID 0x0D
#define QMC5883_ID_VAL 0xFF
uint8_t QMC5883_InitConfig(void);
uint8_t QMC5883_GetData(float *Magnet);
uint8_t QMC5883_DumpMag(void);
#endif /*QMC5883L*/
|
感谢分享