ADI 技术
直播中

曹超

1年用户 8经验值
擅长:MEMS/传感技术 嵌入式技术
私信 关注
[问答]

STM32无法和ADIS16465进行SPI通信,浮空输入,接收的数据全是0,MOSI和MISO短接测试没问题有数据

请问各位大佬,有没有可能我买了个坏的?这是我的接线,手头也没有示波器,不知道该怎么办
3755184013b5ae126e5c782655597ce.jpg

我的驱动代码如下:

#include <string.h>
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/ADIS/adis.h"
#include "./BSP/ADIS/adis_reg.h"


SPI_HandleTypeDef spi_handler;
TIM_HandleTypeDef timx_cap_dr_handle;
uint32_t Meas[6];

/*----------------------------------------------硬件初始化-----------------------------------------------*/
void ADIS_SPI_Init(void)
{
	GPIO_InitTypeDef gpio_init_struct;
	
	SPI1_SPI_CLK_ENABLE(); 											   	/* SPI1时钟使能 */
	SPI1_SCK_GPIO_CLK_ENABLE();  										/* SPI1_SCK脚时钟使能 */
	SPI1_MISO_GPIO_CLK_ENABLE(); 										/* SPI1_MISO脚时钟使能 */
	SPI1_MOSI_GPIO_CLK_ENABLE(); 										/* SPI1_MOSI脚时钟使能 */
	ADIS_CS_GPIO_CLK_ENABLE();											/* ADIS 软件CS脚时钟使能 */
	
	gpio_init_struct.Pin = SPI1_SCK_GPIO_PIN;			
	gpio_init_struct.Mode = GPIO_MODE_AF_PP;
	gpio_init_struct.Pull = GPIO_NOPULL;
	gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
	gpio_init_struct.Alternate = GPIO_AF5_SPI1;
	HAL_GPIO_Init(SPI1_SCK_GPIO_PORT, &gpio_init_struct);				/* SCK引脚模式设置(复用输出) */

	gpio_init_struct.Pin = SPI1_MISO_GPIO_PIN;
	HAL_GPIO_Init(SPI1_MISO_GPIO_PORT, &gpio_init_struct);				/* MISO引脚模式设置(复用输出) */

	gpio_init_struct.Pin = SPI1_MOSI_GPIO_PIN;
	HAL_GPIO_Init(SPI1_MOSI_GPIO_PORT, &gpio_init_struct);				/* MOSI引脚模式设置(复用输出) */
	
	gpio_init_struct.Pin = ADIS_CS_GPIO_PIN;
	gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
    HAL_GPIO_Init(ADIS_CS_GPIO_PORT, &gpio_init_struct); 				/* CS ADIS引脚模式设置(推挽输出) */
	
	gpio_init_struct.Pin = ADIS_RST_GPIO_PIN;
    HAL_GPIO_Init(ADIS_RST_GPIO_PORT, &gpio_init_struct); 				/* RST引脚模式设置(推挽输出) */
	
	ADIS_CS(0);															/* 默认单片选  测试拉高 */
	
	ADIS_RST(0);     													/* 硬件复位 */
	delay_us(30);														/* 保持低电平		最小值 10us */
	ADIS_RST(1);
	
	delay_ms(500);														/* 等待开机恢复 	典型值198ms */
	
    spi_handler.Instance = SPI1_SPI;                                	/* SPI1 */
    spi_handler.Init.Mode = SPI_MODE_MASTER;                        	/* 设置SPI工作模式,设置为主模式 */
    spi_handler.Init.Direction = SPI_DIRECTION_2LINES;              	/* 设置SPI单向或者双向的数据模式:SPI设置为双线模式 */
    spi_handler.Init.DataSize = SPI_DATASIZE_16BIT;                 	/* 设置SPI的数据大小:SPI发送接收16位帧结构 */
    spi_handler.Init.CLKPolarity = SPI_POLARITY_HIGH;              		/* 串行同步时钟的空闲状态为高电平 */
    spi_handler.Init.CLKPhase = SPI_PHASE_2EDGE;                    	/* 串行同步时钟的第二个跳变沿(上升或下降)数据被采样 */
    spi_handler.Init.NSS = SPI_NSS_SOFT;                            	/* NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 */
    spi_handler.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;  	/* SPI1时钟84Mhz 单寄存器读取 64 突发读取模式 128  */
    spi_handler.Init.FirstBit = SPI_FIRSTBIT_MSB;                   	/* 指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 */
    spi_handler.Init.TIMode = SPI_TIMODE_DISABLE;                   	/* 关闭TI模式 */
    spi_handler.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;   	/* 关闭硬件CRC校验 */
    spi_handler.Init.CRCPolynomial = 7;                             	/* CRC值计算的多项式 */
    HAL_SPI_Init(&spi_handler);                                     	/* 初始化 */

    __HAL_SPI_ENABLE(&spi_handler); 									/* 使能SPI1 */
}

void timx_capture_dr_init(uint32_t arr, uint16_t psc)
{
    TIM_IC_InitTypeDef tim_ic_init_struct = {0};
	GPIO_InitTypeDef gpio_init_struct = {0};
	
	TIMX_DR_CLK_ENABLE();                         						/* 开启定时器时钟 */
	TIMX_DR_GPIO_CLK_ENABLE();                    						/* 开启GPIO口时钟 */

	gpio_init_struct.Pin = TIMX_DR_GPIO_PIN;      						/* 输入捕获的GPIO口 */
	gpio_init_struct.Mode = GPIO_MODE_AF_PP;                			/* 复用推挽输出 */
	gpio_init_struct.Pull = GPIO_PULLDOWN;                  			/* 下拉 */
	gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;     					/* 高速 */
	gpio_init_struct.Alternate = TIMX_DR_GPIO_AF; 						/* 复用 */
	HAL_GPIO_Init(TIMX_DR_GPIO_PORT, &gpio_init_struct);

	HAL_NVIC_SetPriority(TIMX_DR_IRQn, 3, 0);         					/* 捕获秒脉冲1 网络接收2 捕获相机3 */
	HAL_NVIC_EnableIRQ(TIMX_DR_IRQn);                 					/* 开启定时器中断 */
	
    timx_cap_dr_handle.Instance = TIMX_DR;                				/* 定时器 */
    timx_cap_dr_handle.Init.Prescaler = psc;                    			/* 预分频系数 */
    timx_cap_dr_handle.Init.CounterMode = TIM_COUNTERMODE_UP;   			/* 向上计数模式 */
    timx_cap_dr_handle.Init.Period = arr;                       			/* 自动重装载值 */
    HAL_TIM_IC_Init(&timx_cap_dr_handle);                       			/* 初始化定时器 */
    
    tim_ic_init_struct.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; 	/* 上升沿捕获 */
    tim_ic_init_struct.ICSelection = TIM_ICSELECTION_DIRECTTI; 			/* 映射通道 */
    tim_ic_init_struct.ICPrescaler = TIM_ICPSC_DIV1;           			/* 配置输入分频,不分频 */
    tim_ic_init_struct.ICFilter = 0;                           			/* 配置输入滤波器,不滤波 */
    HAL_TIM_IC_ConfigChannel(&timx_cap_dr_handle, &tim_ic_init_struct, TIMX_DR_CHX); /* 配置通道 */

    HAL_TIM_IC_Start_IT(&timx_cap_dr_handle, TIMX_DR_CHX);    			/* 使能通道中断和定时器 */
}

void TIMX_DR_IRQHandler(void)
{
	if (__HAL_TIM_GET_FLAG(&timx_cap_dr_handle, TIM_FLAG_CC1) != RESET)			/* 通道1 捕获中断 */
    {
		__HAL_TIM_CLEAR_IT(&timx_cap_dr_handle, TIM_IT_CC1);  					/* 清除中断标志位 */
		
//		memset(Meas,  6, sizeof(uint32_t));
//		ADIS_SPI_ReadMeasData(Meas);
    }
}
/*------------------------------------------------IMU配置------------------------------------------------*/
/* 配置寄存器 */
static uint16_t Imu_Config_Address[]={
	/* 恢复出厂设置 */
//	(((uint16_t)(GLOB_CMD    | WRITE_FLAG)) << 8) | (uint16_t)0x02,	/* 低8位 */
//	(((uint16_t)(GLOB_CMD+1  | WRITE_FLAG)) << 8) | (uint16_t)0x00,	/* 高8位 */
	/* 开启加速度计偏差 */
	(((uint16_t)(NULL_CNFG   | WRITE_FLAG)) << 8) | (uint16_t)0x0A,
	(((uint16_t)(NULL_CNFG+1 | WRITE_FLAG)) << 8) | (uint16_t)0x3F,
	/* 100Hz输出 2000 / (19 + 1) = 100 */
	(((uint16_t)(DEC_RATE    | WRITE_FLAG)) << 8) | (uint16_t)0x13,	
	(((uint16_t)(DEC_RATE+1  | WRITE_FLAG)) << 8) | (uint16_t)0x00,	
	/* 设备自检 */
//	(((uint16_t)(GLOB_CMD    | WRITE_FLAG)) << 8) | (uint16_t)0x04,	
//	(((uint16_t)(GLOB_CMD+1  | WRITE_FLAG)) << 8) | (uint16_t)0x00
};

void ADIS_SPI_Imu_Config(void)
{
	uint16_t STAT = 0, Address = ((uint16_t)(DIAG_STAT | READ_FLAG)) << 8;
	
	// 获取芯片ID
	ADIS_SPI_ReadID();
	
	// 配置IMU  可按指定索引进行
//	for (uint8_t i = 0; i < sizeof(Imu_Config_Address) / sizeof(Imu_Config_Address[0]); i++) {
//		SPI_READ_WRITE_16bit(Imu_Config_Address[i]);
//	}
	
	// 读取自检寄存器
//		   SPI_READ_WRITE_16bit(Address);
//	STAT = SPI_READ_WRITE_16bit(Address);
//	printf("自检结果 0x%X\n", STAT);
//	STAT = SPI_READ_WRITE_16bit(Address);
//	printf("自检结果 0x%X\n", STAT);
//	STAT = SPI_READ_WRITE_16bit(Address);
//	printf("自检结果 0x%X\n", STAT);
//	
//	// 读输出Hz
//	SPI_READ_WRITE_16bit(((uint16_t)(NULL_CNFG   | WRITE_FLAG)) << 8);
//	STAT = SPI_READ_WRITE_16bit(((uint16_t)(NULL_CNFG   | WRITE_FLAG)) << 8);
//	printf("频率 0x%X\n", STAT);
//	STAT = SPI_READ_WRITE_16bit(((uint16_t)(NULL_CNFG   | WRITE_FLAG)) << 8);
//	printf("频率 0x%X\n", STAT);
//	STAT = SPI_READ_WRITE_16bit(((uint16_t)(NULL_CNFG   | WRITE_FLAG)) << 8);
//	printf("频率 0x%X\n", STAT);
}

/*------------------------------------------------软件读写------------------------------------------------*/
/* 输出寄存器 */
static uint16_t Address_Meas[]={
	((uint16_t)(X_GYRO_LOW   | READ_FLAG)) << 8,
	((uint16_t)(X_GYRO_OUT   | READ_FLAG)) << 8,
	((uint16_t)(Y_GYRO_LOW   | READ_FLAG)) << 8,
	((uint16_t)(Y_GYRO_OUT   | READ_FLAG)) << 8,
	((uint16_t)(Z_GYRO_LOW   | READ_FLAG)) << 8,
	((uint16_t)(Z_GYRO_OUT   | READ_FLAG)) << 8,
	((uint16_t)(X_ACCL_LOW   | READ_FLAG)) << 8,
	((uint16_t)(X_ACCL_OUT   | READ_FLAG)) << 8,
	((uint16_t)(Y_ACCL_LOW   | READ_FLAG)) << 8,
	((uint16_t)(Y_ACCL_OUT   | READ_FLAG)) << 8,
	((uint16_t)(Z_ACCL_LOW   | READ_FLAG)) << 8,
	((uint16_t)(Z_ACCL_OUT   | READ_FLAG)) << 8,
	(uint16_t)Address_Dummy
};
	
void ADIS_SPI_ReadMeasData(uint32_t *Meas)
{
	uint16_t TempMeas[12] = {0};
	
	// 1 读取16位寄存器
	SPI_READ_WRITE_16bit(Address_Meas[0]);
	for (uint8_t i=0; i<12; i++) {
		TempMeas[i] = SPI_READ_WRITE_16bit(Address_Meas[i+1]);
	}
	// 2 合并为32位
	for (uint8_t i=0; i<6; i++) {
		Meas[i] = ((uint32_t)TempMeas[i*2+1]  << 16) | TempMeas[i*2];
	}
}

uint8_t ADIS_SPI_ReadID(void)
{
	uint16_t ID = 0, Address = ((uint16_t)(PROD_ID | READ_FLAG)) << 8;
	uint8_t *tmp = (uint8_t *)&Address;
	
//	printf("ID AD 0x%X\n", Address);
//	printf("0x%X 0x%X\n", tmp[0], tmp[1]);
//	printf("%p %p\n", &Address, &*tmp);
	
	SPI_READ_WRITE_16bit(Address);
	SPI_READ_WRITE_16bit(Address);
	ID = SPI_READ_WRITE_16bit(Address_Dummy);			/* 读取 */
	
    if(ID != ADIS16465_ID) {
        printf("检测不到ADIS16465模块,请检查接线  ID:0x%X\n", ID); 	return 0;
    }
	else {
		printf("ADIS16465模块,ID:0x%X\n", ID);
	}
	
	return 1;
}

uint16_t SPI_READ_WRITE_16bit(uint16_t txdata)
{
    uint16_t rxdata = 0;
	
    HAL_SPI_TransmitReceive(&spi_handler, (uint8_t*)&txdata, (uint8_t*)&rxdata, 1, SPIT_FLAG_TIMEOUT);
	delay_us(Stall_Time_US);
	
    return rxdata;
}

回帖(1)

曹超

2023-6-6 17:13:47
后来修改了一下网上一个标准库的驱动,发现他没问题!!!后面逐一比对一下我哪里出了问题
https://blog.csdn.net/qq_42759162/article/details/104168045
2 举报
  • 曹超: 我写的那个驱动,由于单设备,所以在初始化GPIO时把CS片选一直拉低,想节约反复拉高拉低的时间,结果导致无法通信。
  • 曹超: 初始化也有问题,RST引脚PA15无法使用,换了个引脚就好了

更多回帖

发帖
×
20
完善资料,
赚取积分