0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

LSM6DSO六軸傳感器使用指南

CHANBAEK ? 來源:嵌入式Linux系統(tǒng)開發(fā) ? 作者:Jasonangel ? 2023-04-17 18:04 ? 次閱讀

博主最近在調(diào)試 lsm6dso,一款集合加速度和陀螺儀的模塊,主要運(yùn)用在手持設(shè)備中。

1、前言

LSM6DSO 是 ST 公司的六軸傳感器,集成三軸加速度和三軸陀螺儀。

2、傳感器特性

  1. 具有數(shù)字 I2C、SPI 和 MIPI I3C 串口標(biāo)準(zhǔn)輸出,組合工作在高性能模式下功耗只要 0.55 mA。
  2. 滿量程加速度范圍:±2/±4/±8/±16 g,且角速率范圍為 ±125/±250/±500/±1000/±2000 dps。
  3. 經(jīng)過配置,LSM6DSO 可利用硬件識(shí)別出的自由落體事件、6D 方向、單擊和雙擊感應(yīng)、活動(dòng)或不活動(dòng)、喚醒事件,來生成中斷信號(hào)
  4. SMD 封裝的超小尺寸和重量使其成為手持便攜式應(yīng)用的理想選擇,如智能手機(jī)、物聯(lián)網(wǎng)IoT)連接設(shè)備,穿戴,以及需要減小封裝尺寸和重量的其他應(yīng)用,尺寸:2.5 mm x 3 mm x 0.83 mm
  5. 支持 1.71V to 3.6V 供電。

3、參考資料

ST 對(duì)于自己出的傳感器,都會(huì)提供驅(qū)動(dòng) demo,放在 github,如下:

https://github.com/STMicroelectronics

其中分為不同的平臺(tái),有的是僅僅基于 C 語言的平臺(tái)無關(guān)的驅(qū)動(dòng),有的是基于 STM32,有的是基于 Linux,有的是基于 Android,一開始學(xué)習(xí)的時(shí)候,建議大家下載平臺(tái)無關(guān)的驅(qū)動(dòng):

圖片

若后續(xù)大家想移植到 Linux、Android ,也可以在這里可以找到工程:

https://github.com/STMicroelectronics/STMems_Standard_C_drivers
https://github.com/STMicroelectronics/st-mems-android-linux-drivers-input
https://github.com/STMicroelectronics/STMems_Linux_IIO_drivers
https://github.com/STMicroelectronics/STMems_Android_Sensor_HAL_IIO

lsm6dso-pid 參考代碼:

https://github.com/STMicroelectronics/STMems_Standard_C_drivers/tree/master/lsm6dso_STdC

arduino、micropython 參考代碼:

https://github.com/arduino-libraries/Arduino_LSM6DSOX
https://github.com/micropython-Chinese-Community/mpy-lib/tree/master/sensor/LSM6DSO

數(shù)據(jù)手冊(cè)下載,其中包含有中文應(yīng)用手冊(cè):

https://www.st.com/zh/mems-and-sensors/lsm6dso.html

圖片

4、引腳說明

一共 14 個(gè) PIN 腳,每個(gè)引腳的詳細(xì)說明可以參考數(shù)據(jù)手冊(cè)。 總的來說就是 I2C 和 SPI 無法同時(shí)使用,因?yàn)樗鼈冇泄灿?PIN 腳。

圖片

5、硬件模式

一般用模式 1,模式 2、模式 3、模式 4 比較復(fù)雜,可以外接傳感器,攝像頭等。

圖片

6、I2C 讀寫地址

LSM6DSO 從機(jī)地址是 110101x ,最后一位 x 和一個(gè) PIN 的狀態(tài)有關(guān)系。 如果 SDO/SA0 是高,從機(jī)地址是 1101011。 如果 SDO/SA0 是低,從機(jī)地址是 1101010。

這個(gè)方案可以使得一路 I2C bus 掛兩個(gè) lsm6dso,同時(shí)使用。

加上讀寫位,總結(jié)如下:

圖片

傳輸示意圖如下:

圖片圖片

7、寄存器

該器件有 60+ 個(gè)寄存器,主要的幾個(gè)如下:

1、設(shè)備 ID

只讀,出廠已經(jīng)固化在硬件里面了,可以通過讀寫這個(gè)寄存器,判斷設(shè)備是否存在,通訊是否正常,設(shè)備的 ID 是 0x6C。

圖片

2、加速度控制寄存器

這個(gè)寄存器可以設(shè)置加速度的量程、輸出速率等;

圖片圖片

3、陀螺儀控制寄存器

這個(gè)寄存器可以設(shè)置陀螺儀的量程、輸出速率等;

圖片圖片

4、狀態(tài)寄存器

通過讀取這個(gè)寄存器可以判斷,傳感器是否有新的數(shù)據(jù)。

圖片

5、溫度傳感器

2個(gè)寄存器,輸出的是有符號(hào)數(shù)據(jù)。

圖片

6、陀螺儀數(shù)據(jù)傳感器

總共 6 個(gè)寄存器,分 x、y、z 三軸的高位和低位,這里要注意,輸出的是有符號(hào)數(shù)據(jù)。

圖片

圖片

圖片

7、加速度數(shù)據(jù)傳感器

總共 6 個(gè)寄存器,分 x、y、z 三軸的高位和低位,這里要注意,輸出的是有符號(hào)數(shù)據(jù)。

圖片

圖片

圖片

8、代碼

博主用的是輪詢?nèi)プx數(shù)據(jù),大家也可以配置成中斷方式。 另外,博主是直接去各個(gè)數(shù)據(jù)寄存器去讀數(shù)據(jù),大家也可以配置成去器件 FIFO 中讀數(shù)據(jù)。 該器件有 3Kbyte 的 FIFO,若使用壓縮算法,可以達(dá)到 9Kbyte。

初始化部分:

i2c_init();
LSM6DSO_Check();
  
u8 LSM6DSO_Check(void)
{
 u8 temp;
 temp=LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_WHO_AM_I);
 if(temp==0X6C)
  return 0; 
 else
   return 1; 
}

LSM6DSO_WriteOneByte(LSM6DSO_ADDRESS,LSM6DSO_CTRL1_XL,ODR_XL_104Hz|FS_XL_2g);
LSM6DSO_WriteOneByte(LSM6DSO_ADDRESS,LSM6DSO_CTRL2_G,ODR_G_104Hz|FS_G_250);

讀數(shù)據(jù)

while(1)
{
  status=LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_STATUS_REG);
  
  if(status & TEM_DATA_AVAILABLE)
  {
   temp_raw=LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUT_TEMP_L)|(LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUT_TEMP_H)<<8);
   temp_deg=temp_raw/TEMP_LSB_PER_DEG+TEMP_OFFSET_DEG;
   sprintf((char*)temperature,"temperature:%02f",temp_deg);
   LCD_ShowString(30,90,200,16,16,temperature);  
  }
  
  if(status & GYR_DATA_AVAILABLE)
  {
   gyr_x_raw = LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTX_L_G)|(LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTX_H_G)<<8);
   gyr_y_raw = LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTY_L_G)|(LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTY_H_G)<<8);
   gyr_z_raw = LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTZ_L_G)|(LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTZ_H_G)<<8);

   gyr_x = gyr_x_raw*GYR_LSB_250_PER;
   gyr_y = gyr_y_raw*GYR_LSB_250_PER;
   gyr_z = gyr_z_raw*GYR_LSB_250_PER;
   
   printf("Gyro:X:%02f mdps,Y:%02f mdps,Z:%02f mdps \\r\\n",gyr_x,gyr_y,gyr_z);
  }
  
  if(status & ACC_DATA_AVAILABLE)
  {
   acc_x_raw=LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTX_L_A)|(LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTX_H_A)<<8);
   acc_y_raw=LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTY_L_A)|(LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTY_H_A)<<8);
   acc_z_raw=LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTZ_L_A)|(LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTZ_H_A)<<8);

   acc_x=acc_x_raw*ACC_LSB_2G_PER;
   acc_y=acc_y_raw*ACC_LSB_2G_PER;
   acc_z=acc_z_raw*ACC_LSB_2G_PER;
   
   printf("Acc:X:%02f mg,Y:%02f mg,Z:%02f mg \\r\\n",acc_x,acc_y,acc_z);   
  }

寄存器定義

#define LSM6DSO_ADDRESS      0xD4

#define LSM6DSO_ID          0x6C

#define LSM6DSO_SDO_CRTL          0x02
#define LSM6DSO_FIFO_CTRL1        0x07  
#define LSM6DSO_FIFO_CTRL2        0x08
#define LSM6DSO_FIFO_CTRL3        0x09
#define LSM6DSO_FIFO_CTRL4        0x0A
#define LSM6DSO_COUNTER_BDR_REG1  0x0B
#define LSM6DSO_COUNTER_BDR_REG2  0x0C  
#define LSM6DSO_INT1_CTRL         0x0D
#define LSM6DSO_INT2_CTRL         0x0E
#define LSM6DSO_WHO_AM_I         0x0F
#define LSM6DSO_CTRL1_XL         0x10
  //bit[7:4]
typedef enum {
   ODR_XL_OFF                  = (0<<4),  
   ODR_XL_1Hz6_LOW_POWER_ONLY  = (11<<4),
   ODR_XL_12Hz5                = (1<<4),
   ODR_XL_26Hz                 = (2<<4),
   ODR_XL_52Hz                 = (3<<4),  
   ODR_XL_104Hz                = (4<<4),   
   ODR_XL_208Hz                = (5<<4),  
   ODR_XL_416Hz                = (6<<4),   
   ODR_XL_833Hz                = (7<<4), 
   ODR_XL_1k66Hz               = (8<<4), 
   ODR_XL_3k33Hz               = (9<<4), 
   ODR_XL_6k66Hz               = (10<<4),  
} lsm6dso_odr_xl_t;
  //bit[3:2]
typedef enum {
   FS_XL_2g                    = (0<<2),
   FS_XL_4g                    = (2<<2),
   FS_XL_8g                    = (3<<2),
   FS_XL_16g_SPIT_OIS_IU_FS    = (1<<2), /* check  XL_FS_MODE = ‘0’ in CTRL8_XL (17h) */
} lsm6dso_fs_xl_t;
#define ACC_LSB_2G_PER       0.061
#define ACC_LSB_4G_PER       0.122
#define ACC_LSB_8G_PER       0.244
#define ACC_LSB_16G_PER      0.488 

#define LSM6DSO_CTRL2_G     0x11
   //bit[7:4]
typedef enum {
   ODR_G_OFF                  = (0<<4),  
   ODR_G_12Hz5                = (1<<4),
   ODR_G_26Hz                 = (2<<4),
   ODR_G_52Hz                 = (3<<4),  
   ODR_G_104Hz                = (4<<4),   
   ODR_G_208Hz                = (5<<4),  
   ODR_G_416Hz                = (6<<4),   
   ODR_G_833Hz                = (7<<4), 
   ODR_G_1k66Hz               = (8<<4), 
   ODR_G_3k33Hz               = (9<<4), 
   ODR_G_6k66Hz               = (10<<4), 
   ODR_G_NOT_AVAILABLE        = (11<<4),
} lsm6dso_odr_g_t;
  //bit[3:2]
typedef enum {
   FS_G_250                   = (0<<2),
   FS_G_500                   = (1<<2),
   FS_G_1000                  = (2<<2),
   FS_G_2000                  = (3<<2),
} lsm6dso_fs_g_t;
    
#define GYR_LSB_250_PER        8.75
#define GYR_LSB_500_PER        17.50
#define GYR_LSB_1000_PER       35.0
#define GYR_LSB_2000_PER       70.0 
  
#define LSM6DSO_CTRL3_C         0x12
#define LSM6DSO_CTRL4_C         0x13
#define LSM6DSO_CTRL5_C        0x14
#define LSM6DSO_CTRL6_C        0x15
#define LSM6DSO_CTRL7_G          0x16
#define LSM6DSO_CTRL8_XL         0x17
#define LSM6DSO_CTRL9_XL         0x18
#define LSM6DSO_CTRL10_C         0x19
#define LSM6DSO_ALL_INT_SRC      0x1A
#define LSM6DSO_WAKE_UP_SRC      0x1B
#define LSM6DSO_TAP_SRC          0x1C
#define LSM6DSO_D6D_SRC          0x1D
#define LSM6DSO_STATUS_REG       0x1E
#define TEM_DATA_AVAILABLE   (1<<2)
#define GYR_DATA_AVAILABLE   (1<<1)
#define ACC_DATA_AVAILABLE   (1<<0)
  
#define LSM6DSO_OUT_TEMP_L       0x20
#define LSM6DSO_OUT_TEMP_H       0x21
#define TEMP_LSB_PER_DEG     256.0
#define TEMP_OFFSET_DEG      25

#define LSM6DSO_OUTX_L_G     0x22
#define LSM6DSO_OUTX_H_G     0x23
#define LSM6DSO_OUTY_L_G     0x24
#define LSM6DSO_OUTY_H_G     0x25
#define LSM6DSO_OUTZ_L_G     0x26
#define LSM6DSO_OUTZ_H_G     0x27

#define LSM6DSO_OUTX_L_A    0x28
#define LSM6DSO_OUTX_H_A     0x29
#define LSM6DSO_OUTY_L_A     0x2A
#define LSM6DSO_OUTY_H_A     0x2B
#define LSM6DSO_OUTZ_L_A     0x2C
#define LSM6DSO_OUTZ_H_A     0x2D
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 傳感器
    +關(guān)注

    關(guān)注

    2541

    文章

    49963

    瀏覽量

    747538
  • 陀螺儀
    +關(guān)注

    關(guān)注

    44

    文章

    768

    瀏覽量

    98190
  • ST
    ST
    +關(guān)注

    關(guān)注

    32

    文章

    1120

    瀏覽量

    128553
  • 串口
    +關(guān)注

    關(guān)注

    14

    文章

    1533

    瀏覽量

    75465
  • 六軸傳感器
    +關(guān)注

    關(guān)注

    1

    文章

    17

    瀏覽量

    16199
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    線性NTC溫度傳感器使用指南

    線性NTC溫度傳感器使用指南 1.什么是線性NTC溫度傳感器?
    發(fā)表于 01-14 08:52 ?2484次閱讀

    LSM6DSR和LSM6DSO區(qū)別有多大?

    在開發(fā)LSM6DSR的軟件,我有LSM6DSO的驅(qū)動(dòng)代碼,請(qǐng)問,LSM6DSR和LSM6DSO在開發(fā)方面區(qū)別大嗎?我能否直接拿LSM6DSO
    發(fā)表于 03-11 08:09

    LSM6DSO中的ID無法檢測(cè)到自由落體示例代碼是什么原因呢

    大家好!我在帶有 stm32l4 MCU 的定制板上安裝了 LSM6DSO,我只使用 I2C 接口(我不使用中斷)。我在 STMems 標(biāo)準(zhǔn) C 驅(qū)動(dòng)程序中使用 LSM6DSO 自由落體示例代碼,我
    發(fā)表于 12-19 07:42

    我想知道lsm6dso傳感器在什么情況下會(huì)重置呢?

    我正在為手表使用 lsm6dso 傳感器。一開始,我使用以下函數(shù)來獲取寄存器中的步驟。它在一個(gè)while循環(huán)中工作,可以正常工作。int32_t
    發(fā)表于 01-05 07:00

    LSM6DSO計(jì)步器如何設(shè)置?

    現(xiàn)在我正在使用 LSM6DSO 傳感器計(jì)步功能。我發(fā)現(xiàn)它太敏感了,想改變它。我找到了四個(gè)計(jì)步器設(shè)置。它們是 ****_CMD_REG、****_DEB_STEPS_C
    發(fā)表于 01-09 07:28

    如何配置LSM6DSO并將其同步到樹莓派?

    了 Unico GUI 程序,以配置我的慣性模塊。當(dāng)我打開它并選擇我的慣性模塊 (LSM6DSO) 時(shí),然后我按“選擇設(shè)備”,程序關(guān)閉。您需要知道它所連接的主板嗎?因?yàn)槲也恢缿T性傳感器連接到哪個(gè)主板。我得到
    發(fā)表于 01-12 09:20

    MEMS LSM6DSD/LSM6DS3/LSM6DSO是否比LSM6DSR具有更好的“抗沖擊性”?

    MEMS LSM6DSD、LSM6DS3、LSM6DSO 是否比 LSM6DSR 具有更好的“抗沖擊性”?LSM6DSR數(shù)據(jù)表中找不到以下短
    發(fā)表于 02-02 09:21

    如何輕松進(jìn)行lsm6dsolsm6dsox軟件檢測(cè)?

    我們?yōu)槲覀兊拈_發(fā)使用兩種類型的傳感器lsm6dsolsm6dsox。有必要檢測(cè)傳感器 SW 的類型(無需打開設(shè)備)。這很困難,因?yàn)榈刂罚ㄎ覀兪褂?i2c)是相同的,
    發(fā)表于 02-03 11:24

    SPI的LSM6DSO問題如何處理?

    目前我們正在嘗試在我們的項(xiàng)目中使用 LSM6DSO6 MEMS 傳感器)。我們能夠使用 ST 適配器板 STEVAL-MKI159V1 成功測(cè)試
    發(fā)表于 02-09 07:09

    LSM6DSO iNEMO慣性傳感器模塊相關(guān)的使用信息和應(yīng)用提示

    LSM6DSO 是系統(tǒng)級(jí)封裝的 3D 數(shù)字加速度計(jì)和 3D 數(shù)字陀螺儀,具有數(shù)字 I2C、SPI 和 MIPI I3CSM 串口標(biāo)準(zhǔn)輸出,組合工作在高性能模式下功耗只要 0.55 mA。由于陀螺儀
    發(fā)表于 09-06 06:56

    LSM6DSO的應(yīng)用筆記

    本文檔旨在提供 ST LSM6DSO iNEMO 慣性傳感器模塊相關(guān)的使用信息和應(yīng)用提示。LSM6DSO 是系統(tǒng)級(jí)封裝的 3D 數(shù)字加速
    發(fā)表于 09-13 08:05

    線性NTC溫度傳感器使用指南

    線性NTC溫度傳感器使用指南
    發(fā)表于 06-30 19:39 ?2000次閱讀

    LSM6DS3_傳感器

    小鋼炮(CANNON)使用的傳感器LSM6DS3
    發(fā)表于 02-19 14:51 ?0次下載

    LSM303AGR_傳感器

    小鋼炮(CANNON)使用的傳感器LSM303AGR
    發(fā)表于 02-19 14:51 ?0次下載

    工程師筆記|NUCLEO-G474RE 開發(fā)板擴(kuò)展 LSM6DSO 實(shí)現(xiàn) Data Fusion 演示

    的評(píng)估或工程演示時(shí),往往需要快速地得到直觀的評(píng)估效果。Unicleo-GUI 是針對(duì)運(yùn)動(dòng) MEMS 和環(huán)境傳感器擴(kuò)展軟件的 GUI,主要功能是演示 MEMS 傳感器和算法。LSM6DSO 是一款具有
    的頭像 發(fā)表于 11-27 18:30 ?1598次閱讀