LIS3DH 三軸加速度傳感器使用流程及示例

 

LIS3DH是一個三軸加速度傳感器,可用於檢測X、Y、Z軸上的加速度,以及設置閾值,在加速度超出閾值時觸發中斷。
支持SPI和IIC讀寫。
測試

下面主要是IIC方式讀寫:ui

 

1、寄存器讀寫流程


首先硬件鏈接會決定該模塊的IIC地址
若是SAO腳接地,IIC地址爲0X30(不包含最低位).
若是接V3.3,則IIC地址爲0X32(不包含最低位).




spa

這個器件地址很重要,由於讀寫寄存器都是要先寫一下對應的器件地址,而後再寫命令的code

注意先發送的器件地址只是前7位,最後一位決定的是讀寫位,0是寫寄存器,1爲讀寄存器,因此寫寄存器時是寫「LIS_ADDR|0x00」,讀的時候則是「LIS_ADDR|0x01」blog

a、主機向從機寫一個字節,下表是經過IIC向LIS3DH寄存器寫一個字節的流程。簡單來講就是先寫1個字節的寫命令+IIC地址,再寫一個字節的你要寫的寄存器地址,最後寫一個字節你要寫入寄存器的內容

事件

示例:it

//IIC寫一個字節
//reg:寄存器地址
//data:數據
//返回值:0,正常
//其餘,錯誤代碼
uint8_t LIS_Write_Byte(uint8_t reg,uint8_t data)
{
  	IIC_Start(); 
	IIC_Send_Byte(LIS_ADDR|0x00);//發送器件地址+寫命令
	if(IIC_Wait_Ack())	//等待應答
	{
		IIC_Stop();		 
		return 1;		
	}
	IIC_Send_Byte(reg|0x00);		//寫寄存器地址  D7位爲低用於單字節傳輸
	IIC_Wait_Ack();					//等待應答
	IIC_Send_Byte(data);			//發送數據
	if(IIC_Wait_Ack())				//等待ACK
	{
		IIC_Stop();
		return 1;
	}
	IIC_Stop();	
	AP_interface->ol_Sleep(5000);
	return 0;
}

 

b、LIS3DH讀寄存器一個字節
流程:先寫1個字節的寫命令+IIC地址,再寫你要讀的寄存器。而後寫1個字節的讀命令+IIC地址,最後讀一個字節的數據
io

示例:class

//IIC讀一個字節
//reg:寄存器地址
//返回值:讀到的數據
uint8_t LIS_Read_Byte(uint8_t reg)
{
	uint8_t res=0x00;

  	IIC_Start();
	IIC_Send_Byte(LIS_ADDR|0x00);//發送器件地址+寫命令	
	if(IIC_Wait_Ack())		//等待ACK
	{
		IIC_Stop();	 
		return 1;		 
	}
	IIC_Send_Byte(reg);	//寫寄存器地址
	IIC_Wait_Ack();		//等待應答
	IIC_Start();
	IIC_Send_Byte(LIS_ADDR|0x01);	//發送器件地址+讀命令	
	IIC_Wait_Ack();					//等待應答 
	res = IIC_Read_Byte(0);			//讀取數據,發送nACK
	IIC_Stop();						//產生一箇中止條件 
	return res;
}

c、IIC連續寫寄存器:stream


示例:

//IIC連續寫
//addr:器件地址 
//reg:寄存器地址
//len:寫入長度
//buf:數據區
//返回值:0,正常
//	其餘,錯誤代碼
uint8_t LIS_Write_Len(uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf)
{
	uint8_t i; 
  IIC_Start();
	IIC_Send_Byte(LIS_ADDR|0x00);//發送器件地址+寫命令
	if(IIC_Wait_Ack())	//等待應答
	{
		IIC_Stop();		 
		return 1;		
	}
    IIC_Send_Byte(reg|0x80);	//寫寄存器地址  D7位爲高用於多字節傳輸
    IIC_Wait_Ack();		//等待應答
	for(i=0;i<len;i++)
	{
		IIC_Send_Byte(buf[i]);	//發送數據
		if(IIC_Wait_Ack())		//等待ACK
		{
			IIC_Stop();	 
			return 1;		 
		}		
	}    
    IIC_Stop();
	return 0;	
}

d、IIC方式連續讀寄存器。注意MAK和NMAK。

示例:

//IIC連續讀
//addr:器件地址
//reg:要讀取的寄存器地址
//len:要讀取的長度
//buf:讀取到的數據存儲區
//返回值:0,正常
//    其餘,錯誤代碼
uint8_t LIS_Read_Len(uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf)
{
 	IIC_Start();
	IIC_Send_Byte(LIS_ADDR|0x00);//發送器件地址+寫命令
	if(IIC_Wait_Ack())	//等待應答
	{
		IIC_Stop();		 
		return 1;		
	}
    IIC_Send_Byte(reg|0x80);	//寫寄存器地址  D7位爲高用於多字節傳輸
    IIC_Wait_Ack();		//等待應答
    IIC_Start();
	IIC_Send_Byte(LIS_ADDR|0x01);//發送器件地址+讀命令
    IIC_Wait_Ack();		//等待應答
	while(len)
	{
		if(len==1)*buf=IIC_Read_Byte(0);//讀數據,發送nACK 
		else *buf=IIC_Read_Byte(1);		//讀數據,發送ACK  
		len--;
		buf++; 
	}    
    IIC_Stop();	//產生一箇中止條件 
	return 0;	
}

2、設置閾值震動觸發中斷應用

 

首先,經過讀取一個叫WHO_AM_I的寄存器,能夠用來肯定芯片可用,由於這個寄存器讀取的值是恆定的0x33。

設置閾值觸發中斷示例:

該實例設置了中斷鎖存。即直到從新讀取INT1_SRC寄存器前,中斷都不會被清除,引腳會被一直強拉到從新讀取INT1_SRC爲止。

LIS_Write_Byte(CTRL_REG1,0x3F);			//設置低功耗模式 xyz軸使能 採樣頻率25HZ
	LIS_Write_Byte(CTRL_REG2,0x09);			//高通濾波正常模式,數據從內部濾波器到輸出寄存器 高通濾波器使能到中斷1
	LIS_Write_Byte(CTRL_REG3,0x40);			//使能AOI中斷1
	LIS_Write_Byte(CTRL_REG4,0x80);			//分辨率爲+-2g  則單位爲 4000/(2^8)=16mg       僅在LSB和MSB被讀時才更新數據
	LIS_Write_Byte(CTRL_REG5,0x08);			//寄存器鎖存中斷,只有讀INT1_SRC能夠恢復
	LIS_Write_Byte(INT1_THS,0x10);			//設置閾值 16*16=256 mg
	LIS_Write_Byte(INT1_DURATION,0x00);		//中斷持續時間設置,此處設爲0,由於不讀INT1_SRC中斷就一直鎖存
	LIS_Read_Byte(REFERENCE);				//讀虛寄存器,強制將高通濾波器值加載到當前加速度值,開始比較

	//INT1_CFG使能中斷  中斷模式爲 「OR」組合 只使能xyz軸高事件
	//LIS_Write_Byte(INT1_CFG,0x2A);
	//INT1_CFG使能中斷  中斷模式6-direction position  使能xyz軸高低事件
	LIS_Write_Byte(INT1_CFG,0xFF);
	LIS_Read_Byte(INT1_SRC);//清除中斷位

另外,還能夠設置中斷觸發指定時間,隨後引腳會還原。主要經過設置INT1_DURATION (33h)寄存器

這個ODR能夠經過GTRL_REG1設置。

最後中斷持續時間就是INT1_DURATION/ODR

 

3、FIFO模式讀取X、Y、Z軸方向加速度值

 

出於高速讀寫的需求,可能須要使用FIFO方式來進行加速度的讀取

LIS3DH的FIFO模式有4種:

一、Bypass mode

中間模式,只有切換模式的時候用獲得

二、FIFO mode

數據填充滿緩衝區後,中止繼續填充

三、Stream mode

數據持續輸出,填充滿緩衝區後會覆蓋舊的數據,數據依次向前推一字節

四、Stream-to-FIFO mode

FIFObuffer開始處於stream模式,等到中斷腳選擇觸發時,切換到FIFO模式。FIFO_CTRL_REG (2Eh)的TR位能夠決定是INT1腳仍是INT2腳來進行控制

 

示例:讀取XYZ軸方向的加速度,用Stream mode。

watermark是指配置FSS [4:0]來檢查讀取的時候數據總量是否超出指定的範圍。由於FIFO的緩衝區最多爲32級,好比能夠設置爲20,則讀取的時候,若是當時數據超出20個,則FIFO_SRC_REG (2Fh) (WTM)位會被置1,不然爲0。

同時FIFO_SRC_REG (2Fh) 的 OVRN_FIFO會被置1,若是32級緩衝區所有滿了。

//測試FIFO
  IIC_WriteByte(LIS3DH_CTRL_REG1,0x80|0x0F);   //0010 0111	低功耗模式
	IIC_WriteByte(LIS3DH_CTRL_REG2,0x00);				//高通濾波關閉

	IIC_WriteByte(LIS3DH_CTRL_REG3,0x06);				//使能FIFO中斷    0000 0110
	IIC_WriteByte(LIS3DH_CTRL_REG4,0x00);				//分辨率+-16g 		0011 0000

	IIC_WriteByte(LIS3DH_CTRL_REG5,0x48);					//FIFO使能	0100 1000
	IIC_WriteByte(LIS3DH_FIFO_CTRL,0x80|0x1D);		//0100 1111	配置FIFO模式和水印
	
	IIC_ReadByte(LIS3DH_INT1_SRC);	//清除中斷位
	
	collect_LIS_Data();



void collect_LIS_Data(void)
{
		uint16_t  LIS_temp_data[3] = {0,0,0};
		uint8_t data_len,i;

		FIFO_data_len = IIC_ReadByte(LIS3DH_FIFO_SRC);

		FIFO_data_len &= 0x1F;
		for(i=0;i<FIFO_data_len;i++)
		{
			LIS3DH_ReadData(LIS_temp_data);    //讀取3個方向的數據
		}
}

數據會不斷刷新,因此要定時讀取,讀取間隔能夠經過ODR來控制調整。

相關文章
相關標籤/搜索