CH32V30X 纳秒级延时以及指令周期的疑问

发现sdk自带了微秒和毫秒延时函数,但是没有发现纳秒级延时(不需要精确到1ns,只要比如60ns或者120ns的倍数即可)

于是我想到了用for循环来实现纳秒延时,遗憾的是需要知道指令周期才能确定,for循环实际执行了多久

比如

for(int?i=100;?i>0;--i)
asm?volatile("nop");


汇编代码是:

 ? ?li a5,100
.j: nop
? ?addi a5,a5,-1
? ?bnez a5,.j
这4行代码,目前确定第二行 nop 需要 1个指令周期 6.94ns(144M频率)

其他3行代码,并不知道具体执行指令的周期,也就没法计算for循环实际需要执行多久

是否有什么数据手册,可以提供比如 li 指令 addi 指令 bnez等指令的执行周期

这样,就能编写一个宏,实现 比如delay300ns,delay600ns这样的功能

您好,实现us级的延时,可以参考一下下图延时函数写法,do while执行一次大概4个时钟周期,在系统主频72MHz,入口参数t的值为100时,延时时间大概是55us左右。附件为测试代码,你可以参考一下。后续若有问题,可通过邮箱(lzs@wch.cn)和我沟通。

icon_rar.gifCH32V307 us延时.zip

image.png

image.png


虽然和我的代码差不多,但是又让我学了一招:

使用函数的时候,某些代码不会被优化掉(除非使用静态函数)

0000030e :
     30e:47a9                lia5,10
     310:02f50533          mula0,a0,a5
     314:0001                nop
     316:157d                addia0,a0,-1
     318:fd75                bneza0,314 
     31a:8082                ret





我之前也研究过类似的问题,虽然是ch573,但问题应该也差不多。

https://www.wch.cn/bbs/thread-82077-1.html


指令运行的速度应该受流水线影响很大,而且估计详细的信息也是没有的。最重要的是,混合16位和32位指令会导致复杂的流水线延迟。


我猜你这个应用的话,可以嵌入汇编写一堆重复的32位nop,然后在起始的位置使用参数计算偏移量,控制跳转不同的nop处。短延时就往后面点跳,长延时就往前面点跳。由于nop指令都一样,跳转位置和执行时间应该就能成线性关系。


通过跳转到不同的nop地址似乎是个不错的方法,但是如何c代码和汇编代码混合编写呢?


只有登录才能回复,可以选择微信账号登录