STM32L4 //基于中断的并行SPI

时间:2020-05-20 13:17:45

标签: parallel-processing stm32 interrupt spi

遵循此post之后,我设法为我的Nucleo板设置了两个SPI设备和工作中断,并以1ms的周期发送6字节有效负载。我的想法是将两个SPI模块一起触发,以使它们并行运行,但是有一些事情使我无法实现:

  • 预期:SPI1和SPI2序列有99%的重叠,仅通过几个系统时钟进行去相位
  • 已观察到:第一个字节按预期重叠,但是随后,被称为(SPI1)的第一个SPI模块似乎具有优先权,并在允许SPI2终止其发送之前完成了其传输。如果首先调用SPI2,则它将首先完成。 Scope view of two SPI transactions

这是我的主要代码段:

volatile uint8_t t[6] = {0x50, 0x60, 0x70, 0x80, 0x90, 0x10};
volatile uint8_t r[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

volatile uint8_t transmit_count1 = 6, transmit_count2 = 6, transmit_count3 = 6;
volatile uint8_t transmit_index1 = 0, transmit_index2 = 0, transmit_index3 = 0;

void do_SPI_ISR(){
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // SS1
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // SS2

    LL_SPI_Enable(SPI1);
    LL_SPI_Enable(SPI2);

    transmit_index1 = transmit_index2 = transmit_index3 = 0;
    transmit_count1 = transmit_count2 = transmit_count3 = 6;

    LL_SPI_EnableIT_TXE(SPI1); // enable SPI1 TX interrupt
    LL_SPI_EnableIT_TXE(SPI2); // enable SPI2 TX interrupt

    LL_SPI_TransmitData8(SPI1, t[transmit_index1]);
    LL_SPI_TransmitData8(SPI2, t[transmit_index2]);

    while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) == GPIO_PIN_RESET || HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET){
        // SS are set HIGH by interrupts, remain here until that happens for both lines
    }
}

void SPI1_ISR_callback(){
    if (transmit_index1 < transmit_count1 - 1){
        transmit_index1 ++;
        LL_SPI_TransmitData8(SPI1, t[transmit_index1]);
    } else {
        LL_SPI_DisableIT_TXE(SPI1);
        transmit_index1 = 0;
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
        LL_SPI_Disable(SPI1);
    }
}

void SPI2_ISR_callback(){
    if (transmit_index2 < transmit_count2 - 1){
        transmit_index2 ++;
        LL_SPI_TransmitData8(SPI2, t[transmit_index2]);
    } else {
        LL_SPI_DisableIT_TXE(SPI2);
        transmit_index2 = 0;
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
        LL_SPI_Disable(SPI2);
    }
}

我没有对中断优先级进行任何调整,两个SPI的优先级均为0/0。我以为两个中断都会依次触发并触发字节传输,但事实并非如此,也许某些中断事件不断在SPI1上触发,从而阻止SPI2触发他?我尝试删除所有错误并接收中断,但这并没有改变结果。

编辑,更多代码:

void SPI1_IRQHandler(void)
{
  /* USER CODE BEGIN SPI1_IRQn 0 */
    if (LL_SPI_IsActiveFlag_TXE(SPI1)){
        SPI1_ISR_callback();
    }

  /* USER CODE END SPI1_IRQn 0 */
  /* USER CODE BEGIN SPI1_IRQn 1 */

  /* USER CODE END SPI1_IRQn 1 */
}

/**
  * @brief This function handles SPI2 global interrupt.
  */
void SPI2_IRQHandler(void)
{
  /* USER CODE BEGIN SPI2_IRQn 0 */
    if (LL_SPI_IsActiveFlag_TXE(SPI2)){
        SPI2_ISR_callback();
    }

  /* USER CODE END SPI2_IRQn 0 */
  /* USER CODE BEGIN SPI2_IRQn 1 */

  /* USER CODE END SPI2_IRQn 1 */
}

编辑2(25/05/2020),其中TXE标志由主应用程序管理,并且中断被禁用: enter image description here

对应的代码:

void do_SPI_ISR(){
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // SS1
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // SS2

    LL_SPI_Enable(SPI1);
    LL_SPI_Enable(SPI2);

    transmit_index1 = transmit_index2 = transmit_index3 = 0;
    transmit_count1 = transmit_count2 = transmit_count3 = 6;

    //LL_SPI_EnableIT_TXE(SPI1); // enable SPI1 TX interrupt
    //LL_SPI_EnableIT_TXE(SPI2); // enable SPI2 TX interrupt

    LL_SPI_TransmitData8(SPI1, t[transmit_index1]);
    LL_SPI_TransmitData8(SPI2, t[transmit_index2]);

    while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) == GPIO_PIN_RESET || HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET){
        if (LL_SPI_IsActiveFlag_TXE(SPI1)){
            SPI1_ISR_callback();
        }

        if (LL_SPI_IsActiveFlag_TXE(SPI2)){
            SPI2_ISR_callback();
        }
    }
}

非常感谢任何帮助

0 个答案:

没有答案