精华内容
下载资源
问答
  • 项目上使用了一款Lis2dh12三轴加速度传感器。 要引用官方提供SDK中的lis2dh12_reg.h文件、lis2dh12_reg.c文件,才行。 我使用的主控芯片是STM32L051C8T6,硬件IIC与lis2dh12通讯。 原理图: 1、创建lis2dh...

    目录

    概述

    项目上使用了一款Lis2dh12三轴加速度传感器。开发前要准备的工作。

    1、原理图:

    1.1、创建lis2dh12.c文件

    1.2、在此重点说明,如果想调传感器的中断灵敏度,注意:关注1、INT1_THS(32h),2、INT1_DURATION(33h)这两个寄存器即可。

    1.3、计算阀值:主要是看配置中断的量程是哪个。

    1.4、创建lis2dh12.h文件

    1.5、main.c文件

    1.6、demo运行结果如下: 


    概述

          项目上使用了一款Lis2dh12三轴加速度传感器。开发前要准备的工作。

          1)要引用官方提供SDK中的lis2dh12_reg.h文件、lis2dh12_reg.c文件,才行。

          2)我使用的主控芯片是STM32L051C8T6,硬件IIC与lis2dh12通讯。

          3)本次写的是Demo项目,使用工具STM32Cube IDE开发

    1、原理图:

                            

    .ioc文件创建

     

    1.1、创建lis2dh12.c文件

    #include "lis2dh12.h"
    #include "lis2dh12_reg.h"
    #include "i2c.h"
    #include "stdlib.h"
    #include "stdio.h"
    #include <string.h>
    #include <math.h>
    
    
    #define LIS2DH12_FROM_FS_2g_HR_TO_mg(lsb)  (float)((int16_t)lsb>>4) * 1.0f
    #define LIS2DH12_FROM_FS_4g_HR_TO_mg(lsb)  (float)((int16_t)lsb>>4) * 2.0f
    #define LIS2DH12_FROM_FS_8g_HR_TO_mg(lsb)  (float)((int16_t)lsb>>4) * 4.0f
    #define LIS2DH12_FROM_FS_16g_HR_TO_mg(lsb) (float)((int16_t)lsb>>4) * 12.0f 
    #define LIS2DH12_FROM_LSB_TO_degC_HR(lsb)  (float)((int16_t)lsb>>6) / 4.0f+25.0f
    
     
    axis_info_t acc_sample;
    filter_avg_t acc_data;
    
    
    /* ============================================================
    func name   :  lis2_Delay_us
    discription :  lis2 微妙延时
    param       :  us
    return      :  
    Revision    : 
    =============================================================== */
    void lis2_Delay_us(uint32_t us)
    {
    	int n = 11;
    	while(--us)
    	{
    	    while(--n);
    	    n = 11;
    	}
    }
    
    /* ============================================================
    func name   :  lis2_Delay_ms
    discription :  lis2 毫秒延时
    param       :  ms
    return      :  
    Revision    : 
    =============================================================== */
    void lis2_Delay_ms(uint32_t ms)
    {
    	int i = 0;
    	for(;i<ms;i++)
    	{
    	    lis2_Delay_us(1000);
    	}
    }
    
    
    /* ============================================================
    func name   :  lis2dh12_iic_read_byte
    discription :  写一个字节
    param       :  reg:寄存器地址,data:寄存器对应的值
    return      :  
    Revision    : 
    =============================================================== */
    int32_t lis2dh12_iic_write_byte(uint8_t reg, uint8_t data)
    {
    	 #ifdef HARDWARE_IIC
    			HAL_I2C_Mem_Write(&hi2c1, LIS2DH12_I2C_ADD_H, reg,I2C_MEMADD_SIZE_8BIT, &data, 1, 1000);
    	 #endif
    	
    	 #ifdef SIMULATED_IIC
    			Lis2DH12_IIC_Write_Byte(LIS2DH12_I2C_ADD_H, reg, data); 
    	 #endif
    	 return 1;
    }
    
    /* ============================================================
    func name   :  lis2dh12_iic_read_byte
    discription :  读一个字节
    param       :  reg:寄存器地址,data:寄存器对应的值
    return      :  
    Revision    : 
    =============================================================== */
    int32_t lis2dh12_iic_read_byte(uint8_t reg, uint8_t* data)
    {
    	 #ifdef HARDWARE_IIC
    			HAL_I2C_Mem_Read(&hi2c1, LIS2DH12_I2C_ADD_H, reg,I2C_MEMADD_SIZE_8BIT, data, 1, 1000);
    	 #endif
    	
    	 #ifdef SIMULATED_IIC
    			Lis2DH12_IIC_Read_Byte(LIS2DH12_I2C_ADD_H, reg, data); 
    			
    	 #endif
    	 return 1;
    }
    
    
    /* ============================================================
    func name   :  Lis2dh12_Init
    discription :  配置检测阈值与中断
    param       :  void
    return      :  
    Revision    : 
    =============================================================== */
    int32_t Lis2dh12_Init(void)
    {	
    	/* Initialization of sensor */
    	lis2dh12_iic_write_byte(0x20, 0x37);	/* CTRL_REG1(20h): 关闭sensor,设置进入掉电模式 ODR 25HZ */
    //	lis2dh12_iic_write_byte(0x20, 0x57);	/* CTRL_REG1(20h): 关闭sensor,设置进入低功耗模式 ODR 100HZ */
    	lis2dh12_iic_write_byte(0x21, 0x03);	/* CTRL_REG2(21h): IA1、IA2 开启高通滤波 bc */
    	lis2dh12_iic_write_byte(0x22, 0xc0);	/* CTRL_REG3(22h): 0x80 使能单击中断到INT_1 INT_2 */
    	lis2dh12_iic_write_byte(0x23, 0x88);  /* CTRL_REG4(23h): 使能快,数据更新,全量程+/-2G,非常精度模式 */
    //	lis2dh12_iic_write_byte(0x25, 0x00);  /* CTRL_REG6(25h): 高电平(上升沿)触发中断 */
    	
    	/* INT1 翻转检测,中断*/							//0x6a
    	lis2dh12_iic_write_byte(0x30, 0x7f);  /* INT1_CFG(30h): 使能,6D X/Y/Z任一超过阈值中断 */
    //	lis2dh12_iic_write_byte(0x30, 0x4f);  /* INT1_CFG(30h): 使能,6D X/Y任一超过阈值中断 */
    //  lis2dh12_iic_write_byte(0x31, 0x20);  /* INT1_SRC(31h): 设置中断源 */
    
    	lis2dh12_iic_write_byte(0x32, 0x02);  	/* INT1_THS(32h): 设置中断阀值 0x10: 16*2(FS)  0x20: 32*16(FS) */
    
    //	lis2dh12_iic_write_byte(0x33, 0x02);  	/* INT1_DURATION(33h): 1LSB=1/ODR  如果ODR=25HZ  那么1LSB=40ms 设置延时 1s,对应25->0x19 */
    //	lis2dh12_iic_write_byte(0x33, 0x03);  /* INT1_DURATION(33h): 1LSB=1/ODR  如果ODR=50HZ   那么1LSB=20ms 设置延时 1s,对应50->0x32 */
      lis2dh12_iic_write_byte(0x33, 0x03);  	/* INT1_DURATION(33h): 1LSB=1/ODR  如果ODR=100HZ  那么1LSB=10ms 设置延时 1s,对应100->0x64 */
    
    	
    //	/* INT2 单击中断 */
    	lis2dh12_iic_write_byte(0x24, 0x01);	/* CTRL_REG5(24h):  */
    //	lis2dh12_iic_write_byte(0x25, 0xa0);  /* CTRL_REG6(25h): Click interrupt on INT2 pin */
    //
    //	lis2dh12_iic_write_byte(0x38, 0x15);	/* CLICK_CFG (38h): 单击识别中断使能 */
    	lis2dh12_iic_write_byte(0x39, 0x10);
    //	lis2dh12_iic_write_byte(0x3a, 0x7f);  /* CLICK_THS (3Ah): 单击阀值 */
    //	lis2dh12_iic_write_byte(0x3b, 0xff);  /* TIME_LIMIT (3Bh): 时间限制窗口6 ODR 1LSB=1/ODR 1LSB=1/100HZ,10ms,设置延时1s,对应100—>0x64*/
    //	lis2dh12_iic_write_byte(0x3c, 0xff);  /* TIME_LATENCY (3Ch): 中断电平持续时间1 ODR=10ms */
    //	lis2dh12_iic_write_byte(0x3d, 0x01);  /* TIME_WINDOW (3Dh):  单击时间窗口 */
    	
    	/* Start sensor */
    //	lis2dh12_iic_write_byte(0x20, 0x37);
    	lis2dh12_iic_write_byte(0x20, 0x5f);  /* CTRL_REG1(20h): Start sensor at ODR 100Hz Low-power mode */
    	
    	return 0;
    }
    
    
    /* ============================================================
    func name   :  get_acc_value
    discription :  获取加速度值
    param       :  axis_info_t *sample
    return      :  void
    Revision    : 
    =============================================================== */
    void get_acc_value(axis_info_t *sample)
    {
    	uint8_t i = 0;
    	uint8_t data[6];
    	for (i=0; i<6; i++){
    		lis2dh12_iic_read_byte(0x28+i, data+i);		//获取X、y、z轴的数据
    		//printf("data[i] %d, \r\n", data[i]);
    	}
    //  sample->x = abs((int)(LIS2DH12_FROM_FS_2g_HR_TO_mg(*(int16_t*)data))); 
    //	sample->y = abs((int)(LIS2DH12_FROM_FS_2g_HR_TO_mg(*(int16_t*)(data+2))));
    //	sample->z = abs((int)(LIS2DH12_FROM_FS_2g_HR_TO_mg(*(int16_t*)(data+4))));
    	sample->x = LIS2DH12_FROM_FS_2g_HR_TO_mg(*(int16_t*)data); 
    	sample->y = LIS2DH12_FROM_FS_2g_HR_TO_mg(*(int16_t*)(data+2));
    	sample->z = LIS2DH12_FROM_FS_2g_HR_TO_mg(*(int16_t*)(data+4));
    }
    
    /* ============================================================
    func name   :  filter_calculate
    discription :  均值滤波器---滤波
    			   读取xyz数据存入均值滤波器,存满进行计算,滤波后样本存入sample
    param       :  filter_avg_t *filter, axis_info_t *sample
    return      :  void
    Revision    : 
    =============================================================== */
    void filter_calculate(filter_avg_t *filter, axis_info_t *sample)
    {
    	uint8_t i = 0;
    	short x_sum = 0, y_sum = 0, z_sum = 0;	
    	
    	for (i=0; i<FILTER_CNT; i++) 
    	{
    		get_acc_value(sample);
    
    		filter->info[i].x = sample->x;
    		filter->info[i].y = sample->y;
    		filter->info[i].z = sample->z;
    		
    		x_sum += filter->info[i].x;
    		y_sum += filter->info[i].y;
    		z_sum += filter->info[i].z;
    		
    		printf("acc_x:%d,  acc_y:%d,  acc_z:%d \n",filter->info[i].x,filter->info[i].y,filter->info[i].z);
    	}
    	sample->x = x_sum / FILTER_CNT;
    	sample->y = y_sum / FILTER_CNT;
    	sample->z = z_sum / FILTER_CNT;	
    	printf("\r\n acc_info.acc_x:%d, acc_info.acc_y:%d, acc_info.acc_z:%d \r\n",sample->x, sample->y, sample->z);
    }
     
     
    /* ============================================================
    func name   :  new_angle_calculate
    discription :  计算新角度
    param       :  axis_info_t *sample
    return      :  void
    Revision    : 
    =============================================================== */
    void new_angle_calculate(axis_info_t *sample)
    {
    	sample->new_angle_x = atan((short)sample->x/(short)sqrt(pow(sample->y, 2)+pow(sample->z, 2))) * DEGREE_CAL;
    	sample->new_angle_y = atan((short)sample->y/(short)sqrt(pow(sample->x, 2)+pow(sample->z, 2))) * DEGREE_CAL;
    	sample->new_angle_z = atan((short)sample->z/(short)sqrt(pow(sample->x, 2)+pow(sample->y, 2))) * DEGREE_CAL;
    	if (sample->new_angle_z < 0)
    	{
    		sample->new_angle_x = 180-sample->new_angle_x;
    		sample->new_angle_y = 180-sample->new_angle_y;
    	}
    	printf("sample->new_angle_x:%d, sample->new_angle_y:%d, sample->new_angle_z:%d \r\n",sample->new_angle_x, sample->new_angle_y, sample->new_angle_z);
    }
    
    /* ============================================================
    func name   :  old_angle_calculate
    discription :  计算旧角度
    param       :  axis_info_t *sample
    return      :  void
    Revision    : 
    =============================================================== */
    void old_angle_calculate(axis_info_t *sample)
    {
    	sample->old_angle_x = atan((short)sample->x/(short)sqrt(pow(sample->y, 2)+pow(sample->z, 2))) * DEGREE_CAL;
    	sample->old_angle_y = atan((short)sample->y/(short)sqrt(pow(sample->x, 2)+pow(sample->z, 2))) * DEGREE_CAL;
    	sample->old_angle_z = atan((short)sample->z/(short)sqrt(pow(sample->x, 2)+pow(sample->y, 2))) * DEGREE_CAL;
    	if (sample->old_angle_z < 0)
    	{
    		sample->old_angle_x = 180-sample->old_angle_x;
    		sample->old_angle_y = 180-sample->old_angle_y;
    	}
    	printf("sample->old_angle_x:%d, sample->old_angle_y:%d, sample->old_angle_z:%d \r\n",sample->old_angle_x, sample->old_angle_y, sample->old_angle_z);
    }
    

    1.2、在此重点说明,如果想调传感器的中断灵敏度,注意:关注1、INT1_THS(32h),2、INT1_DURATION(33h)这两个寄存器即可。

    INT1_THS(32h)

    1.3、计算阀值:主要是看配置中断的量程是哪个。

    (1)如果量程 FS=2g 每1LSB=16mg  
    那么寄存器配置INT1_THS=2 那么阈值=2*16mg
    如果INT1_THS=5 那么阈值=5*16mg
     
    (2)如果量程FS=4g,那么每1LSB=32mg 
    INT1_THS =5 阈值就是5*32mg=160mg

    看配置的ODR是哪个,来计算延时的时间。

    1LSB=1/ODR  如果ODR=50HZ  那么1LSB=20ms

    /*
    500mg = 30°
    250mg = 15°
    160mg = 10°
    我现在对应的量程是FS=2g,INT1_THS=10,那么阀值=10*16mg
     
    1LSB=1/ODR  如果ODR=50HZ  那么1LSB=20ms
    50LSB   = 1s
    100LSB = 2s 
    */

    1.4、创建lis2dh12.h文件

    #ifndef __LIS2DH12_H
    #define __LIS2DH12_H
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
    #include "stdint.h"
    
    #define DEGREE_CAL 180.0/3.1416
    #define FILTER_CNT 4
    
    
    typedef struct {
      short x;
      short y;
      short z;
      short new_angle_x;
      short new_angle_y;
      short new_angle_z;
      short old_angle_x;
      short old_angle_y;
      short old_angle_z;
    }axis_info_t;
    
    
    typedef struct filter_avg{
      axis_info_t info[FILTER_CNT];
      unsigned char count;
    }filter_avg_t;
    
    extern axis_info_t acc_sample;
    extern filter_avg_t acc_data;
    
    int32_t Lis2dh12_Init(void);
    void filter_calculate(filter_avg_t *filter, axis_info_t *sample);
    void old_angle_calculate(axis_info_t *sample);
    void new_angle_calculate(axis_info_t *sample);
    
    
    
    #endif
    

    1.5、main.c文件

    /* USER CODE END Header */
    
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    #include "i2c.h"
    #include "usart.h"
    #include "gpio.h"
    
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    #include "stdio.h"
    
    #include "lis2dh12.h"
    /* USER CODE END Includes */
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    
    /* USER CODE END PTD */
    
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
    /* USER CODE END PD */
    
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
    
    /* USER CODE END PM */
    
    /* Private variables ---------------------------------------------------------*/
    
    /* USER CODE BEGIN PV */
    
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    /* USER CODE BEGIN PFP */
    
    /* USER CODE END PFP */
    
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
    
    /* USER CODE END 0 */
    
    /**
      * @brief  The application entry point.
      * @retval int
      */
    int main(void)
    {
      /* USER CODE BEGIN 1 */
    
      /* USER CODE END 1 */
    
      /* MCU Configuration--------------------------------------------------------*/
    
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();
    
      /* USER CODE BEGIN Init */
    
      /* USER CODE END Init */
    
      /* Configure the system clock */
      SystemClock_Config();
    
      /* USER CODE BEGIN SysInit */
    
      /* USER CODE END SysInit */
    
      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_I2C1_Init();
      MX_USART1_UART_Init();
      /* USER CODE BEGIN 2 */
      Lis2dh12_Init();
      filter_calculate(&acc_data, &acc_sample);
      old_angle_calculate(&acc_sample);
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
    	 HAL_Delay(1000);
    	 filter_calculate(&acc_data, &acc_sample);
    	 new_angle_calculate(&acc_sample);
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
      }
      /* USER CODE END 3 */
    }

    1.6、demo运行结果如下: 

    代码:Git

    展开全文
  • <div><p>The lis2dh12 has a size 32 FIFO, but lis2dh12_get_fifo_sample_number returns 31 when the FIFO is full. Perhaps the value returned from LIS2DH12_FIFO_SRC_REG refers to the last <em>index</em> ...
  • lis2dh12_STdC.zip

    2021-02-04 14:32:40
    lis2dh12
  • ST的三轴传感器 LIS2DH12和LIS2DW12的单双击 配置代码,寄存器配置,以及ODR的设置,还有阈值配置的算法,双击的中间间隔的算法
  • lis2dh12.rar

    2019-07-03 14:25:40
    iic通讯代码 lis2dh12底层驱动代码 读取加速度值 分层清晰
  • lis2dh12驱动

    2020-12-18 10:25:42
    void lis2dh12_self_test(void) { stmdev_ctx_t dev_ctx; lis2dh12_reg_t reg; uint8_t i, j; /* Initialize mems driver interface / dev_ctx.write_reg = platform_write; dev_ctx.read_reg = platform_read;

    https://blog.csdn.net/fengweibo112/article/details/87868052

    void lis2dh12_self_test(void)
    {
    stmdev_ctx_t dev_ctx;
    lis2dh12_reg_t reg;
    uint8_t i, j;
    /* Initialize mems driver interface /
    dev_ctx.write_reg = platform_write;
    dev_ctx.read_reg = platform_read;
    // dev_ctx.handle = &SENSOR_BUS;
    /
    Wait boot time and initialize platform specific hardware /
    platform_init();
    /
    Wait sensor boot time /
    platform_delay(BOOT_TIME);
    /
    Check device ID */
    // uint8_t value=0;
    // for(uint8_t i=0;i<255;i++)
    // {
    // I2C_dma_BlockRead_Sleep(i,LIS2DH12_WHO_AM_I,&value,1);
    // platform_delay(1);
    // if(valueLIS2DH12_ID)
    // {
    // value=0;
    // }
    // value=0;
    // }
    //验证传感器读写是否OK
    uint8_t value=0xaa;
    // I2C_dma_BlockWrite_Sleep(LIS2DH_I2C_ADDR2,LIS2DH12_INT1_THS,&value,1);
    // platform_delay(1);
    // value=0;
    // I2C_dma_BlockRead_Sleep(LIS2DH_I2C_ADDR2,LIS2DH12_INT1_THS,&value,1);
    // platform_delay(1);
    // if(0xaa
    value)
    // {
    // value=0;//验证传感器读写是否OK
    // }
    value=0xFF;
    // I2C_dma_BlockWrite_Sleep(LIS2DH_I2C_ADDR2,LIS2DH12_CTRL_REG3,&value,1);
    platform_delay(1);
    value=0;
    I2C_dma_BlockRead_Sleep(LIS2DH_I2C_ADDR2,LIS2DH12_CTRL_REG3,&value,1);
    platform_delay(1);
    if(0xFF==value)
    {
    value=0;//验证传感器读写是否OK
    }
    lis2dh12_device_id_get(&dev_ctx, &reg.byte);

    if (reg.byte != LIS2DH12_ID) {
    while (1) {
    /* manage here device not found */
    }
    }

    /* Initialization of sensor */
    lis2dh12_iic_write_byte(0x20, 0x37);	/* CTRL_REG1(20h): 关闭sensor,设置进入掉电模式 ODR 25HZ */
    

    // lis2dh12_iic_write_byte(0x20, 0x57); /* CTRL_REG1(20h): 关闭sensor,设置进入低功耗模式 ODR 100HZ /
    lis2dh12_iic_write_byte(0x21, 0x03); /
    CTRL_REG2(21h): IA1、IA2 开启高通滤波 bc */

    lis2dh12_iic_write_byte(0x22, 0xc0);	/* CTRL_REG3(22h): 0x80 使能单击中断到INT_1 INT_2 */
    

    // lis2dh12_iic_write_byte(0x22, 0xD0); /* CTRL_REG3(22h): 0x80 使能单击中断到INT_1 INT_2 /
    lis2dh12_iic_write_byte(0x23, 0x88); /
    CTRL_REG4(23h): 使能快,数据更新,全量程+/-2G,非常精度模式 /
    // lis2dh12_iic_write_byte(0x25, 0x00); /
    CTRL_REG6(25h): 高电平(上升沿)触发中断 */

    /* INT1 翻转检测,中断*/							//0x6a
    lis2dh12_iic_write_byte(0x30, 0x7f);  /* INT1_CFG(30h): 使能,6D X/Y/Z任一超过阈值中断 */
    

    // lis2dh12_iic_write_byte(0x30, 0x4f); /* INT1_CFG(30h): 使能,6D X/Y任一超过阈值中断 /
    // lis2dh12_iic_write_byte(0x31, 0x20); /
    INT1_SRC(31h): 设置中断源 */

    lis2dh12_iic_write_byte(0x32, 0x03);  	/* INT1_THS(32h): 设置中断阀值 0x10: 16*2(FS)  0x20: 32*16(FS) */
    

    // lis2dh12_iic_write_byte(0x33, 0x02); /* INT1_DURATION(33h): 1LSB=1/ODR 如果ODR=25HZ 那么1LSB=40ms 设置延时 1s,对应25->0x19 /
    // lis2dh12_iic_write_byte(0x33, 0x03); /
    INT1_DURATION(33h): 1LSB=1/ODR 如果ODR=50HZ 那么1LSB=20ms 设置延时 1s,对应50->0x32 /
    lis2dh12_iic_write_byte(0x33, 0x00); /
    INT1_DURATION(33h): 1LSB=1/ODR 如果ODR=100HZ 那么1LSB=10ms 设置延时 1s,对应100->0x64 */

    // /* INT2 单击中断 /
    lis2dh12_iic_write_byte(0x24, 0x01); /
    CTRL_REG5(24h): /
    // lis2dh12_iic_write_byte(0x25, 0xa0); /
    CTRL_REG6(25h): Click interrupt on INT2 pin /
    //
    // lis2dh12_iic_write_byte(0x38, 0x15); /
    CLICK_CFG (38h): 单击识别中断使能 /
    lis2dh12_iic_write_byte(0x39, 0x10);
    // lis2dh12_iic_write_byte(0x3a, 0x7f); /
    CLICK_THS (3Ah): 单击阀值 /
    // lis2dh12_iic_write_byte(0x3b, 0xff); /
    TIME_LIMIT (3Bh): 时间限制窗口6 ODR 1LSB=1/ODR 1LSB=1/100HZ,10ms,设置延时1s,对应100—>0x64*/
    // lis2dh12_iic_write_byte(0x3c, 0xff); /* TIME_LATENCY (3Ch): 中断电平持续时间1 ODR=10ms /
    // lis2dh12_iic_write_byte(0x3d, 0x01); /
    TIME_WINDOW (3Dh): 单击时间窗口 */

    /* Start sensor */
    

    // lis2dh12_iic_write_byte(0x20, 0x37);
    lis2dh12_iic_write_byte(0x20, 0x5f); /* CTRL_REG1(20h): Start sensor at ODR 100Hz Low-power mode */

    }

    展开全文
  • 本driver为ST的三轴芯片lis2dh12驱动代码,已经调试OK,清有需要的人下载。
  • LIS2DH12三轴加速传感器中文寄存器详细描述,已整理成EXCEL格式,方便配置
  • gsensor LIS2DH12 datasheet

    2018-06-07 09:38:45
    本篇文档主要说三轴加速度传感器gsensor 型号为LIS2DH12芯片的datasheet,通过本篇datasheet可以了解该芯片的使用方法。
  • 加速传感器LIS2DH12的STM32驱动程序,使用IIC通信。内有跌落检测、6D运动检测、惯性检测等例程,还有LIS2DH12输出数据转换程序
  • 加速传感器LIS2DH12的STM32驱动程序,使用SPI通信。内有跌落检测、6D运动检测、惯性检测等例程,还有LIS2DH12输出数据转换程序。内有详细的代码注释,如有不明之处可给我发私信
  • LIS2DH12应用总结

    万次阅读 2019-02-21 20:38:16
    LIS2DH12的功能和特色如下: • I2C/SPI两种通信接口 • 1Hz~5.3kHz的ODR可配置 • high-resolution/normal/low-power三种运行模式 high-resolution模式时输出为12bits normal模式时输出为10bits low-power...

    LIS2DH12的功能和特色如下:

    • I2C/SPI两种通信接口
    • 1Hz~5.3kHz的ODR可配置
    • high-resolution/normal/low-power三种运行模式
    high-resolution模式时输出为12bits
    normal模式时输出为10bits
    low-power模式时输出为8bits;
    • 测量范围 ±2g/±4g/±8g/±16g可选
    • 两个可配置的中断资源INT1和INT2
    • 内置温度传感器
    • 内置FIFO
    • 两个中断输出引脚
    • 6D/4D方向检测 6D/4D orientation detection
    • 自由落体检测 Free-fall detection
    • 动作检测 Motion detection
    • 单击/双击识别 Click/double-click recognition
    • 自动休眠/唤醒 Sleep-to-wake and return-to-sleep
    其中6D/4D方向检测、自由落体检测和动作检测并不是由独立的单元实现的,这三种功能的实现都是通过对可配置中断资源INT1和INT2进行设置后实现的。
    单击/双击识别和自动休眠/唤醒都是由独立的单元实现的,其中单击/双击识别有相应的中断标志位,自动休眠/唤醒没有标志位。

    加速度原始数据读取计算

    rang范围可设定为±2g、±4g、±8g、±16g (1g=9.8N/kg,正常不动,三轴的向量和为1g)
    ADC可设置成8bit、10bit、12bit。
    数据读取
    sensor用了16bit来表示一个轴的值。即读取出来的原始寄存器数据为一个int16_t格式的数值。
    lis2dhReadReg(LIS2DH_OUT_Y_L, buf, 4);
    tempAccY=(int16_t)((buf[1]<<8)+buf[0])>>6;
    tempAccZ=(int16_t)((buf[3]<<8)+buf[2])>>6;
    temp_f_y=(int32_t)(tempAccYx38.28);
    temp_f_z=(int32_t)(tempAccZx38.28); //±2G,256LBS/g 放大1000倍 9800/256 = 38.28 mg

    举例以配置为±8g,10bit为例:
    10bit的数值范围为-512到+512,不管rang设置多大,输出的范围是固定的。
    range设置成±8g是,测量范围为-8g ~ +8g,数字化后,即为64LSB/g,即1g的加速度对应的输出是64。同理:1个数字代表的加速度为8/512=15.6mg

    数据连续读取

    连续读取多个数据,和普通的I2C读取有一定区别,需要地址最高位置1,注意Datasheet有如下一句话:
    “In order to read multiple bytes, it is necessary to assert the most significant bit of the subaddress field. In other words, SUB(7) must be equal to 1 while SUB(6-0) represents the
    Address of the first register to be read.”
    在这里插入图片描述

    运动中断唤醒设置

    在这里插入图片描述
    CTRL_REG1 = 0x1F;//1MHz,低功耗模式,X/Y/Z都使能
    CTRL_REG2 = 0x01;//INT1上使用High-pass
    CTRL_REG3 = 0x40;//INT1上产生中断。
    INT1_CFG = 0x2A;//使能,X/Y/Z任一超过阈值中断。
    INT1_THS = 0x10;//中断阈值 16*FS
    INT1_DURATION = 0x00;//超过时立刻产生中断。
    在这里插入图片描述

    展开全文
  • LIS2DH12 官方驱动

    2018-10-24 14:26:47
    LIS2DH官方寄存器驱动,包含对寄存器操作的.C文件。配合.H文件,可直接使用
  • 三轴加速传感器LIS2DH12中文数据手册+开发手册+数据转换方法。含前辈备注使用心得
  • nrf52驱动lis2dh12问题

    2020-09-07 09:58:25
    以前用的也是nrf52调试的lis2dh12的驱动,不过是nrf SDK9.0,现在用SDK15.2重新再调试,发现不行了,又得重新调过。 问题一:SPI驱动问题 问题二:定时中断问题 问题一:SPI驱动问题,以前的驱动驱动不了了。 ...

    以前用的也是nrf52调试的lis2dh12的驱动,不过是nrf SDK9.0,现在用SDK15.2重新再调试,发现不行了,又得重新调过。

    问题一:SPI驱动问题

    问题二:定时中断问题

    问题一:SPI驱动问题,以前的驱动驱动不了了。

    void gspi_event_handler(nrf_drv_spi_evt_t const * p_event,void *p_context)
    {
        spi_lis_done = true;
    //    NRF_LOG_INFO("gspi event done!");
    }


    void SPI1_Init(void)
    {
        uint32_t err_code;
        nrf_drv_spi_config_t spiconfig = NRF_DRV_SPI_DEFAULT_CONFIG;
        spiconfig.sck_pin = SPIM1_SCK_PIN;
        spiconfig.mosi_pin = SPIM1_MOSI_PIN;
        spiconfig.miso_pin = SPIM1_MISO_PIN;
        spiconfig.ss_pin = SPIM1_CS_PIN;
        spiconfig.frequency = NRF_DRV_SPI_FREQ_8M;
    //    spiconfig.mode      = NRF_DRV_SPI_MODE_0;
        spiconfig.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;

        err_code = nrf_drv_spi_init(&gSpi, &spiconfig,gspi_event_handler, NULL);
        APP_ERROR_CHECK(err_code);
        NRF_LOG_INFO("nrf_drv_spi_init:%d\r\n",    err_code);
        nrf_gpio_cfg_output(SPIM1_CS_PIN);
        gSPI_CS_HIGH;
    }

    以前LIS2DH12_ReadReg读寄存器是分开两个nrf_drv_spi_transfer()发送来执行的,现在只能合并成一个发送来完成。而且读数据的buf以前是一个字节,现在要用两个字节,不然读取一个字节nrf_drv_spi_transfer(&gSpi, data, 1, p_data,1);总是得不到正确的数值,看程序你就会明白,你正在想读取的字节已经跑到rx_data[1]位置了,这是因为在发送data的时候,同时也返回了一个字节 rx_data[0],坑啊!

    u8_t LIS2DH12_ReadReg(u8_t Reg, u8_t* p_data) {
      
      //To be completed with either I2c or SPI reading function
    //    uint32_t err_code = NRF_SUCCESS;
        uint8_t    data[2];
        uint8_t rx_data[2];
        
        data[0]    = Reg | LIS2DH12_READBIT;

        gSPI_CS_LOW;
        spi_lis_done = false;
        nrf_drv_spi_transfer(&gSpi, data, 1, rx_data,2);
    //    APP_ERROR_CHECK(err_code);
    //    NRF_LOG_INFO("LIS2DH12_ReadReg:%x,%x\r\n",    rx_data[0],rx_data[1]);
        while(!spi_lis_done);
        p_data[0] = rx_data[1];

        gSPI_CS_HIGH;
      return 1;
    }

    /*******************************************************************************
    * Function Name        : LIS2DH12_WriteReg
    * Description        : Generic Writing function. It must be fullfilled with either
    *            : I2C or SPI writing function
    * Input            : Register Address, Data to be written
    * Output        : None
    * Return        : None
    *******************************************************************************/
    u8_t LIS2DH12_WriteReg(u8_t WriteAddr, u8_t Data) {
      
      //To be completed with either I2c or SPI writing function
    //    uint32_t err_code = NRF_SUCCESS;
    //    uint8_t    send_size = 2;
        uint8_t    data[2];
        
        data[0] = WriteAddr&0x7F;
        data[1] = Data;
        gSPI_CS_LOW;
        spi_lis_done = false;
        nrf_drv_spi_transfer(&gSpi, data,2, NULL, 0);
    //    APP_ERROR_CHECK(err_code);
        while(!spi_lis_done);
        gSPI_CS_HIGH;
      return 1;
    }
    发送端没啥好说的,但是如果要发送的是寄存器或地址+data的话,一定要写在一个buf里去,不然会有问题,原因这就得看SPI的协议了,一般芯片datasheet都带SPI 协议说明的 。如果你分两次发送,发送一次寄存器或地址,数据部分另外再同一函数发送,就会有问题,数据发送出去了,得不到回应或写入不成功。SPI驱动外部flash芯片就明白。

    问题二:定时中断问题

          我没采用芯片的INT脚产生中断,而是采用定时中断去读取数据,这里要说明一点的是,不要在中断里面加死循环,不然会出错,即使加了,循环的次数也不能太多,不然也会卡死的,因为驱动里有while(!spi_lis_done);所以就不能放中断里去读取发送了,但是不要while(!spi_lis_done);很多时候,它又会提示busy;所以最好把读数据都放在main的while循环里,中断只给出一个中断标记就可以了。

    以上是再次调试lis2dh12的一点经验,分享给大家,希望对大家有帮助。

     

    展开全文
  • 项目上用到LIS2DH12检测震动告警,设备倾斜状态,原理图如下 要检测震动跟倾斜角度,配置LIS2DH12的相关寄存器即可,寄存器很多,这里只说明程序中使用到的 #define LIS2DH12_FROM_FS_2g_HR_TO_mg(lsb) (float)(...
  • LIS2DH12TR读取 hal库

    2020-09-27 20:41:00
    LIS2DH12TR读取 hal库 硬件焊接和验证,读取who_am_I 手焊这么小的芯片,真的是手抖。靠感觉吧,如果感觉这样焊接更好,那就拆了按感觉来焊,不要等测了好多次没数据,然后想,到底是焊接问题还是程序问题。怀疑...
  • <div><p>This PR has two commits, the first one is a straightforward spelling fix and the second a fix to the acceleration conversion table from mg units to LIS2DH12 register values. <p>The previous ...
  • LIS2DH12TR驱动

    2020-09-27 20:52:19
    听说是st的官方驱动,看了一下函数,应该可以的。然后为什么要写那么多简介啊。语文不好啊,啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
  • 在上篇介绍了OLED的II以写操作为主,没有进行读取操作。...lis2dh_read_registers(LIS2DH_WHO_AM_I,&temp,1); 我们现在操作的寄存器为who_am_i时序如下 好了现在贴上主要代码 #define ME...
  • 也可以安装加速度计LIS2DW12,LIS2DH12。 由CR2032电池供电。 不要捐赠给我,它在这个世界上行不通: : ,只需购买: 组装好的传感器-15美元 带盒子-+ $ 5 联络人: 视频: : 有关更多信息,请访问 (仍然...
  • 状态:发布 描述:disable REG_INT1_CFG、REG_INT2_CFG z-axis,并未起作用 解决: 转载于:https://www.cnblogs.com/HongZheng/p/5833077.html
  • LIS2DH SPI Support

    2021-01-10 05:30:51
    <p>The makes using the lis2dh12 on the ruuvitag almost impossible. <p>Environment - OS:Debian 10 - Toolchain Zephyr SDK - Version 2.1.99</p><p>该提问来源于开源项目:zephyrproject-rtos/zephyr...
  • This module is based on the one for LIS2DS12 (thanks, !), but as sensors are noticeably different, the contents underwent major rework. I've also run <code>clang-format</code> on all C/CXX/H/HPP ...
  • <div><p>Share lis2dh ...same register interface: LIS2DH, LIS3DH, LSM303DLHC, LIS2DH12, LSM303AGR. <p>Signed-off-by: Armando Visconti </p><p>该提问来源于开源项目:zephyrproject-rtos/zephyr</p></div>

空空如也

空空如也

1 2 3 4
收藏数 72
精华内容 28
关键字:

lis2dh12