假设我想使用带有ESP8266模块的bit-banging驱动SPI外设。我有外设的数据表告诉我它有设置时间和保持时间等。问题是,我怎么知道多少时间(大约)之间通过一行代码拉着莫西人高例如直到下一行把SCK高所以我知道我需要一个延迟之间的线,如果是这样的话,多长时间?
\ \ begingroup \美元
\ \ endgroup \美元
让我们来讨论bit-bang,并且仅在SPI主端(尽管从端类似)和C语言中。
第一个简单的方法,
创建具有汇编语言编写的关键计时区域的函数。每条指令的时钟周期数通常在指令集列表的数据表中。也许Tensilica的大部分指令都需要一个时钟。
如何在不阅读1000页数据表的情况下做到这一点?:
- 用C语言编写一个简单的bit-bang和for(;;)循环计时代码,然后编译并生成程序集列表。
- 从生成的程序集代码列表中获取计时关键部分。
- 在查看指令列表的同时,通过添加NOP、JUMP等来调整汇编代码。
- 将汇编代码嵌入C函数中,并使其可调用。
第二种方法,
帮助我们的是:SPI操作与时钟同步。因此,所有的时间都被引用到时钟。从端等待主操作和计时操作的时钟(和频闪器)信号从主。SPI可以指定设置和保持时间,但不需要指定超时。
因此,我们可以做松散的信号,但不能匆忙和违反设置和保持时间。
- 编写一个与delay() (for()循环或调用delay())之间的bit-bang代码。
- 在监控信号引脚上的计时时调整delay(),以避免计时违规。
第三种方法:
你仍然希望你的SPI不阻塞其他任务,持有100Mhz RISC处理器为一些mS, 1mS * 1000uS * 100Mhz = 100,000指令周期。
- 创建定时器ISR。如何使用计时器的方法可以走一定的距离,取决于你的想象,如;可变时间,启用和禁用。
- ISR根据“调度序列”进行位响,生成SPI时序。
- 创建一个虚拟寄存器集,模拟类似于硬件SPI寄存器的东西。
- 创建一个线轴/FIFO在内存中,并有ISR通过线轴/FIFO从/到驱动器的数据。
这些方法也可以组合使用。对于刚开始工作的人来说,这不是一件微不足道的工作。:-)
\ \ begingroup \美元
\ \ endgroup \美元
我能想到三个选择:
撕入装配代码用来执行拉MOSI引脚高的功能和计数时钟周期用于执行每一行。
在一些头针上运行代码,并在示波器上探测它们。
使用专用的SPI接口,这样就不用担心了。