本文主要是介绍AK8975磁力计数据采集--模拟SPI读取,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
AK8975磁力计数据采集–模拟SPI读取
1、ak8975磁力计特性
1.1 四种模式:
1.2 SPI读写时序
SPI工作在模式3
CSB拉低表示开启SPI数据读取模式, SK上升沿读取数据,下降沿数据进行变换
SPI写数据时序图
SPI读数据时序图
2、模拟SPI读取磁力计
AK8975寄存器地址
#define AK8975_WIA_REG 0X00
#define AK8975_INFO_REG 0X01
#define AK8975_ST1_REG 0X02
#define AK8975_HXL_REG 0X03
#define AK8975_HXH_REG 0X04
#define AK8975_HYL_REG 0X05
#define AK8975_HYH_REG 0X06
#define AK8975_HZL_REG 0X07
#define AK8975_HZH_REG 0X08
#define AK8975_ST2_REG 0X09
#define AK8975_CNTL_REG 0X0A
#define AK8975_RSV_REG 0X0B
#define AK8975_ASTC_REG 0X0C
#define AK8975_TS1_REG 0X0D
#define AK8975_TS2_REG 0X0E
#define AK8975_I2CDIS_REG 0X0F
#define AK8975_ASAX_REG 0X10
#define AK8975_ASAY_REG 0X11
#define AK8975_ASAZ_REG 0X12
模拟SPI读写函数
/*******************************************************************************
** 名 称 : SPIReadWriteByte
** 功 能 : SPI 收发字节
** 入口参数 :txd:发送字节
** 出口参数 : rev:返回字节
*******************************************************************************/
unsigned char ak8975SPIReadWriteByte(unsigned char txd)
{ unsigned char i; unsigned int rev = 0;AK8975_SK = 0;for(i=0; i<8; i++){ if (txd&0x80){AK8975_SI = 1;delay_us(1);}else{AK8975_SI = 0;delay_us(1);}txd<<=1;AK8975_SK=1; //上升沿时读写数据, 下降沿时交换数据rev <<= 1;delay_us(1);if (AK8975_SO == 1) // 下降沿来临之前AK8975_SO还没有变{rev++;}AK8975_SK=0; delay_us(1);} return rev;
}
Ak8975数据读取函数
/*******************************************************************************
** 名 称 : AK8975_Read
** 功 能 : ak8975读取数据
** 入口参数 :reg: 寄存器地址 buf:存储读取到的字节数据 len:需要读取数据的长度
** 出口参数 : void
*******************************************************************************/
void AK8975_Read(u8 reg, u8 *ak8975_buf, u8 len)
{ AK8975_SK = 1;AK8975_CSB = 0;delay_us(1);ak8975SPIReadWriteByte(reg | 0x80); // 0写 1读 for(u8 i=0; i<len; i++){*ak8975_buf = ak8975SPIReadWriteByte(0xff); // 读ak8975_buf++;}AK8975_CSB = 1;delay_us(1);ak8975_Trig();
}/*******************************************************************************
** 名 称 : ak8975IdCheck
** 功 能 : ak8975读取ak8975的ID
** 入口参数 : void
** 出口参数 : 返回ID: 0x48
*******************************************************************************/
u8 ak8975IdCheck()
{u8 add;AK8975_SK = 1;AK8975_CSB = 0;ak8975SPIReadWriteByte(AK8975_WIA_REG|0x80); // 0写 1读 add = ak8975SPIReadWriteByte(0xff); // 读AK8975_SK = 1;AK8975_CSB = 1;delay_us(1);ak8975_Trig();return add;
}/*******************************************************************************
** 名 称 : ak8975_Trig
** 功 能 : ak8975状态切换: 每次读取完数据后,ak8975都会自动变为power-down模式,所以每次读完数据都需要重新设置成单次测量模式
** 入口参数 : void
** 出口参数 : void
*******************************************************************************/
void ak8975_Trig(void)
{AK8975_CSB = 0;ak8975SPIReadWriteByte(AK8975_CNTL_REG & 0x7f);ak8975SPIReadWriteByte(0x01);AK8975_CSB = 1;
}// 最终数据可以这样获取
Drv_AK8975_Read(AK8975_HXL_REG, ak8975_buf, 6); // 连续读6个字节数据
// 磁数据 数字量
mag_x = (((int16_t)ak8975_buf[1]) << 8) | ak8975_buf[0];
mag_y = (((int16_t)ak8975_buf[3]) << 8) | ak8975_buf[2];
mag_z = (((int16_t)ak8975_buf[5]) << 8) | ak8975_buf[4];**mag_x、mag_y 、mag_z 为采集的数字量,datasheet中提到分辨率为0.3uT/LSB
实际数据 = mag_x * 0.3 单位uT 1uT = 10mG(毫高斯)
实际数据 = mag_x * 0.3 * 10 单位mG
注意:每次读取的间隔需要*20ms*左右(经验值), 具体可以通过读取DRDY位来判断数据是否就绪**
3、总结
由于个人水平有限,如有错误,欢迎指正。
需要源代码的可以下方留言,留下邮箱即可。
这篇关于AK8975磁力计数据采集--模拟SPI读取的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!