You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SPI发送数据时TXE标志未清除且RXEN异常置位问题咨询

SPI发送函数异常问题分析
void SPI_SendData(SPI_RegDef_t *pSPIx ,uint8_t *pTxBuffer,uint32_t len)
{
    while(len > 0)
    {
        // 1. 等待TXE标志置位(等待发送缓冲区为空)
        while (SPI_GetFlagStatus(pSPIx, SPI_FLAG_TXE) == FLAG_RESET);
        //2. 检查DFF位

        if(((pSPIx->CR1 >> SPI_CR1_DFF) & 1) == SPI_DFF_16BIT)
        {
            // 16位模式
            pSPIx->DR = *((uint16_t*) pTxBuffer);
            (uint16_t*) pTxBuffer++;
            len--;

        }else
        {
            pSPIx->DR = *pTxBuffer;
            pTxBuffer++;
        }

         len--;
    }
}

根据SPI协议知识,写入SPI_DR寄存器应清除TXE标志,但实际执行上述发送数据代码时,TXE标志未被清除,RXEN标志却被置位。请问RXEN标志为何会被置位?TXE标志未清除的原因是什么?


问题分析与解答

1. RXEN标志被置位的原因

RXEN是SPI接收使能位,它的置位和发送操作本身无直接关联,核心原因是SPI初始化阶段就已开启接收功能:

  • SPI本质是全双工总线,多数MCU的SPI外设默认或初始化配置中会自动使能接收(RXEN位置1)。因为全双工模式下,发送操作必然伴随接收动作——即使你不需要接收数据,硬件也会在发送时钟驱动下采样MISO线数据并填充接收缓冲区。
  • 部分MCU的SPI外设中,RXEN位是只读属性,或仅能通过切换到单工发送模式关闭。如果你的初始化代码没有做这类特殊配置,RXEN会一直保持置位状态。

2. TXE标志未清除的原因

正常写入SPI_DR后硬件会自动清除TXE标志,你的代码出现异常是因为存在两处关键错误,导致DR寄存器未被正确写入:

  • 16位模式下的指针操作错误:(uint16_t*) pTxBuffer++; 优先级逻辑错误,++优先级高于强制类型转换,实际执行的是(uint16_t*)(pTxBuffer++)——先把8位指针pTxBuffer自增1(仅移动1字节),再转成16位指针。这会导致写入DR的是错误内存地址的数据,甚至因地址不对齐触发硬件异常,直接跳过DR写入操作。正确写法应为((uint16_t*)pTxBuffer)++;,或用临时变量中转指针。
  • len的重复递减:16位分支内已执行len--;,但循环末尾又重复执行一次len--;,会导致len被多减1,提前退出循环。比如当len=1时,进入16位分支后len变为0,循环末尾再减1变成-1,直接终止循环,此时DR可能未被写入,TXE自然不会被清除。

内容的提问来源于stack exchange,提问作者metisai02

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 18:45:21