neutronlmk 发表于 2023-3-23 12:53:51

51内置硬件SPI,如果判断SPI传送完成标志会多花很多时间

SPI写一字节代码,两帧码之间时间间隔4.18US:
    /* 清标志 */
    SPSTAT = 0xC0;
    /* 数据写入发送缓冲区 */
    SPDAT= fu8_Data;
    /* 等待完成 */
    while(!(SPSTAT&0x80));
    //SPSTAT = 0xC0;

如果把把查询完成标志的语句注释掉,两帧码之间间隔1.58US,足足缩短2.6US。
我查了编译后的汇编,这个查询也就两条指令:
C:0x0013    E5AD   MOV      A,SPSTAT(0xAD)
C:0x0015    30E7FB   JNB      0xE0.7,C:0013


由此看来这两条指令循环了多次才等到到标志位置位的。
但我不查询SPI传送完成,看波形数据也被送出了啊,这里等待的时间为啥这么长?不等待可不可以。

智涅 发表于 2023-3-23 13:02:14

你能确保你下一次再操作的时间间隔足够大应该是没问题吧
我也有这样用过,用DAC输出波形,尽量快速,所以把等待都取消掉了。
或者安全一点的方法是下次再用SPI的时候再进行判断

neutronlmk 发表于 2023-3-23 14:25:05

智涅 发表于 2023-3-23 13:02
你能确保你下一次再操作的时间间隔足够大应该是没问题吧
我也有这样用过,用DAC输出波形,尽量快速,所以把 ...
(引用自2楼)

足够时间间隔不好裁量,毕竟我要最短时间的。
是不是用逻辑分析仪,看到数据都是正确传送就可以呢?

初音之恋 发表于 2023-3-23 14:50:06

突破标识时间连续使用肯定不可靠,一个行也不能代表个个行,发送之前判断一下标识是否完成了,没完成说明等待时间太短,如果是短时间里有大量数据要发则扔到到缓冲区一条一条单独发送,一直大量数据则无解

矩阵时间 发表于 2023-3-23 14:58:03

SPSTAT = 0xA5;
SPDAT = fu8_Data;
SPSTAT = 0x5A;
SPDAT = fu8_Data;
SPSTAT = 0xA5;
SPDAT = fu8_Data;
SPSTAT = 0x5A;
SPDAT = fu8_Data;

试试就 shishi

neutronlmk 发表于 2023-3-23 15:12:15

矩阵时间 发表于 2023-3-23 14:58
试试就 shishi
(引用自5楼)

感谢。
这样测试写数据时序确实出不来了。
我循环写SPI的代码时序是可以出来的,说明指令延时的时间足够到标志位置位。那我就没必要写SPI之后再等待标志位置位了。

yyts 发表于 2023-3-23 15:13:02

可以把判断发送结束标志的判断,放到每次发送之前。

neutronlmk 发表于 2023-3-23 15:19:45

yyts 发表于 2023-3-23 15:13
可以把判断发送结束标志的判断,放到每次发送之前。
(引用自7楼)

逻辑上有个坑:如果之前没有写操作,此位一直为0,我是不是还得加个超时判断?程序搞起来就太复杂了。

矩阵时间 发表于 2023-3-23 16:22:22

neutronlmk 发表于 2023-3-23 15:19
逻辑上有个坑:如果之前没有写操作,此位一直为0,我是不是还得加个超时判断?程序搞起来就太复杂了。 ...
(引用自8楼)

逻辑上没有坑
把那个判断放前面试试吧
就一个忙标识位而已

yuyu87 发表于 2023-3-23 16:30:44

你把波特率调低点,你再试肯定就会乱掉。

mcu5i51 发表于 2023-3-23 16:46:05

为什么不用中断呢

1a2b3c 发表于 2023-3-24 09:18:52

要等好久不是基本上可以算的出来的吗。spi速度多少,一个字节传输耗多少时间,去掉你搬运时间,剩下的不就是等待的么。
你这样估计是刚好凑巧罢了,前面人说的你换低波特率看看,估计就出问题

负西弱 发表于 2023-3-24 22:01:01

什么应用场景对SPI发送的时间要求这么严格呢

国学芯用 发表于 2023-3-28 09:09:39

本帖最后由 国学芯用 于 2023-3-28 09:18 编辑

要范例程序测试一下




如果还不行,可以用STC8H8K64U 仿真看一下https://www.amobbs.com/thread-5777628-1-1.html
页: [1]
查看完整版本: 51内置硬件SPI,如果判断SPI传送完成标志会多花很多时间