我尝试使用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 */
}
&#13;
什么可能导致这个脉冲早? 我希望我的问题有道理。 感谢
答案 0 :(得分:1)
当您发送脉冲时,SPI仍在传输数据。您必须等到SPI完成所有挂起传输,而不是等待传输缓冲区为空(我认为SPI是双缓冲的:tx缓冲区加移位寄存器,这很常见)。
因此,SPI模块有一个状态位,表示“传输完成”(在STM32上,这称为“忙”,SPI上有反向信号)。或者,如果没有这样的标志,则应使用计时器等待经过的正确时钟数。 (启动定时器将最后一个字接收到SPI,超时值> =根据SPI时钟和每次传输的位数的传输持续时间)。
好的,我仔细看了一下,实际上没有“完整/忙/闲标志。所以我们必须等待使用接收标志传输的每个字节(见下文)
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。否则必须遵循相同的程序。