根据AN5444应用笔记介绍,IIS3DWB是一款高性能MEMS三轴振动传感器,具有超宽带宽低噪声等特点,SPI标准接口输出。具体的介绍可参考AN5444应用笔记。本次先对该传感器有个初步的数据读取测试,关于滤波等后面学习时再添加。
$ S) P) P1 M! C- f8 r 原理图关于该部分的说明,如图1所示:3 c5 r' ]3 m$ [$ Z0 u% s
& L9 q* a/ T) O$ a( Z) @/ V图12 K8 k/ A8 K% J' l! E( S5 P
* j1 Y0 O8 t8 I. ` q+ ~ 先使用CubeMx建立工程,时钟等正常配置即可,因为要使用SPI通讯,所以引脚配置如图2:4 `$ \- `- L! d( u) J
- a, b+ ~# n3 ~0 |$ n. X: m) V
/ X) m: S* G$ ]9 V) P- C
! \+ L7 \" Q7 O$ q, n/ v0 r图2 x b8 u8 |( w1 v {. C
SPI外设参数的基本配置如图3:& H4 b1 v8 ?- x" r: u. e
: F7 {7 X7 Y; q; L1 t
3 b2 t, p* i- c* Q3 B! j3 y图3- D" r0 n. u1 V9 d" z$ n9 F0 `
然后生成项目。在官方提供的文件中有IIS3DWB的驱动,4个文件,如图4所示:
8 [, _& {6 p: @- N6 z
! i/ F4 E9 F! l3 w8 t# n# h
6 _" D" F+ P8 h" f
图4
" U1 J* _3 @/ k: R( x4 T 例程是参考官方github中提供的参考例程,修改了一下,增加了温度读取。初始化如下:& X+ q1 \8 n9 R! C/ q, \
- dev_ctx.write_reg = platform_write;3 e7 \+ N- i9 P, Q" V
- dev_ctx.read_reg = platform_read;
6 t+ J& ], u; U7 G4 [ - dev_ctx.handle = &hspi3;
9 u& }% ~& U& ]" l; k
% Q: u5 [- o% \0 H% k9 C& M- HAL_Delay (10);
% G6 Y5 {% v- V1 o+ E4 Q0 e# B6 D - iis3dwb_device_id_get(&dev_ctx, &whoamI);
, I2 s, R; m, ]& ~$ D, w - // 复位设备( j# j! z5 s- x# ^4 N* ~# w6 ?9 j1 W
- iis3dwb_reset_set(&dev_ctx, PROPERTY_ENABLE);1 T6 T5 z! {& _4 I' o+ k8 E, f( m
- // 配置加速度计, i& e" p% r ^4 M
- iis3dwb_block_data_update_set(&dev_ctx, PROPERTY_ENABLE); m8 `) g# f* g
- iis3dwb_xl_data_rate_set(&dev_ctx, IIS3DWB_XL_ODR_26k7Hz);/ D6 S/ D9 v# \1 @' j# H0 X
- iis3dwb_xl_full_scale_set(&dev_ctx, IIS3DWB_2g);
复制代码
; q1 x2 G2 D0 e- o1 f! z5 b
6 {* A4 S* J" u/ p. X" P6 p: G( g 对于加速度值和温度的读取程序如下:9 P) U" @& S: q, Z! H) n) t
- // 读取加速度数据
! H! E: V8 C- m( q -
7 J N% l& H+ z* R: K2 ~ - iis3dwb_xl_flag_data_ready_get(&dev_ctx, &drdy);//读取状态值
+ X+ |. Y% ?, @$ p+ B2 ? - if (drdy) {
" ~1 i- S' ` I! M8 |2 o8 ? -
# q# P+ u% m; e1 `# L - iis3dwb_acceleration_raw_get(&dev_ctx, data_raw);
5 ~. g$ K. W; ^& s: y' K: E - 5 _3 D7 a2 {6 }' Q
- acceleration_mg[0] = iis3dwb_from_fs2g_to_mg(data_raw[0]);& K9 H' F8 S! V* J' E J, B+ W
- acceleration_mg[1] = iis3dwb_from_fs2g_to_mg(data_raw[1]);. ?6 S4 p- c+ o7 G5 ~! b" O" _# B
- acceleration_mg[2] = iis3dwb_from_fs2g_to_mg(data_raw[2]);
' B2 P7 A9 ~2 d4 P - }
9 P9 @- |7 i7 P& r5 h - iis3dwb_read_reg (&dev_ctx ,IIS3DWB_OUT_TEMP_L ,temp_data ,2);; x- A* @ N) }
- temp_raw = (int16_t )((temp_data [1]<<8) | temp_data[0]);
# t% z2 O& j+ J+ d; x* r0 M - temp_cel = temp_raw /256+25;( O5 Z' l( H; J$ B
- . j1 {' q# l% I4 \' H
- HAL_Delay(1000); // 每秒读取一次数据
复制代码 / o( i6 m& ^1 w* R
5 }* z3 @( Q) x& G2 d 测试结果如图5所示:
6 J# L' W$ O9 V0 e) U. I
3 G( h& x7 u* K2 ~( }
8 v+ ^9 b# u; Y. Y f$ q图5
5 h+ [5 _! ~/ \3 v J1 q1 U# K( UDevice ID和温度值是正确的,滤波,FIFO等功能的增加一边理解一边添加测试。6 l6 H& B/ e' J% Z* d
8 Y+ j& G4 {1 N! i: m$ |- \8 M
: K& }# `4 g8 m! Z |
感谢博主指导,我已经调试完成,发现是在使用spi3时只在spi.h文件中声明了spi3,并没有在main.h中声明,在声明之后后获取了数据,再次感谢博主的答疑,辛苦您了(鞠躬)
感谢分享
这个板子肯定可以吧,性能满强的
确实,大佬
感谢分享,学习
你好博主,麻烦问一下您配置这个振动传感器的时候是怎么配置的呢,我看官方的应用笔记上面说明片选在拉低的时候才能用spi,但我配置之后仍然无法读到数据(可以的话能麻烦您分享一下源码我学习一下吗,谢谢您😄 )
[md]不知道是否调通了,我是参考的官方的例程,cubemx配置好SPI后,将传感器的.c 和.h文件移植过来,在main函数中初始化即可。源代码我得找找,有什么问题可以随时留言交流。
[md]我在cubeMX中直接配置了IIS3DWB的驱动文件,然后在官方的例程中进行了修改,但是貌似读取不到设备的ID,麻烦您看一下我这里的配置是有什么问题吗,谢谢您
;
static void platform_delay(uint32_t ms);
//static void platform_init(void);
/ Main Example --------------------------------------------------------------/
void iis3dwb_read_data_polling(void)
{
stmdev_ctx_t dev_ctx;
/ Initialize mems driver interface /
dev_ctx.write_reg = platform_write;
dev_ctx.read_reg = platform_read;
dev_ctx.handle = &hspi3;
/ Init test platform /
// platform_init();
/ Wait sensor boot time /
platform_delay(BOOT_TIME);
/ Check device ID /
iis3dwb_device_id_get(&dev_ctx, &whoamI);
uint8_t ctrl_reg;
iis3dwb_read_reg(&dev_ctx, IIS3DWB_CTRL1_XL, &ctrl_reg, 1);
printf("CTRL1_XL: 0x%02X\n", ctrl_reg);
// if (whoamI != IIS3DWB_ID)
// while (1);
/ Restore default configuration /
iis3dwb_reset_set(&dev_ctx, PROPERTY_ENABLE);
// do {
// iis3dwb_reset_get(&dev_ctx, &rst);
// } while (rst);
/ Enable Block Data Update /
iis3dwb_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
/ Set Output Data Rate /
iis3dwb_xl_data_rate_set(&dev_ctx, IIS3DWB_XL_ODR_26k7Hz);
/ Set full scale /
iis3dwb_xl_full_scale_set(&dev_ctx, IIS3DWB_2g);
/* Configure filtering chain(No aux interface)
*/
iis3dwb_xl_filt_path_on_out_set(&dev_ctx, IIS3DWB_LP_ODR_DIV_100);
/ Read samples in polling mode (no int) /
while (1) {
uint8_t reg;
/ Read output only if new xl value is available /
iis3dwb_xl_flag_data_ready_get(&dev_ctx, ®);
if (reg) {
/ Read acceleration field data / // memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));
iis3dwb_acceleration_raw_get(&dev_ctx, data_raw_acceleration);
acceleration_mg[0] =
acceleration_mg[1] =
acceleration_mg[2] =
}
HAL_Delay(100); // iis3dwb_temp_flag_data_ready_get(&dev_ctx, ®);
//
// if (reg) {
// / Read temperature data /
// memset(&data_raw_temperature, 0x00, sizeof(int16_t));
// iis3dwb_temperature_raw_get(&dev_ctx, &data_raw_temperature);
// temperature_degC = iis3dwb_from_lsb_to_celsius(data_raw_temperature);
// sprintf((char *)tx_buffer,
// "Temperature [degC]:%6.2f\r\n", temperature_degC);
//// tx_com(tx_buffer, strlen((char const *)tx_buffer));
// }
}
}
/*
*/
static int32_t platform_write(void handle, uint8_t reg, const uint8_t bufp,
{
//#ifdef STEVAL_MKI109V3
//
// if (handle == &hspi2) {
HAL_GPIO_WritePin(CS_up_GPIO_Port, CS_up_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit(handle, ®, 1, 1000);
HAL_SPI_Transmit(handle, (uint8_t*) bufp, len, 1000);
HAL_GPIO_WritePin(CS_up_GPIO_Port, CS_up_Pin, GPIO_PIN_SET); // }
//
//#elif defined(SPC584B_DIS)
// / Add here the SPC5 write SPI interface /
//#endif
return 0;
}
/*
*/
static int32_t platform_read(void handle, uint8_t reg, uint8_t bufp,
{
//#ifdef STEVAL_MKI109V3
//
// if (handle == &hspi2) {
/ Read command /
reg |= 0x80;
HAL_GPIO_WritePin(CS_up_GPIO_Port, CS_up_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit(handle, ®, 1, 1000);
HAL_SPI_Receive(handle, bufp, len, 1000);
HAL_GPIO_WritePin(CS_up_GPIO_Port, CS_up_Pin, GPIO_PIN_SET); // }
//#elif defined(SPC584B_DIS)
// / Add here the SPC5 read SPI interface /
//#endif
return 0;
}
那想问一下您在platform_write以及platform_read这个函数中的CS_up_GPIO_Port,以及CS_up_Pin是GPIOF pin5还是GPIOE pin14呢?我在csdn上看到一个博主这里是GPIOE pin14
! f4 [$ P( A# s% @- y! {/ D+ K8 E
[md]CS我用的PF5,
```
static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp, uint16_t len)
{
// uint8_t tx_buffer[1 + len];/ w& c1 u) F5 C* e3 |
// tx_buffer[0] = reg;
// memcpy(&tx_buffer[1], bufp, len);: p; |& K/ e# Z
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_5, GPIO_PIN_RESET); // 选择合适的CS引脚
// HAL_StatusTypeDef status = HAL_SPI_Transmit(handle, tx_buffer, len + 1, HAL_MAX_DELAY);
HAL_SPI_Transmit(handle, ®, 1, 1000);
HAL_SPI_Transmit(handle, (uint8_t*) bufp, len, 1000);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_5, GPIO_PIN_SET); // 选择合适的CS引脚
$ w( j& j% W5 c( B2 i
// return (status == HAL_OK) ? 0 : -1;$ m$ K y" n+ s6 o1 ^8 h
return 0;
}- t& K: L J5 m- @2 _0 t# e
```
您好,请问根据时序图来看,CPOL空闲时应该是高电平,为什么在您这里配置选择LOW。但是,在实例中只有CPOL选择低电平的时候采用数据输出,高电平没有,这与数据手册中的SPI时序图不相符,请问这是怎么回事?