加速度计AIS2IHTR开发(5)----轮询获取加速度数据 概述AIS2IH 是一款超低功耗三轴线性加速度计它利用了微机械加速度计生产中已采用的稳健成熟的制造工艺旨在解决非安全汽车应用问题。AIS2IH 具有用户可选的 ±2g/±4g/±8g/±16g 满量程能够测量加速度输出数据速率从 1.6 Hz 到 1600 Hz。AIS2IH 具有集成的 32 级先进先出 (FIFO) 缓冲区允许用户存储数据以限制主机处理器的干预。该设备为应用提供了广泛的灵活性因为它能够随时从超低功耗模式切换到高分辨率、高性能模式。内置的自检功能允许用户在最终应用中检查传感器的功能。AIS2IH 具有专用的内部引擎用于处理运动和加速度检测包括自由落体、唤醒、高度可配置的单/双击识别、6D/4D 方向以及活动/非活动。AIS2IH 采用小型薄塑料 LGA 封装并保证可在 -40 °C 至 115 °C 的宽温度范围内工作。需要样片的可以加群申请925643491 / 615061293 。视频教学https://www.bilibili.com/video/BV1esTR6FEN1/样品申请https://www.wjx.top/vm/OhcKxJk.aspx#源码下载参考程序https://github.com/CoreMaker-lab/STM32C542CC_AIS2IHhttps://gitee.com/CoreMaker/STM32C542CC_AIS2IH硬件准备首先需要准备一个开发板这里我准备的是自己绘制的开发板需要的可以进行申请。主控为STM32C542CC,加速度计为AIS2IH通信模式对于AIS2IH可以使用SPI或者IIC进行通讯。最小系统图如下所示。在CS管脚为1的时候为IIC模式本文使用的板子原理图如下所示。管脚定义IIC通信模式在使用IIC通讯模式的时候SA0是用来控制IIC的地址位的。对于IIC的地址可以通过SDO/SA0引脚修改。SDO/SA0引脚可以用来修改设备地址的最低有效位。如果SDO/SA0引脚连接到电源电压LSb最低有效位为’1’地址0011001b否则如果SDO/SA0引脚连接到地线LSb的值为’0’地址0011000b。对应的IIC接口如下所示。主要使用的管脚为CS、SCL、SDA、SA0。速率该模块支持的速度为普通模式(100k)到快速模式(3.4M)。生成STM32CUBEMX2用STM32CUBEMX2生成例程这里使用MCU为STM32C542CCT6。打开 STM32CubeMX2 后进入 Home 首页点击 MCU基于具体芯片型号创建工程在 MCU name 中输入 STM32C542CCT6选择对应的 STM32C5 芯片型号后点击 Continue 进入下一步工程配置。填写工程名称和保存路径后点击 “Automatically Download, Install Create Project”STM32CubeMX2 会自动下载所需软件包并创建工程。STM32CubeMX2 提示 Project Successfully Created 后点击右下角 “Launch Project” 进入工程配置界面。时钟树配置点击左侧外设配置入口进入 Peripherals 配置界面在 System 分类下选择 RCC用于配置系统时钟源HSE Source 选择 Crystal/ceramic resonator启用外部高速晶振LSE Source 选择 Crystal/ceramic resonator启用外部低速晶振点击左侧 Clock 图标进入时钟树配置界面HSE OSC设置外部高速晶振频率这里配置为 24 MHzPSI Mux / PLL选择并配置 PLL 时钟源用于倍频生成系统主频System Mux选择系统时钟来源当前系统主频配置为 144 MHzDEBUG配置在 Peripherals 中选择 Cortex → DEBUG将 Mode 配置为 Single-wire trace asynchronous用于后续程序下载、在线调试和 Trace 调试功能。串口配置查看原理图PA9和PA10设置为开发板的串口。在左侧 Peripherals 中选择 Connectivity → USART1Mode 选择 Async表示配置为异步串口模式Function used by the component 显示为 UART说明 USART1 在异步模式下使用 UART HAL 驱动串口参数配置为115200 波特率、8 位数据位、无校验、1 位停止位、收发模式GPIO TxUSART1_TX 选择 PA9GPIO RxUSART1_RX 选择 PA10PA9 / PA10 均配置为 Alternate 复用功能模式Pull 选择 No pull-up and no pull-downOutput type 选择 Push pullSpeed 选择 LowIIC配置这里传感器IIC接入到开发板的PB6和PB7。首先在 STM32CubeMX2 中进入 Peripherals 外设配置页面在 Connectivity 分类中选择 I2C1并将 I2C1 外设使能。如图所示本实验的 I2C1 配置步骤如下点击左侧 Peripherals 外设配置入口在 Connectivity 分类中选择 I2C1将 I2C1 Mode 设置为 I2C并确认 I2C1 显示为 ActiveSpeed frequency 设置为 Fast mode - 400 kHz确认 I2C1 的 GPIO 引脚映射SCL 为 PB6SDA 为 PB7CS和SA0设置确认 AIS2IH 的 I2C 模式选择和地址选择CS 需要处于 I2C 模式对应电平SA0 需要固定为高电平或低电平将 PA1 和 PB8 配置为普通 GPIO。在 STM32CubeMX2 的 Pinout 页面中将 PA1 和 PB8 配置为普通 GPIO。SA0用于选择 AIS2IH 的 I2C 地址CS用于选择 AIS2IH 的通信接口模式在右侧 Pin signals 中将对应引脚设置为 GPIO → Configured表示该引脚将作为普通 GPIO 使用由用户程序控制输出高低电平。进入 System → GPIO 配置页面可以看到 PA1 和 PB8 已经被加入 GPIO 配置列表。本实验中将 PB8 作为 CS 控制脚 , 将 PA1 作为 SA0 控制脚 。生成项目修改配置后左下角会提示 Click to save需要先保存当前工程配置点击左侧 Project settings进入工程生成设置页面在 IDE Project Generation 中选择工程格式和工具链本例选择 CMake GCC然后点击 Generate IDE project 生成工程导入STM32CubeIDE打开 STM32CubeIDE点击菜单栏 File选择 Import…准备导入 STM32CubeMX2 生成的 CMake 工程在 Import 窗口中展开 Import STM32 Project选择 STM32 CMake Project点击 Next进入 CMake 工程路径选择页面Project name填写导入到 STM32CubeIDE 中显示的工程名称Source directory选择 STM32CubeMX2 生成的 CMake 工程目录点击 Next继续完成工程导入Toolchain选择 MCU ARM GCC表示使用 ARM GCC 工具链进行编译MCU确认芯片型号为 STM32C542CCTx与前面 STM32CubeMX2 中选择的 MCU 保持一致CPU/Core确认内核为 Cortex-M33Core 为 0点击 Finish完成 CMake 工程导入设置工程编码在 Project Explorer 中选中当前工程点击菜单栏 Project选择 Properties进入工程属性设置在工程属性中选择 ResourceText file encoding 选择 Other编码格式输入 GBK点击 Apply and Close 保存设置添加头文件在 main.c 中添加头文件#includemx_usart1.h#includestdio.h#includestring.hprintf 重定向为了让 printf() 输出到 USART1需要重写 _write() 函数。GCC 工程中printf() 底层会调用 _write() 输出字符因此只需要在 _write() 中调用 HAL_UART_Transmit()就可以把 printf() 的内容通过串口发送出去。int_write(intfile,char*ptr,intlen){hal_uart_handle_t*huart1mx_usart1_uart_gethandle();if(huart1!NULL){HAL_UART_Transmit(huart1,ptr,len,1000);}returnlen;}参考程序https://github.com/STMicroelectronics/ais2ih-pid添加对应驱动程序。CMake设置把 ais2ih_reg.c 加入 CMake 编译 。target_sources(${CMAKE_PROJECT_NAME}PRIVATE#Add additional source files hereais2ih_reg.c)printf 输出浮点数需要额外开启 float printf 支持。CMake 官方说明 target_link_options() 就是给可执行目标添加 linker options 的命令。target_link_options(${CMAKE_PROJECT_NAME}PUBLIC#Add additional linker flags here-u _printf_float)头文件设置添加头文件。#includeais2ih_reg.h初始换管脚由于需要向AIS2IH_I2C_ADD_L写入以及为IIC模式。所以使能CS为高电平配置为IIC模式。配置SA0为低电平。printf(HELLO\n);HAL_GPIO_WritePin(CS_PORT,CS_PIN,HAL_GPIO_PIN_SET);HAL_GPIO_WritePin(SA0_PORT,SA0_PIN,HAL_GPIO_PIN_RESET);变量定义。/* Private macro -------------------------------------------------------------*/#defineBOOT_TIME20//ms/* Private variables ---------------------------------------------------------*/staticint16_tdata_raw_acceleration[3];staticfloat_tacceleration_mg[3];staticuint8_twhoamI,rst;staticuint8_ttx_buffer[1000];/* Extern variables ----------------------------------------------------------*//* Private functions ---------------------------------------------------------*//* * WARNING: * Functions declare in this section are defined at the end of this file * and are strictly related to the hardware platform used. * */staticint32_tplatform_write(void*handle,uint8_treg,constuint8_t*bufp,uint16_tlen);staticint32_tplatform_read(void*handle,uint8_treg,uint8_t*bufp,uint16_tlen);staticvoidtx_com(uint8_t*tx_buffer,uint16_tlen);staticvoidplatform_delay(uint32_tms);staticvoidplatform_init(void);获取ID我们可以向WHO_AM_I (0Fh)获取固定值判断是否为0x44。ais2ih_device_id_get为获取函数。对应的获取ID驱动程序,如下所示。/* Initialize mems driver interface */stmdev_ctx_tdev_ctx;dev_ctx.write_regplatform_write;dev_ctx.read_regplatform_read;dev_ctx.mdelayplatform_delay;dev_ctx.handlemx_i2c1_i2c_gethandle();/* Initialize platform specific hardware */// platform_init();/* Wait sensor boot time */platform_delay(BOOT_TIME);/* Check device ID */ais2ih_device_id_get(dev_ctx,whoamI);printf(AIS2IH_ID0x%x,id0x%x\n,AIS2IH_ID,whoamI);if(whoamI!AIS2IH_ID)while(1){/* manage here device not found */}复位操作可以向CTRL2 (21h)的SOFT_RESET寄存器写入1进行复位。ais2ih_reset_set为重置函数。对应的驱动程序,如下所示。/* Restore default configuration */lis2dw12_reset_set(dev_ctx,PROPERTY_ENABLE);do{lis2dw12_reset_get(dev_ctx,rst);}while(rst);BDU设置在很多传感器中数据通常被存储在输出寄存器中这些寄存器分为两部分MSB和LSB。这两部分共同表示一个完整的数据值。例如在一个加速度计中MSB和LSB可能共同表示一个加速度的测量值。连续更新模式BDU ‘0’在默认模式下输出寄存器的值会持续不断地被更新。这意味着在你读取MSB和LSB的时候寄存器中的数据可能会因为新的测量数据而更新。这可能导致一个问题当你读取MSB时如果寄存器更新了接下来读取的LSB可能就是新的测量值的一部分而不是与MSB相对应的值。这样你得到的就是一个“拼凑”的数据它可能无法准确代表任何实际的测量时刻。块数据更新BDU模式BDU ‘1’当激活BDU功能时输出寄存器中的内容不会在读取MSB和LSB之间更新。这就意味着一旦开始读取数据无论是先读MSB还是LSB寄存器中的那一组数据就被“锁定”直到两部分都被读取完毕。这样可以确保你读取的MSB和LSB是同一测量时刻的数据避免了读取到代表不同采样时刻的数据。简而言之BDU位的作用是确保在读取数据时输出寄存器的内容保持稳定从而避免读取到拼凑或错误的数据。这对于需要高精度和稳定性的应用尤为重要。可以向CTRL2 (21h)的BDU寄存器写入1进行开启。对应的驱动程序,如下所示。/* Enable Block Data Update */ais2ih_block_data_update_set(dev_ctx,PROPERTY_ENABLE);设置传感器的量程FS[1:0] - 全量程选择这两个位用于设置传感器的量程。量程决定了传感器可以测量的最大加速度值。例如量程可以设置为±2g、±4g、±8g或±16g。这允许用户根据应用的特定需求调整传感器的灵敏度。对应的驱动程序,如下所示。/* Set full scale *///ais2ih_full_scale_set(dev_ctx, AIS2IH_8g);ais2ih_full_scale_set(dev_ctx,AIS2IH_2g);配置过滤器链ais2ih_filter_path_set(dev_ctx, AIS2IH_LPF_ON_OUT);设置加速度计输出的过滤器路径。这里选择了输出上的低通滤波器LPF用于去除高频噪声。ais2ih_filter_bandwidth_set(dev_ctx, AIS2IH_ODR_DIV_4);设置过滤器的带宽。这里的设置是将输出数据率ODR除以4进一步决定了滤波器的截止频率。设置输出数据速率ais2ih_data_rate_set(dev_ctx, AIS2IH_XL_ODR_25Hz);设置加速度计的输出数据速率为每秒25次。输出数据速率决定了传感器多久采集一次数据并影响数据的实时性和功耗。/* Set Output Data Rate */ais2ih_data_rate_set(dev_ctx,AIS2IH_XL_ODR_25Hz);轮询获取加速度检查新数据是否可用ais2ih_flag_data_ready_get(dev_ctx, reg);这个函数调用检查加速度计是否有新的数据可读。如果有新数据reg 变量将被设置为非零值。主要为读取STATUS (27h)的DRDY位。如果 reg 是非零的说明有新的加速度数据可读。ais2ih_acceleration_raw_get(dev_ctx, data_raw_acceleration);这个函数调用实际读取加速度计的原始数据并存储在 data_raw_acceleration 数组中。数据在28h-2Dh中。加速度数据首先以原始格式通常是整数读取然后需要转换为更有意义的单位如毫重力mg。这里的转换函数 ais2ih_from_fs2_to_mg() 根据加速度计的量程这里假设为±2g将原始数据转换为毫重力单位。acceleration_mg[0] ais2ih_from_fs2_to_mg(data_raw_acceleration[0]); 等三行代码分别转换 X、Y、Z 轴的加速度数据。● AIS2IH 加速度计通常会有一个固定的位分辨率比如 16 位即输出值是一个 16 位的整数。这意味着加速度计可以输出的不同值的总数是 2^1665536。这些值均匀地分布在 -2g 到 2g 的范围内。while(1){uint8_treg;/* Read output only if new value is available */ais2ih_flag_data_ready_get(dev_ctx,reg);if(reg){/* Read acceleration data */memset(data_raw_acceleration,0x00,3*sizeof(int16_t));ais2ih_acceleration_raw_get(dev_ctx,data_raw_acceleration);//acceleration_mg[0] ais2ih_from_fs8_lp1_to_mg(data_raw_acceleration[0]);//acceleration_mg[1] ais2ih_from_fs8_lp1_to_mg(data_raw_acceleration[1]);//acceleration_mg[2] ais2ih_from_fs8_lp1_to_mg(data_raw_acceleration[2]);acceleration_mg[0]ais2ih_from_fs2_to_mg(data_raw_acceleration[0]);acceleration_mg[1]ais2ih_from_fs2_to_mg(data_raw_acceleration[1]);acceleration_mg[2]ais2ih_from_fs2_to_mg(data_raw_acceleration[2]);printf(Acceleration [mg]:%4.2f\t%4.2f\t%4.2f\r\n,acceleration_mg[0],acceleration_mg[1],acceleration_mg[2]);}HAL_Delay(5);}演示