不說廢話 先上源碼:
void MX_SPI2_Init(void)
{
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(spiHandle->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspInit 0 */
/* USER CODE END SPI2_MspInit 0 */
/* SPI2 clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
/**SPI2 GPIO Configuration
PB12 ------> SPI2_NSS
PB13 ------> SPI2_SCK
PB14 ------> SPI2_MISO
PB15 ------> SPI2_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* SPI2 interrupt Init */
HAL_NVIC_SetPriority(SPI2_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(SPI2_IRQn);
/* USER CODE BEGIN SPI2_MspInit 1 */
/* USER CODE END SPI2_MspInit 1 */
}
}
上邊全是初始化的工作,不多說了
void SPI2_IRQHandler(void)
{
/* USER CODE BEGIN SPI2_IRQn 0 */
/* USER CODE END SPI2_IRQn 0 */
HAL_SPI_IRQHandler(&hspi2);
/* USER CODE BEGIN SPI2_IRQn 1 */
/* USER CODE END SPI2_IRQn 1 */
}
中斷觸發調HAL庫,下邊是HAL庫的中斷
void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
{
uint32_t itsource = hspi->Instance->CR2;
uint32_t itflag = hspi->Instance->SR;
/* SPI in mode Receiver ----------------------------------------------------*/
if(((itflag & SPI_FLAG_OVR) == RESET) &&
((itflag & SPI_FLAG_RXNE) != RESET) && ((itsource & SPI_IT_RXNE) != RESET))
{
hspi->RxISR(hspi);
return;
}
/* SPI in mode Transmitter -------------------------------------------------*/
if(((itflag & SPI_FLAG_TXE) != RESET) && ((itsource & SPI_IT_TXE) != RESET))
{
hspi->TxISR(hspi);
return;
}
/* SPI in Error Treatment --------------------------------------------------*/
if(((itflag & (SPI_FLAG_MODF | SPI_FLAG_OVR | SPI_FLAG_FRE)) != RESET) && ((itsource & SPI_IT_ERR) != RESET))
{
/* SPI Overrun error interrupt occurred ----------------------------------*/
if((itflag & SPI_FLAG_OVR) != RESET)
{
if(hspi->State != HAL_SPI_STATE_BUSY_TX)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
__HAL_SPI_CLEAR_OVRFLAG(hspi);
}
else
{
__HAL_SPI_CLEAR_OVRFLAG(hspi);
return;
}
}
/* SPI Mode Fault error interrupt occurred -------------------------------*/
if((itflag & SPI_FLAG_MODF) != RESET)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
__HAL_SPI_CLEAR_MODFFLAG(hspi);
}
/* SPI Frame error interrupt occurred ------------------------------------*/
if((itflag & SPI_FLAG_FRE) != RESET)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE);
__HAL_SPI_CLEAR_FREFLAG(hspi);
}
if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
{
/* Disable all interrupts */
__HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR);
hspi->State = HAL_SPI_STATE_READY;
/* Disable the SPI DMA requests if enabled */
if ((HAL_IS_BIT_SET(itsource, SPI_CR2_TXDMAEN))||(HAL_IS_BIT_SET(itsource, SPI_CR2_RXDMAEN)))
{
CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN));
/* Abort the SPI DMA Rx channel */
if(hspi->hdmarx != NULL)
{
/* Set the SPI DMA Abort callback :
will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError;
HAL_DMA_Abort_IT(hspi->hdmarx);
}
/* Abort the SPI DMA Tx channel */
if(hspi->hdmatx != NULL)
{
/* Set the SPI DMA Abort callback :
will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError;
HAL_DMA_Abort_IT(hspi->hdmatx);
}
}
else
{
/* Call user error callback */
HAL_SPI_ErrorCallback(hspi);
}
}
return;
}
}
標紅的字就是我們所要用的 HAL庫函數,這里是結構體指針,指向以下函數:
HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size);
這里具體為什么,是在這些函數中會具體實現,同時也會在函數中使能SPI 使能SPI中斷,最后結束的時候關閉SPI中斷。所以,我們只要在主函數中調用以上3個就可以實現全部的收發。
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
;
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
上邊這個是回調函數,在你使用了HAL的三個中斷后可以在回調函數里做一些別的事情。
下邊是我的用法:
void SPIWrite2Bytes(uint16_t address , uint16_t sendtemp)
{
uint8_t d_read;
uint8_t szTxData[7];
SPI_CS_ENABLE();
szTxData[0] = (uint8_t)(address>>8)& 0xff;
szTxData[1] = (uint8_t)(address) & 0xff;
szTxData[2] = 0x00;
szTxData[3] = (uint8_t)(sendtemp>>8);
szTxData[4] = (uint8_t)(sendtemp) & 0xff;
HAL_SPI_TransmitReceive_IT(&hspi2,szTxData,&d_read,5);
SPI_CS_DISABLE() ;
}
/******************************************************************************
** Abstract:
** write 1 byte to ADE7953
** Parameters:
** unsigned int address: register address
** long int sendtemp : configuration value
** Returns:
** none
*******************************************************************************/
void SPIWrite1Byte(uint16_t address , uint8_t sendtemp)
{
uint8_t d_read;
uint8_t szTxData[7];
SPI_CS_ENABLE();
szTxData[0] = (uint8_t)(address>>8);
szTxData[1] = (uint8_t)(address);
szTxData[2] = 0x00;
szTxData[3] = sendtemp;
HAL_SPI_TransmitReceive_IT(&hspi2,szTxData,&d_read,4);
SPI_CS_DISABLE();
}
/************
******************************************************************
** Abstract:
** read 4 bytes from ADE7953
** Parameters:
** unsigned int address: register address
** Returns:
** readout : read value
*******************************************************************************/
uint32_t SPIRead4Bytes(uint16_t address,uint8_t *pbuffer)
{
uint32_t readout;
uint8_t d_send = 0xff,d_read;
uint8_t szTxData[7];
SPI_CS_ENABLE();
szTxData[0] = (uint8_t)(address>>8)&0xff;
szTxData[1] = (uint8_t)(address)&0xff;
szTxData[2] = 0x80;
HAL_SPI_TransmitReceive_IT(&hspi2,szTxData,&d_read,3);
HAL_SPI_TransmitReceive_IT(&hspi2,&d_send,pbuffer,4);
readout = (pbuffer[0]<<24)+(pbuffer[1]<<16)+(pbuffer[2]<<8)+pbuffer[3];
SPI_CS_DISABLE();
return (readout);
}
/******************************************************************************
** Abstract:
** read 2 bytes from ADE7953
** Parameters:
** unsigned int address: register address
** Returns:
** readout : read value
*******************************************************************************/
uint16_t SPIRead2Bytes(uint16_t address,uint8_t *pbuffer)
{
uint16_t readout;
uint8_t d_send = 0xff,d_read;
uint8_t szTxData[7];
SPI_CS_ENABLE();
szTxData[0] = (uint8_t)(address>>8)&0xff;
szTxData[1] = (uint8_t)(address)&0xff;
szTxData[2] = 0x80;
HAL_SPI_TransmitReceive_IT(&hspi2,szTxData,&d_read,3);
HAL_SPI_TransmitReceive_IT(&hspi2,&d_send,pbuffer,2);
readout = (pbuffer[0]<<24)+(pbuffer[1]<<16);
SPI_CS_DISABLE();
return (readout);
}
|