调试ICM-42670-P陀螺仪通过spi通信,获取陀螺仪ID。
逻辑分析仪是这一款
单片机配置部分,先看陀螺仪数据手册spi时序,以及大小端问题。
可以看到,片选线在低电平时进行信号传输,在高电平时空闲;在时钟线的第二个边沿进行数据采样。在手册部分第一点,MSB优先,寄存器地址最高位为读写位。我们可以进行下图配置。全双工主机,硬件片选关闭,摩托罗拉格式,MSB First, CPOL为片选空闲置高,CPHA为第二个边沿。
生成代码,写入测试代码,只截取主要的测试部分。
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6,GPIO_PIN_SET);
//printf("init ok \n");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
uint8_t buf =0x01;
uint8_t imu_addr=0xF5; //寄存器地址为0X75,最高位或上1,为0XF5
while (1)
{
HAL_Delay(500);
//HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_6);
//read_reg(NULL, (uint8_t *)ICM42670P_WHOAMI,&buf, 1);
//status = read_reg(NULL,0X75, &buf,2); // 读取芯片ID
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET); //片选置低
HAL_SPI_Transmit(&hspi1,&imu_addr, 1, 1000); //发送寄存器地址
HAL_SPI_Receive(&hspi1, &buf, 1, 1000); //接收芯片ID
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); //片选置高
//status = HAL_SPI_TransmitReceive(&hspi1, (uint8_t *)0xF5, &buf,2,100);
printf("status =%d \n",status );
if (status == 0){
printf("id = %x \n\n", buf); // 打印芯片ID
}else {
printf("Read error: %d\n", status); // 打印错误信息
}
//inv_imu_get_who_am_i(&ICM_42670, (uint8_t *)ICM42670P_WHOAMI);
//printf("ok buf =%x \n",buf);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
在这里,寄存器地址为0X75,最高位或上1,为0XF5,数据手册寄存器说明如下
单片机进行测试,串口输出如下;一切正常。
接下来用逻辑分析仪看一下时序。使用的PulseView上位机,配合下图逻辑分析仪。
注意:接线一定要牢固,不然信号传输不太好,我这里使用了母对母杜邦线再加公对公杜邦线进行测试,显示结果不太好。尽量不要像下图这样连接 ,可能测不出好数据。
上位机效果;
上图可见,可见采样并不是很好,有漏采样现象,。再就是注意采样深度和采样频率,不然看不到波形,图中中上部分,左边为采样深度,右边为频率。
放大后看一下;
这里有个问题就是,不知道为什么第一个时钟信号的时候没有进行数据传输,不知道大家知不道这个问题,第二个时钟信号再放大一下看一看,第一行为片选,第二行时钟线,第三行失真了,(线材连接一定要好),第四行从机输出。在第二个时钟沿进行采样,可以读到0X67。
如果不接陀螺仪,单片机spi直接连接逻辑分析仪,波形比较稳,可以查看主机发送信号,下图可见采样很稳,都采到了。
放大看一下
再放大,可以很清楚看到发送数据为0XF5;
总结:注意SPI的模式配置,与数据手册对应。注意逻辑分析仪上位机配置采样长度和采样频率,以及采样线材的连接。