
使用SPI读取磁编码器芯片的数据,正常来说,只有几us,为什么使用HAL_SPI_TransmitReceive()多了20多us,改成寄存器读时间就正常了,但是读的数据有问题;配置代码如下: void MX_SPI3_Init(void) { / USER CODE BEGIN SPI3_Init 0 / / USER CODE END SPI3_Init 0 / / USER CODE BEGIN SPI3_Init 1 / / USER CODE END SPI3_Init 1 / hspi3.Instance = SPI3; hspi3.Init.Mode = SPI_MODE_MASTER; hspi3.Init.Direction = SPI_DIRECTION_2LINES; hspi3.Init.DataSize = SPI_DATASIZE_8BIT; hspi3.Init.CLKPolarity = SPI_POLARITY_LOW; hspi3.Init.CLKPhase = SPI_PHASE_2EDGE; hspi3.Init.NSS = SPI_NSS_SOFT; hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi3.Init.TIMode = SPI_TIMODE_DISABLE; hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi3.Init.CRCPolynomial = 7; hspi3.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; hspi3.Init.NSSPMode = SPI_NSS_PULSE_DISABLE; if (HAL_SPI_Init(&hspi3) != HAL_OK) { Error_Handler(); } / USER CODE BEGIN SPI3_Init 2 / / USER CODE END SPI3_Init 2 / } uint8_t H_SPIByte(uint8_t d) { uint8_t receivedData = 0;
return receivedData; } |
关于STM32G474 双BANK的测试问题
STM32G474CBT6上电瞬间用示波器测得io口产生较大电压(浪涌电压)
STM432G4单片机IAP程序+上位机
STM32G473 flash擦除时程序卡死
STSPIN32G4内部驱动电压输出问题
comp输出用于tim1刹车,消隐源和pwm输出是不是得是同一个TIM?
STM32G431内部运放1和2输出连接的ADC为什么不是OPAMP?
workbench6.3.2生成的代码,无法用pilot电机参数识别,无法通讯
stm32G474的flash模式如何判定?single bank 和dual bank
STM32G474高精度定时器HRTIM配置死区互补PWM极端输出问题
使用库函数HAL_SPI_TransmitReceive()读数据,是会带来延迟,因为读函数里面加了很多判断和代码,你可以打开这个函数进去看一下。另外使用寄存器读有问题,把代码贴出来,确认一下寄存器是否读正确
[md]多谢回复,解决了,不是SPI的问题,我在发送和接收前加了大约10个170MHz频率的延时就OK了,但是为什么要加我不清楚,以及为什么加大了也不行,而且必须发送和接收都得加,差一个接收的数据就有问题,应该和编码器的时序有关系
uint8_t LCD_SPI_WriteByte(uint8_t TxData) { uint8_t RxData = 0X00;
if LCD_FAST_WRITE
SPI2->CR1 = SPI_CR1_SSI; SPI2->CR2 = 1; SPI2->CR1 = SPI_CR1_SPE | SPI_CR1_SSI; SPI2->CR1 = SPI_CR1_SPE | SPI_CR1_SSI | SPI_CR1_CSTART; while ((SPI2->SR & SPI_FLAG_TXP) == 0); ((__IO uint8_t )&SPI2->TXDR) = TxData; while ((SPI2->SR & SPI_FLAG_TXC) == 0);
SPI2->IFCR = SPI_IFCR_EOTC | SPI_IFCR_TXTFC; SPI2->CR1 &= ~(SPI_CR1_SPE); return RxData;
else
if(HAL_SPI_TransmitReceive(LCD_SPI_Handle, &TxData, &RxData, 1, 100) != HAL_OK) { RxData = 0XFF; }
endif
return RxData; }
参考上面一段代码中的快速读写看一下
代码功能比较稳健,但执行效率相对寄存器操作就要慢些、差些。
如果说觉得直接调用现存API函数在时间上不合适的话,我们可以基于库的API函数对其
做些瘦身,把当前应用不关心不需要的代码屏蔽或删掉,重新构造一个新的用户函数,
满足应用需求即可。
或者 基于寄存器来进行操作,既可以缩小代码容量又可以提升代码执行效率,这时候
往往需要我们对手册有较详细的阅读,其中,对于那些配置有先后时序要求的要加以小心。
[md]uint8_t H_SPIByte( uint8_t d ) { while( (hspi3.Instance->SR & SPI_SR_TXE ) == RESET );hspi3.Instance->DR = d;
while( (hspi3.Instance->SR & SPI_SR_RXNE ) == RESET ); return(hspi3.Instance->DR); }
这是我现在改后的,然后原来SPI使能是在HAL_SPI_TransmitReceive()里面做的,我改后加上去了,不知道是不是还有其他的操作没加
解决了,在发送和接收前,加了一个非常小的延时,就可以了,加大了还不行,会影响到时序