单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 128|回复: 1
收起左侧

基于STM32 HAL库的SPI中断

[复制链接]
awagajgjka 发表于 2019-11-22 16:27 | 显示全部楼层 |阅读模式
不说废话  先上源码:
           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);  
}

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

 楼主| awagajgjka 发表于 2019-11-22 16:31 | 显示全部楼层
希望帮到大家

ExampleCode_MTR_ADE7953.zip

147.99 KB, 下载次数: 1, 下载积分: 黑币 -5

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|单片机论坛 |51黑电子论坛技术交流 管理员QQ:125739409;技术交流QQ群636986012

Powered by 单片机教程网

快速回复 返回顶部 返回列表