RM3100应用笔记驱动程序SPI接口

PNI磁传感器套件RM3100磁传感器套件由2个Sen-XY-f(pn13104)地磁传感器,1个Sen-Z-f(pn13101)地磁传感器和MagI2C(pn13156)控制芯片组成,能够实现三维空间的磁场大小测量。

RM3100.c


#include "stm32f10x.h"
#include "mag3d3100.h"

#define MAG_ON

#define CS_L			GPIO_ResetBits(GPIOB, GPIO_Pin_12)
#define CS_H			GPIO_SetBits(GPIOB, GPIO_Pin_12)

extern uint8_t Tx_Update_Enable;


/** 定义结构 */
struct config {
    unsigned int cycle_count;
    float sample_rate;
    float max_data_rate;
    float gain;
};
/* Default Values c99*/
struct config rm = {
    .cycle_count   = 200,
    .sample_rate   = 37,
    .max_data_rate = 440,
    .gain          = 75
};

u8 SPI_WriteByte(SPI_TypeDef* SPIx,u8 data) 
{ 
  u8 Data = 0;

  //Wait until the transmit buffer is empty 
  while(SPI_I2S_GetFlagStatus(SPIx,SPI_I2S_FLAG_TXE)==RESET); 
  // Send the byte  
  SPI_I2S_SendData(SPIx,data); 

  //Wait until a data is received 
  while(SPI_I2S_GetFlagStatus(SPIx,SPI_I2S_FLAG_RXNE)==RESET); 
  // Get the received data 
  Data = SPI_I2S_ReceiveData(SPIx); 

  // Return the shifted data 
  return Data; 

}  
//多字节写入寄存器
u8 SPI_Write_M3D3100(SPI_TypeDef* SPIx,u8 reg_addr,u8 *datain,u8 lenth)
{
	u8 bytecount=0;
	u8 temp=0;
 
	CS_L ;
	Delay_ms(10);	
	temp=0x00+(reg_addr&0x3f); //MSB=0  read reg
	SPI_WriteByte(SPIx,temp);

	//send lest bytes
	for(bytecount=0;bytecount<lenth;bytecount++)
	{
		temp=*(datain+bytecount);
		SPI_WriteByte(SPIx,temp);
	}
	CS_H;
	return 0;
}

u8 SPI_Read_M3D3100(SPI_TypeDef* SPIx,u8 reg_addr,u8 *dataout,u8 lenth)
{
	u8 bytecount=0;
	u8 temp=0;	
	
	CS_L;
	
	temp=0x80+(reg_addr&0x3f); //MSB=1 rw=1-->addr auto increase
	SPI_WriteByte(SPIx,temp);

	for(bytecount=0;bytecount<lenth;bytecount++)
	{
		temp=SPI_WriteByte(SPIx,0);
		*(dataout+bytecount) = temp;
	}
	CS_H ;
	return 0;	
}
/**
 *  @brief  Sets cycle count and updates gain and max_data_rate values
 *  @param[in]  desire value PNI recomends values between 30 and 400 Hz
 *  @return     1 if successful, 0 otherwise.
 */
bool setCycleCount ( u16 value ) {

    char to_reg[6];

    if (value > 65535 || value<0)
        return FALSE;
    else{

        if (value > 400)
            value=400;
        else if (value < 30)
            value=30;

        to_reg[0] = value>>8;
        to_reg[1] = value;
        to_reg[2] = to_reg[0];
        to_reg[3] = to_reg[1];
        to_reg[4] = to_reg[0];
        to_reg[5] = to_reg[1];

        if (SPI_Write_M3D3100(SPI2, M3D_3100_CCX, to_reg,6))
            return FALSE;

    }
    return TRUE;
}


/**
 *  @brief  Sets data rate in Continuous Measurement Mode.
 *  Fails if desire datarate is higher than the max data rate recommended by PNI.
 *  @param[in]  Data rate configuration BYTE
 *  @return     1 if successful, 0 otherwise.
 */
bool setCMMdatarate ( char conf ) {

    if (conf < CMM_UPDATERATE_600 || conf > CMM_UPDATERATE_0_075)
        return FALSE;
    else{
        char *ptr;
        float temp = 1000;

        switch (conf){
            case CMM_UPDATERATE_600: temp=600;
                                    break;
            case CMM_UPDATERATE_300: temp=300;
                                    break;
            case CMM_UPDATERATE_150: temp=150;
                                    break;
            case CMM_UPDATERATE_75 : temp=75;
                                    break;
            case CMM_UPDATERATE_37 : temp=37;
                                    break;
            case CMM_UPDATERATE_18 : temp=18;
                                    break;
            case CMM_UPDATERATE_9  : temp=9;
                                    break;
            case CMM_UPDATERATE_4_5: temp=4.5;
                                    break;
            case CMM_UPDATERATE_2_3: temp=2.3;
                                    break;
            case CMM_UPDATERATE_1_2: temp=1.2;
                                    break;
            case CMM_UPDATERATE_0_6: temp=0.6;
                                    break;
            case CMM_UPDATERATE_0_3: temp=0.3;
                                    break;
            case CMM_UPDATERATE_0_15: temp=0.15;
                                    break;
            case CMM_UPDATERATE_0_075: temp=0.075;
                                    break;
        }
        if (temp > rm.max_data_rate)				
            return FALSE;

        ptr = &conf ;
        if (SPI_Write_M3D3100(SPI2, M3D_3100_TMRC, ptr,1))
            return FALSE;
        else{
            rm.sample_rate = temp;
        }
    }
    return TRUE;
}


void setCMMdtr(char dtr)
{
	char temp;
   switch (dtr){
		case 14:
			temp=CMM_UPDATERATE_600;
         break;
		case 13:
			temp=CMM_UPDATERATE_300;
         break;
		case 12:
			temp=CMM_UPDATERATE_150;
         break;
		case 11:
			temp=CMM_UPDATERATE_75;
         break;
		case 10:
			temp=CMM_UPDATERATE_37;
         break;
		case 9:
			temp=CMM_UPDATERATE_18;
         break;
		case 8:
			temp=CMM_UPDATERATE_9;
         break;
		case 7:
			temp=CMM_UPDATERATE_4_5;
         break;		
		case 6:
			temp=CMM_UPDATERATE_2_3;
         break;
		case 5:
			temp=CMM_UPDATERATE_1_2;
         break;
		case 4:
			temp=CMM_UPDATERATE_0_6;
         break;
		case 3:
			temp=CMM_UPDATERATE_0_3;
         break;
		case 2:
			temp=CMM_UPDATERATE_0_15;
         break;
		case 1:
			temp=CMM_UPDATERATE_0_075;
         break;
      }

	setCMMdatarate ( temp );
}
/**
 *  @brief  Continuous Measurement Mode (CMM) Register Configuration.
 *  @param[in]  CMM configuration BYTE:
 *  @return     1 if successful, 0 otherwise.
 */
bool continuousModeConfig ( char conf ) {

    char *ptr;

    ptr = &conf ;
    if (SPI_Write_M3D3100(SPI2, M3D_3100_CMM, ptr,1))
        return FALSE;

    return TRUE;
}

/**
 *  @brief      Request Single Measurement to PNI ASIC.
 *  @param[in]  none:0*** 0000  :
 *  @return     1 if successful, 0 otherwise.
 */
bool requestSingleMeasurement ( void ) {

    char to_reg = SM_ALL_AXIS;
    char *ptr;

    ptr = &to_reg;
    if (SPI_Write_M3D3100(SPI2, M3D_3100_POLL, ptr,1))
        return FALSE;

    return TRUE;
}

/**
 *  @brief      Get data ready Status
 *  @param[in]  none
 *  @return     1 if data ready, 0 otherwise.
 */
bool getDataReadyStatus ( void ) {

    char data[1];

    SPI_Read_M3D3100(SPI2, M3D_3100_STATUS,  data,1);

    return (data[0] & STATUS_MASK);
}

/**
 *  @brief      Self test to Ev Board.
 *  @param[in]  none  缺省值0x1b
 *  @return     1 if all axis OK, 0 otherwise.
 */
bool getRM3100Status ( void ) {

    char data[1];
    char to_reg = STE_ON | BW_11 | BP_11;
    char *ptr;

    ptr = &to_reg;
    if (SPI_Write_M3D3100(SPI2, M3D_3100_BIST, ptr,1))
        return FALSE;

    if (requestSingleMeasurement ()==FALSE)
        return FALSE;

    while(!getDataReadyStatus());
    
    if (SPI_Read_M3D3100(SPI2, M3D_3100_BIST,  data,1))
        return FALSE;

    if (data[0] & STE_ON){
        to_reg = STE_OFF;
        ptr = &to_reg;
        if (SPI_Write_M3D3100(SPI2, M3D_3100_BIST, ptr,1))
            return FALSE;

        return (data[0] & BIST_MASK);
    }
    return FALSE;
}

/**
 *  @brief      Request RM3100 Ev. Board Revision
 *  @param[in]  none
 *  @return     Revision value.
 */
char getRM3100revision ( void ) {

   char data[1];

	SPI_Read_M3D3100(SPI2, M3D_3100_REVID,  data,1);
   return data[0];
}


void ThreeD3100_magic_init(void)
{
	u8  i=0;
	u8 cycle_count_read_back[6]={0};

	SPI2_Init();
	Delay_ms(100);

	continuousModeConfig(CMM_ALL_AXIS_ON|DRDY_WHEN_ALL_AXIS_MEASURED|CM_START); 			//设置测试轴,drdy 开启连续模式
	setCycleCount(200);												//设置CCR寄存器200
	setCMMdatarate(12);
	Delay_ms(100);	

	SPI_Read_M3D3100(SPI2,M3D_3100_CCX,cycle_count_read_back,6);								//for verification purpose only.   回读 验证是否写入
}

/**************************实现函数********************************************
*函数原型:	  void MagL_Start_Calib(void)
*功  能:	   进入磁力计标定
输入参数:     	
输出参数:  无
*******************************************************************************/

void ThreeD3100_magic_GetData(MagData_t* buff)
{
 u8 i;
 u8 temp[9]={0};

 s32 Mag_Data[3]={0};
 char err[5]={0xaa,0x00,0xa1,0xa2,0xa3};
// Spi2_Init(0);
// Delay(1000);

while(M3D_DRDY==0);

 CS_H ;
 SPI_Read_M3D3100(SPI2,0x24,temp,9);
 Mag_Data[0]=temp[0]<<16 | temp[1]<<8 | temp[2];			
 Mag_Data[1]=temp[3]<<16 | temp[4]<<8 | temp[5];
 Mag_Data[2]=temp[6]<<16 | temp[7]<<8 | temp[8];

 for(i=0;i<3;i++)
 {
 if(Mag_Data[i]&0x00800000)
	Mag_Data[i]|=0xff000000;
 }
 
 buff->MAG_X=Mag_Data[0];
 buff->MAG_Y=Mag_Data[1];
 buff->MAG_Z=Mag_Data[2]; 
}



RM3100.h

#ifndef __MAG3D3100_H
#define __MAG3D3100_H

#include "stm32f10x.h"

//#define MAG_ON

#define M3D_3100_POLL 	    0			//0X00
#define M3D_3100_CMM		1			//0X00
#define M3D_3100_CCX		4			//0X00C8
#define M3D_3100_CCY		6			//0X00C8
#define M3D_3100_CCZ		8			//0X00C8
#define M3D_3100_TMRC	0x0B		//0X96
#define M3D_3100_MX		0x24
#define M3D_3100_MY		0x27
#define M3D_3100_MZ		0x2A
#define M3D_3100_BIST	0x33
#define M3D_3100_STATUS	0x34
#define M3D_3100_HSHAKE	0x35		//0X1B
#define M3D_3100_REVID  0x36


/// Configurations for continuous measurement mode
#define CMM_OFF                       0x00
#define CM_START                      0x01
#define ALARM_BIT                     0x02
#define DRDY_WHEN_ALARM_AND_ALL_AXIS  0x00
#define DRDY_WHEN_ANY_AXIS_MEASURED   0x04
#define DRDY_WHEN_ALL_AXIS_MEASURED   0x08
#define DRDY_WHEN_ALARM               0x0C
#define CMM_ALL_AXIS_ON               0x70
#define CMM_X_AXIS                    0x10
#define CMM_Y_AXIS                    0x20
#define CMM_Z_AXIS                    0x40
#define LDM_BIT                       0x80

/// Possible data rate choices
#define CMM_UPDATERATE_600            0x92
#define CMM_UPDATERATE_300            0x93
#define CMM_UPDATERATE_150            0x94
#define CMM_UPDATERATE_75             0x95
#define CMM_UPDATERATE_37             0x96
#define CMM_UPDATERATE_18             0x97
#define CMM_UPDATERATE_9              0x98
#define CMM_UPDATERATE_4_5            0x99
#define CMM_UPDATERATE_2_3            0x9A
#define CMM_UPDATERATE_1_2            0x9B
#define CMM_UPDATERATE_0_6            0x9C
#define CMM_UPDATERATE_0_3            0x9D
#define CMM_UPDATERATE_0_15           0x9E
#define CMM_UPDATERATE_0_075          0x9F

#define M3D_DRDY  	(GPIOB->IDR & GPIO_Pin_1)
#define CS_L			GPIO_ResetBits(GPIOB, GPIO_Pin_12)
#define CS_H			GPIO_SetBits(GPIOB, GPIO_Pin_12)

/// Configurations for Self test
#define STE_ON    0x80
#define STE_OFF   0x00
#define BW_00    0x00
#define BW_01    0x04
#define BW_10    0x08
#define BW_11    0x0C
#define BP_00    0x00
#define BP_01    0x01
#define BP_10    0x02
#define BP_11    0x03

typedef struct {
  s32 MAG_X;
  s32 MAG_Y;
  s32 MAG_Z;
} MagData_t;

#define SM_ALL_AXIS    0x70 /** Single measument mode */
#define STATUS_MASK    0x80 /** To get status of data ready */
#define BIST_MASK      0x70 /** To get status of the Ev Board */

//void SPI2_Init(void);
void ThreeD3100_magic_init(void);
void ThreeD3100_magic_GetData(MagData_t* buff);
u8 SPI_Write_M3D3100(SPI_TypeDef* SPIx,u8 reg_addr,u8 *datain,u8 lenth);
u8 SPI_Read_M3D3100(SPI_TypeDef* SPIx,u8 reg_addr,u8 *dataout,u8 lenth);

#endif

  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
RM3100是一种高精度、低功耗的磁传感器,常用于姿态检测、导航、机器人等领域。为了让RM3100能够正常工作,我们需要安装相应的驱动程序。 首先,我们可以从RM3100的官方网站或者供应商的网站上下载到最新版本的驱动程序。下载后,我们需要将驱动程序解压缩到计算机的特定文件夹中。 接下来,我们需要连接RM3100与计算机。如果我们使用的是I2C接口连接,我们需要将RM3100与计算机的I2C总线相连。如果使用SPI接口,我们则需将RM3100与计算机的SPI接口相连。此外,在连接之前,还需要确保供电电压与电流符合RM3100的要求。 一旦确保连接正确,我们可以打开计算机上的设备管理器,并找到RM3100磁传感器。如果驱动程序没有正确安装,设备管理器将显示黄色感叹号或问号。 在设备管理器中,我们可以选择更新驱动程序,选择手动安装驱动程序,并选择我们之前解压缩的驱动程序所在的文件夹。 一旦我们完成安装,设备管理器将显示磁传感器设备的名称,并且没有任何错误标志。 现在,我们可以在计算机上编写程序,使用RM3100磁传感器进行姿态检测、导航或机器人控制等应用。在编写代码时,我们需要调用相应的接口进行数据读取和处理。 总的来说,安装RM3100的驱动程序是使用该磁传感器进行正常工作的必要步骤。在正确安装驱动程序后,我们就可以利用RM3100进行各种应用领域的开发和研究。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AIOT技术栈

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值