C SPI 锁存脉冲发生得太快

C SPI latch pulse happening too soon

我正在尝试使用 9s12 连接 2 个 MAX7219 驱动器。 我的问题是,当我发送数据时,锁存脉冲在 SPI 传输完成之前发生。 http://imgur.com/BGd1sB9

附图显示了在 SPI 时钟和数据仍在发送时发生的脉冲。

void MAX7219Init(void)
{
    INT8U count =0;

    setLow(PORTP, PIN6);    /* Need to set low on startup */
    for (count = 1; count <= 2; count++){ //Run twice to send data to 2 max7219
        spimx(0x0F, 0xCD); 
    }
    pulse(PORTP, PIN6);

    while (1) ;

}

void spimx(INT8U address, INT8U data)
{
   
    while((SPI0SR & SPTEF) == 0){} /*Wait for previous transmit */
    SPI0DR = (INT8U)(address & 0b00001111);                /*Initiate a transfer */
    while((SPI0SR & SPIF) == 0){}  /*Wait for new data */

 
    while((SPI0SR & SPTEF) == 0){} /*Wait for previous transmit */
    SPI0DR = data;                /*Initiate a transfer */
    while((SPI0SR & SPIF) == 0){}  /*Wait for new data */
 
}

是什么原因导致此脉搏提前? 我希望我的问题是有道理的。 谢谢

在你发送脉冲的那一刻,SPI还在传输数据。您必须等到 SPI 完成 all 挂起的传输,而不仅仅是等待传输缓冲区为空(我想 SPI 是双缓冲的:tx 缓冲区加移位寄存器,这非常常见)。

所以,要么 SPI 模块有一个状态位,它发出 "transmission complete" 信号(在 STM32 上,这被称为 "busy",在 SPI 上有反向信号)。或者,如果没有这样的标志,您应该使用计时器来等待经过适当数量的时钟。 (在将最后一个字发送到 SPI 后启动定时器,超时值 >= 根据 SPI 时钟和每次传输的位数的传输持续时间)。

好吧,我仔细看了看,实际上没有“complete/busy/idle标志。所以我们必须等待使用接收标志传输的每个字节(见下文)

void spimx(INT8U address, INT8U data)
{
    SPI0DR = (INT8U)(address & 0b00001111); // send address
    while ( !(SPI0SR & SPIF) ) ;            // Wait until shifted
    SPI0DR;                                 // explaination below
    SPI0DR = data;                          // send data
    while ( !(SPI0SR & SPIF) ) ;            // Wait until shifted
    SPI0DR;                                 // explaination below
    // here the SPI is idle
}

由于SPI的双向特性,如果接收到数据,则存储的字节也已发送。所以实际上不需要测试 SPTEF。一开始,也不需要,因为 SPI 从上次调用开始就为空(请参阅下面的警告)。

要清除SPIIF 标志,我们必须读取数据寄存器。因为我们不需要数据,所以我们将其丢弃(虚拟读取)。否则,该标志将永远保持设置状态,等待循环将立即终止。这将导致所显示的行为。

注意初始化后不要使用其他函数写入SPI。否则必须遵循相同的程序。