本帖最后由 Hufei1994 于 2023-10-23 20:34 编辑
uint16_t SPI_ReadWriteByte(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData)
{
uint16_t retry=0;
hspi->pRxBuffPtr = (uint8_t *)pRxData;
hspi->pTxBuffPtr = (const uint8_t *)pTxData;
hspi->Instance->CR1|=1<<0;//SPE=1,使能spi
hspi->Instance->CR1|=1<<9;//开启spi
while((hspi->Instance->SR&1<<1)==0)//判断SR寄存器第二位TXP是否为1,等待发送区空
{
retry++;
if(retry>0XFFFE)return 0;
}
*((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
retry=0;
while((hspi->Instance->SR&1<<0)==0)//判断SR寄存器第一位RXP是否为1,等待接收完一个byte
{
retry++;
if(retry>0XFFFE)return 0;
}
*((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
hspi->Instance->IFCR|=3<<3;//EOTC和TXTFC置1,清除EOT和TXTFC位
hspi->Instance->CR1&=~(1<<0);//SPE=0,关闭SPI2,会执行状态机复位/FIFO重置等操作
}
uint16_t SPI_ReadWrite_OneByte(uint16_t _txdata)
{
uint16_t rxdata;
HAL_GPIO_WritePin(SPI5_CS_GPIO_Port, SPI5_CS_Pin, GPIO_PIN_RESET);
SPI_ReadWriteByte(&hspi5, (uint8_t *)&_txdata, (uint8_t *)&rxdata);
HAL_GPIO_WritePin(SPI5_CS_GPIO_Port, SPI5_CS_Pin, GPIO_PIN_SET);
return rxdata;
}
uint16_t AS5047_read(uint16_t add)
{
uint16_t data;
add |= 0x4000; //读指令 bit14 置1
if(Parity_bit_Calculate(add)==1) add=add|0x8000; //如果前15位 1的个数位偶数,则Bit15 置1
SPI_ReadWrite_OneByte(add); //发送一条指令,不管读回的数据
data=SPI_ReadWrite_OneByte(NOP|0x4000); //发送一条空指令,读取上一次指令返回的数据。
data &=0x3fff;
return data;
}
我按照HAL库实现的形式,用指针重写了SPI的传输代码,基本上全是寄存器操作,但是用时并没有预期的大大减小,总体角度读取用时由9.5us下降到了6.5us,仍然存在CS下拉后不立刻发CLK的现象(延迟了约1us),可能是cubemx配置的问题?理论的SPI纯传输时间约为3.6us(实际SPI纯CLK时间也是为3.6us左右),时间主要浪费在了CLK延迟响应上了
|