IMU模块ICM42688P加速度计陀螺仪的PCB硬件设计和PX4驱动配置
ICM42688P简介
ICM42688P是一款6轴MEMS运动跟踪设备,结合了3轴陀螺仪和3轴加速度计。它有一个可配置的主机接口,支持I3CSM、I2C和SPI串行通信,具有2KB FIFO和2个可编程中断,支持超低功率唤醒,以最大限度地减少系统功耗。
硬件设计
封装
采用了标准的LGA封装,单位是毫米。
引脚序号。
引脚定义。
原理图
使用SPI总线进行连接时的原理图。
使用I2C总线或I3CSM总线进行连接时的原理图。
PCB设计
我这里使用的是SPI总线进行连接,连接到MCU主控的SPI3接口。
主控选择的是STM32H743VIH6,SPI3总线是使用的MOSI-PB5引脚、MISO-PB4引脚、SCK-PB3引脚,片选信号CS是使用PE0引脚,数据准备完毕信号Data_Ready是使用PE1引脚,这些信息需要记录下来,之后在PX4配置中需要用到。
引脚选择问题
这里需要注意不是所有的引脚都可以作为ICM42688P的连接引脚,这个需要在给定的几种方案中选择。
对于主控STM32H743VIH6来说,有以下的引脚映射头文件。
其中有以下内容:
#define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4)
#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN11)
#define GPIO_SPI3_MOSI_1 (GPIO_ALT|GPIO_AF5|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN6)
#define GPIO_SPI3_MOSI_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN12)
#define GPIO_SPI3_MOSI_3 (GPIO_ALT|GPIO_AF7|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN2)
#define GPIO_SPI3_MOSI_4 (GPIO_ALT|GPIO_AF7|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5)
#define GPIO_SPI3_NSS_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15)
#define GPIO_SPI3_NSS_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN4)
#define GPIO_SPI3_SCK_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN3)
#define GPIO_SPI3_SCK_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN10)
所以SPI3总线的MISO引脚只能从PB4、PC11中选择,MOSI引脚只能从PD6、PC12、PB2、PB5中选择,SCK引脚只能从PB3、PC10中选择。
对于片选信号的选择,可以选择任意空闲的GPIO口。
对于数据准备完毕信号的选择,由于该信号使用的是STM32的外部中断输入功能,所以它们的外部中断号不能重复,比如PE1的外部中断号是EXTI1,如果使用了外部中断号是EXTI1的PE1,那么在之后的其他数据准备完毕信号的选择中就不能选择外部中断号是EXTI1的PA1、PB1、PC1等引脚。
朝向问题
在进行PCB设计时需要注意该芯片的朝向问题。
芯片尽量放在PCB的顶面(重力沿Z轴负方向),且芯片的X轴正方向尽量与飞控的正前方向重合。
如果因为各种原因导致没有办法按上述规则进行放置,也尽量按沿Z轴旋转45°、90°等整数位置进行放置,并随后在PX4中传感器启动部分进行额外配置。
PX4驱动配置
飞控板的配置文件夹结构
飞控板的配置文件夹结构为下列所示。
YanQi
├─extras
| └─UCAS_YanQi_bootloader.bin
├─init
| ├─rc.board_defaults
| └─rc.board_sensors
├─nuttx-config
| ├─bootloader
| | └─defconfig
| ├─include
| | ├─board.h
| | └─board_dma_map.h
| ├─nsh
| | └─defconfig
| ├─scripts
| | ├─bootloader_script.ld
| | └─script.ld
| ├─src
| └─Kconfig
├─src
| ├─board_config.h
| ├─bootloader_main.c
| ├─CMakeLists.txt
| ├─hw_config.h
| ├─i2c.cpp
| ├─init.c
| ├─...
| └─usb.c
├─bootloader.px4board
├─default.px4board
└─firmware.prototype
default.px4board文件
default.px4board文件是最常使用的文件,它负责配置每个串口的映射,配置哪些源码被编译到飞控固件中。由于需要使用ICM42688P的驱动,所以需要添加一行代码。
CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y
nuttx-config/nsh/defconfig文件
nuttx-config/nsh/defconfig文件配置的是飞控固件中需要调用的底层资源,比如串口驱动、SPI驱动、I2C驱动等等。
这里使用的是SPI3总线,所以需要添加以下代码。
CONFIG_STM32H7_SPI3=y
如果需要使用DMA功能,则还需要添加以下代码。
CONFIG_STM32H7_DMA1=y
CONFIG_STM32H7_DMA2=y
CONFIG_STM32H7_SPI3_DMA=y
CONFIG_STM32H7_SPI3_DMA_BUFFER=2048
nuttx-config/include/board.h文件
board.h文件用于配置NuttX操作系统中的时钟和引脚,对于所有具有多功能引脚(比如STM32中的有些引脚既可以作为UART也可以作为普通GPIO)的外围设备,NuttX需要知道每个引脚的设定功能,它们在芯片特定的引脚映射头文件stm32h7x3xx_pinmap.h中定义。
需要按照之前的原理图设计对应引脚映射头文件进行修改。
SPI3的引脚定义设置的代码。
#define ADJ_SLEW_RATE(p) (((p) & ~GPIO_SPEED_MASK) | (GPIO_SPEED_2MHz))
#define GPIO_SPI3_MISO GPIO_SPI3_MISO_1 /* PB4 */
#define GPIO_SPI3_MOSI GPIO_SPI3_MOSI_4 /* PB5 */
#define GPIO_SPI3_SCK ADJ_SLEW_RATE(GPIO_SPI3_SCK_1) /* PB3 */
nuttx-config/include/board_dma_map.h文件
board_dma_map.h文件用于配置DMA。DMA用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动,这就节省了CPU的资源来做其他操作。
注意:DMA1只支持8个通道!DMA2只支持8个通道!
需要按照DMA映射头文件进行配置,这里选择了SPI3的DMA1通道。
#define DMAMAP_SPI3_RX DMAMAP_DMA12_SPI3RX_0 /* DMA1:61 */
#define DMAMAP_SPI3_TX DMAMAP_DMA12_SPI3TX_0 /* DMA1:62 */
src/spi.cpp文件
需要按照之前的原理图设计的片选信号和数据准备完毕信号进行配置SPI::CS{GPIO::PortE, GPIO::Pin0}
和SPI::DRDY{GPIO::PortE, GPIO::Pin1}
。
constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = {
/* SPI 3通道 */
initSPIBus(SPI::Bus::SPI3, {
initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortE, GPIO::Pin0}, SPI::DRDY{GPIO::PortE, GPIO::Pin1}),
}),
};
init/rc.board_sensors文件
rc.board_sensors文件作用是启动连接到板上的传感器。
-s 是 Internal SPI 启动,-S 是 External SPI 启动。
-R 后面是旋转角度。如果之前的芯片的X轴正方向不是沿着飞控的正前方向。这里就不能使用默认参数0了,这里的参数既不是角度制的角度也不是弧度制的角度,这里的数字需要根据旋转的角度进行选择。
uint8 orientation # Direction the sensor faces from MAV_SENSOR_ORIENTATION enum
uint8 ROTATION_YAW_0 = 0 # MAV_SENSOR_ROTATION_NONE
uint8 ROTATION_YAW_45 = 1 # MAV_SENSOR_ROTATION_YAW_45
uint8 ROTATION_YAW_90 = 2 # MAV_SENSOR_ROTATION_YAW_90
uint8 ROTATION_YAW_135 = 3 # MAV_SENSOR_ROTATION_YAW_135
uint8 ROTATION_YAW_180 = 4 # MAV_SENSOR_ROTATION_YAW_180
uint8 ROTATION_YAW_225 = 5 # MAV_SENSOR_ROTATION_YAW_225
uint8 ROTATION_YAW_270 = 6 # MAV_SENSOR_ROTATION_YAW_270
uint8 ROTATION_YAW_315 = 7 # MAV_SENSOR_ROTATION_YAW_315
比如如果芯片的X轴正方向指向飞控的右侧,那么就需要将坐标轴沿YAW轴旋转90度,则参数应该选择ROTATION_YAW_90,设为2。
-b 后面是SPI总线序号。
# 内部 SPI 总线 ICM42688P 加速度计、陀螺仪
icm42688p -R 0 -s start
编译BootLoader和Firmware并烧录进自己的飞控板
在Firmware文件夹中输入命令即可对BootLoader和固件进行编译。
make UCAS_YanQi_bootloader
make UCAS_YanQi_default
没有安装烧录工具的先安装dfu-util烧录工具包。
sudo apt install dfu-util
按住飞控板上的BOOT键同时将USB线插入飞控板,进入DFU模式,运行命令即可进行BootLoader烧录。
dfu-util -a 0 --dfuse-address 0x08000000 -D ./build/UCAS_YanQi_bootloader/UCAS_YanQi_bootloader.bin
之后使用QGC安装UCAS_YanQi_default.px4飞控固件即可。