2017-08-02 489 views
1

使用STM32F4xx并想学习编程ST-HAL。 在我尝试通过中断发送/接收SPI的那一刻。STM32 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) 
    { 
    . . . 
    } 
} 

Interrputhandler:

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 */ 
} 

Callb ackfunction(主文件中定义):

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) 
{ 
    volatile uint8_t y = 5; 
} 

我的问题之前:使用 “正常” SPI_Transmit &接收功能,我发送&接收正确。

我的问题是,我不明白我应该如何使用这个功能。 如:我应该在哪里调用start“功能”,当谈到的回调函数,一个我要明确Interruptflags,等等...

目前我在使用‘HAL_SPI_Transmit_IT’&‘HAL_SPI_Receive_IT’ while(1)循环。在Rx和Tx回调函数中,我有计数器变量。我看到tmpCounterRx向上计数,但tmpCounterTx dosnt?

例如为:

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(); 
    } 
} 
+0

显示您的SPI初始化代码,请。 –

+0

我会建议裸登记方法。 –

+0

嗯......我喜欢中断处理与StdLib协同工作的方式。但我必须学习使用HAL,我不知道它是否推荐混合HAL和裸注册方法......? – TangoOne

回答

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我知道这应该是发表评论,但它是相当困难的放置较长的代码条评论

+0

嘿!感谢您的回复!我可以确认中断触发。但是,中断触发SPI通信的问题对写入或读取EEPROM没有影响。该死的! – TangoOne

+0

现在你必须连接逻辑分析仪。别无退路。检查是否有正确的时钟极性和有效边沿。前段时间我试图用HAL(我只是好奇)。对于比USB或以太网简单的任何东西都不值得。 –

+0

是的,我完全同意。基本上我知道ISR应尽可能短。但是如果我看到只有HAL_SPI_IRQHandler()有多少代码,它似乎不是非常有效。我错了吗?无论如何,你认为混合HAL和自己的裸机ISR处理是不是“好”? – TangoOne