打印
[STM32C0]

STM32c031c6 SPI Slave Transmit Only模式的疑问

[复制链接]
78|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
两只袜子|  楼主 | 2025-2-24 15:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32c031c6 SPI Slave Transmit Only模式的疑问。

SPI配置如下。

hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_SLAVE;
  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.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
业务场景:

我希望用MCU将自己模拟成一个32位的移位寄存器,我配置了DMA,CS引脚使用的是外部EXTI。

void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) {
    if (GPIO_Pin == CS_Pin) {
//        cs = true;
//        if (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY)
//            HAL_SPI_Abort(&hspi1);


        if (HAL_SPI_GetState(&hspi1) == HAL_SPI_STATE_READY) {
            if (HAL_OK != HAL_SPI_Transmit_DMA(&hspi1, gpio_value, 8)) {
//                Error_Handler();
//                HAL_UART_Transmit(&huart1, "Error_Handler\n", 14, 10);
            }
        }

    }
}
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin) {
    if (GPIO_Pin == CS_Pin) {
//        CLEAR_BIT(hspi1.Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
//        __HAL_SPI_DISABLE(&hspi1); // 禁用 SPI 外设
        for (int i = 0; i < 30; i++) {
            int j = i + 1;

            if (HAL_GPIO_ReadPin(portmap[i], pinmap[i]) == GPIO_PIN_RESET) {
                SET_BIT(gpio_value[j / 8], 1 << (j % 8));
            } else {
                CLEAR_BIT(gpio_value[j / 8], 1 << (j % 8));
            }
        }



        if (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_BUSY) {
//            HAL_UART_Transmit_IT(&huart1, "HF\n", 3);
            HAL_SPI_Abort_IT(&hspi1);
//            HAL_UART_Transmit_IT(&huart1, "Hf\n", 3);
//
        }

    }

}
目前这样会遇到问题,就是我并不知道SPI MASTER到底需要几个字节的内容。如果双方商量好要4个字节,那么没问题。

业务场景下这个小模块面对的master 可能要3个字节 可能要5个字节,这不是我能决定的,也不是可以预知的。

在slave发送8字节的情况下,master如果只请求了3字节,cs就拉高了,这时候spi外设的FIDO还是被DMA填满了3字节。虽然我使用了Abort,但是FIFO好像并不会被清除,而且会等待发送完成,但是这时候没有CLK了,就会导致Abort 在SPI_DMATxAbortCallback函数当中卡住。此时会错过下一次Master的数据请求。

请问有什么可以解决的方案吗?最优解决策略应该就是在CS上升沿中断当中取消SPI然后清空队列,但是我不知道该如何实现。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2098

主题

7882

帖子

11

粉丝