STM32 HAL SPI 中断处理

Posted

技术标签:

【中文标题】STM32 HAL SPI 中断处理【英文标题】:STM32 HAL SPI Interrupt Handling 【发布时间】:2018-01-09 17:35:48 【问题描述】:

我正在使用 STM32F4xx 并想学习使用 ST-HAL 进行编程。 目前我尝试通过中断发送/接收 SPI。

我使用以下函数通过 INT 接收数据:

初始化函数:

void HAL_MspInit(void)

  /* USER CODE BEGIN MspInit 0 */

  /* USER CODE END MspInit 0 */

  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);

  /* System interrupt init*/
  /* MemoryManagement_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0);
  /* BusFault_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0);
  /* UsageFault_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0);
  /* SVCall_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SVCall_IRQn, 0, 0);
  /* DebugMonitor_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0);
  /* PendSV_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(PendSV_IRQn, 0, 0);
  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

  /* USER CODE BEGIN MspInit 1 */
    /* Peripheral interrupt init */

    HAL_NVIC_SetPriority(SPI1_IRQn, 1, 1); //<--------------------
    HAL_NVIC_EnableIRQ(SPI1_IRQn);         //<--------------------

  /* USER CODE END MspInit 1 */

启动函数:

void main(void)

    HAL_SPI_Receive_IT(&hspi1, buff, size);//Start the receiving process?   

    while(1)
    
     . . . 
    

中断处理程序:

void SPI1_IRQHandler(void)

  /* USER CODE BEGIN SPI1_IRQn 0 */

  /* USER CODE END SPI1_IRQn 0 */
    HAL_SPI_IRQHandler(&hspi1);
    /* USER CODE BEGIN SPI1_IRQn 1 */

      /* USER CODE END SPI1_IRQn 1 */

回调函数(在主文件中定义):

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)

    volatile uint8_t y = 5;

在我的问题之前:使用“正常”的 SPI_Transmit&Receive 函数,我可以正确地发送和接收。

我的问题是我不明白我应该如何使用这些功能。 例如:当回调函数出现时,我应该在哪里调用开始“函数”,我是否必须清除中断标志,等等......

目前我在 while(1) 循环中使用“HAL_SPI_Transmit_IT”和“HAL_SPI_Receive_IT”。在 Rx 和 Tx 回调函数中,我有计数器变量。我看到 tmpCounterRx 计数但 tmpCounterTx 不计数???

例如:

while (1)

    HAL_SPI_Transmit_IT(&hspi1, buff, size);
    HAL_Delay(500);
    HAL_SPI_Receive_IT(&hspi1, buff, size);  



void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)

    tmpCounterTx++;
    volatile uint8_t x = 5;


void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)

    tmpCounterRx++;
    volatile uint8_t y = 5;

牧师。 1:

感谢回复,这里是我的 SPI 初始化函数:

void MX_SPI1_Init(void)

    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_MASTER;
    hspi1.Init.Direction = SPI_DIRECTION_2LINES;
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
    hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
    hspi1.Init.NSS = SPI_NSS_SOFT;
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi1.Init.CRCPolynomial = 10;

    if (HAL_SPI_Init(&hspi1) != HAL_OK)
    
        Error_Handler();
    

【问题讨论】:

请显示您的 SPI 初始化代码。 我建议使用裸注册方法。 嗯...我喜欢使用 StdLib 处理中断的方式。但是我必须学习使用 HAL,我不知道是否建议将 HAL 和裸注册方法混合使用...? 【参考方案1】:

试试这个。我假设计数器是volatile。至少您会知道触发了哪些中断以及是否是 HAL 回调配置问题。

volatile uint32_t tmpCounterRx1 = 0, tmpCounterTx1 = 0;

void SPI1_IRQHandler(void)

  if((SPI1 -> SR & SPI_SR_RXNE)) 
  
    tmpCounterRx1++;
   else    // intentional else do not remove
  if((SPI1 -> SR & SPI_SR_TXE)) 
  
    tmpCounterTx1++;
  
  /* USER CODE BEGIN SPI1_IRQn 0 */

  /* USER CODE END SPI1_IRQn 0 */
    HAL_SPI_IRQHandler(&hspi1);
    /* USER CODE BEGIN SPI1_IRQn 1 */

      /* USER CODE END SPI1_IRQn 1 */

PS 我知道应该是注释,但是在 cmets 中放置较长的代码片段非常困难

【讨论】:

嘿!感谢您的回复!我可以确认中断触发。但是中断触发SPI通信的问题对我的EEPROM写入或读取没有影响。该死! 现在您必须连接逻辑分析仪。没有其它的方法。检查您是否有正确的时钟极性和有效边沿。前段时间我尝试使用 HAL(我只是好奇)。对于任何比 USB 或以太网更复杂的东西都不值得。 是的,我完全同意。基本上我了解到 ISR 应尽可能短。但是如果我看到只有 HAL_SPI_IRQHandler() 有多少代码,它似乎不是很有效。我错了吗?无论如何,您认为混合 HAL 和自己的裸机 ISR 处理“可以”吗? 我看不出有什么问题。唯一没有意义的部分是如果混合使用相同的硬件。 HAL 也有很多错误,使用它的唯一一点是更快地跟踪某些认证。 st.com/en/embedded-software/x-cube-classb.html

以上是关于STM32 HAL SPI 中断处理的主要内容,如果未能解决你的问题,请参考以下文章

spidma发送更新中断

细究STM32 HAL库的中断式串口接收

STM32G0学习手册——使用HAL库进行EXTI中断实验

STM32F4 SPI接收中断不起作用

STM32中串口中断接收异常

STM32HAL 串口发送(中断方式)