打印
[其它]

QMC5883L 源代码 分享&PT32L007

[复制链接]
137|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主



/**
  ******************************************************************************
  * @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*/


使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

21

帖子

0

粉丝