本文使用STM32F407与ADIS16465进行SPI通信
完整的单片机例程已上传☞Github链接
问题一:设备接线
我买回来后在淘宝逛了很久才找到接线方案,感觉这是对我来说最难的问题
接线方案:
从图中可看出针脚间隔1mm,2*7p的针脚,淘宝现成的没找到,需要自己做,胶壳都少见,以下为需要
- sh1.0胶壳
- sh1.0单头的电子线
- 杜邦2.54压线钳
- 杜邦2.54母端子
![](https://img-blog.csdnimg.cn/a83a8aaf8466491cab10270b60212954.png)
![](https://img-blog.csdnimg.cn/8f4570e321fa4d7a9e051ba86b30c7d1.jpeg)
问题二:Burst Read Function
采用这个模式需要调整SPI频率到1Mhz以下,不用考虑Tstall的问题,直接读取图中列出的寄存器,但由于只能读出来16位的测量数据被我放弃。
![](https://img-blog.csdnimg.cn/210a57bc51ad4050b31cd305e45daa95.png)
问题三:Tstall
先列下我踩过的坑
- 由于我的SPI总线只挂了一个设备,初始化时拉低了唯一的片选,导致无法通信,每16位数据收发都需要手动拉低拉高
- 设备的SPI通信时序,有关Tstall问题,每16位数据收发后都要延迟这个时间
- 写入寄存器和一些命令操作,需要先低位后高位发送完整的命令,两个命令之间和上一步一样,只需要延迟一个Tstall,在高位发送出去后,还需要额外延迟一个时间。一般的配置写入,比如配置采样率,低通滤波等需要200us;而像软件复位,设备自检需要延迟的时间在图3表格中有列出
![](https://img-blog.csdnimg.cn/a87ee55789e640a08974c15e52a8aa9c.png)
![](https://img-blog.csdnimg.cn/e20abe11ab264d4aabe4d84faaf2e2c4.png)
![](https://img-blog.csdnimg.cn/d1b5a4e4971946d7a38204ba6332694c.png)
单个寄存器读取的驱动代码如下:
下图为读取寄存器的概念图,由于采用全双工通信,读取一个寄存器需要2次16位的读写,对应代码中的2次循环,每次读写16位数据后延迟一个Tstall
![](https://img-blog.csdnimg.cn/7388d0f425c04213b1a841fd9bfea19e.png)
uint16_t ADIS_ReadReg(uint16_t reg_add)
{
uint16_t Temp = 0;
for (uint8_t i=0; i<2; i++) {
ADIS_CS(0);
Temp = SPI_READ_WRITE(reg_add);
ADIS_CS(1);
delay_us(20);
}
return Temp;
}
单个寄存器写入的驱动代码如下:
写入大部分和读取类似,不一样的在于在高位写入后,IMU需要时间处理这个命令,所以通常延迟200us,其他的特殊命令需要的延迟在出了函数后进行
void ADIS_WriteReg(uint16_t reg_l, uint16_t reg_h)
{
uint16_t Temp[2] = {reg_l, reg_h};
for (uint8_t i=0; i<2; i++) {
ADIS_CS(0);
SPI_READ_WRITE(Temp[i]);
ADIS_CS(1);
delay_us(20);
}
delay_us(200);
}
问题四:数据寄存器单位转化
以量程1,32bit陀螺仪为例,读取的数据寄存器的数值单位为LSB,转化为degree/s需要除以10485760
,然后再转化为弧度。
同理32bit加速度计是一样的,需要除以262144000
转化为单位g,g=9.8m/s2,数值也和表27中可以对应上,262144000=4*2^16*1000
![](https://img-blog.csdnimg.cn/889a5d9880f44009989878eb6137348f.png)
![](https://img-blog.csdnimg.cn/142413561ed44613b1be9193d6a1b038.png)
![](https://img-blog.csdnimg.cn/47ad614d258243308cf0b17784b05164.png)
读取数据+转化代码如下
static uint16_t Address_Meas[]={
(X_GYRO_LOW | READ_FLAG) << 8,
(X_GYRO_OUT | READ_FLAG) << 8,
(Y_GYRO_LOW | READ_FLAG) << 8,
(Y_GYRO_OUT | READ_FLAG) << 8,
(Z_GYRO_LOW | READ_FLAG) << 8,
(Z_GYRO_OUT | READ_FLAG) << 8,
(X_ACCL_LOW | READ_FLAG) << 8,
(X_ACCL_OUT | READ_FLAG) << 8,
(Y_ACCL_LOW | READ_FLAG) << 8,
(Y_ACCL_OUT | READ_FLAG) << 8,
(Z_ACCL_LOW | READ_FLAG) << 8,
(Z_ACCL_OUT | READ_FLAG) << 8,
(uint16_t)Address_Dummy
};
void ADIS_SPI_ReadMeasData(float *Meas)
{
uint16_t TempMeas[13] = {0};
/* 1 读取16位寄存器 */
for (uint8_t i=0; i<13; i++) {
ADIS_CS(0);
TempMeas[i] = SPI_READ_WRITE(Address_Meas[i]);
ADIS_CS(1);
delay_us(20);
}
/* 2 合并为32位 10485760 262144000 由于量程不同各不相同,查阅手册 */
for (uint8_t i=0; i<3; i++) {
Meas[i] = ((TempMeas[i*2+2] << 16) | TempMeas[i*2+1]) * 1.0 / 10485760 * D2R;
}
for (uint8_t i=3; i<6; i++) {
Meas[i] = ((TempMeas[i*2+2] << 16) | TempMeas[i*2+1]) * 1.0 / 262144000 * 9.8;
}
}
本文参考: