WCH沁恒单片机
直播中

李晨灵

7年用户 1383经验值
私信 关注
[问答]

求助,CH55X系列指令速度求解

下面有两段代码和反汇编结果对比: UINT8Color

[] = {0x0, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
// WS2812B发送1字节数据
void WS_SendByte(UINT8 buffer)
{
UINT8 i; // 代码段一
//static UINT8 i; // 代码段二
for(i=8;i;--i)
{
if (buffer & 0x80)
{
LED = 1;
++SAFE_MOD;
++SAFE_MOD;
++SAFE_MOD;
}
否则LED = 1;
++SAFE_MOD;
++SAFE_MOD;
LED = 0;
MOD <<= 1;// 没有高空( }空
} { UINT8} SA_MOD = 0x55;// 0 安全解锁模式 SAFE_MOD = 0xAA; 时钟_CFG = 0x86; // 系统时钟分频器4分频=24MHz while (1) {









mDelayuS(1000); // WS_S 观察信号
= 0 观察信号 for; i++i 字节(颜色);
}
}
代码段一反汇编:





注:两段代码唯一的一个关键字关键字
实际使用检测_LED代码段,9次WSSendByte()调用循环,比代码段测长5us。
这个结果的对比比较显示的时间,并没有很短的发现我的查询结果,并没有发现DJNZ会比JNZ明显的多幅相似的时间。
所以希望WCH官方能提出这个疑问。

CH55X指令周期.PDF


回帖(1)

李亮

2022-9-8 10:19:41
有几点需要考虑:

循环变量的静态没有任何意义

您正在使用大型模式,因此 y static i 将被放置在 xdata 中(不能像在非静态版本中那样使用 reg)

vars 总是必须在静态版本的每个循环之后存储回来



因此,为了优化速度,切勿使用大型模式,也不要将静态用于简单的循环 var。Keil 编译器非常聪明,将你的循环变量放在 R6 中,因此可以使用 DJNZ。通过强制它是静态的,它必须在每次计数后存储回来。

通过展开该循环,它会更快,但使用更多代码



阅读一些关于 static 关键字用法的 C 书。

这是一个简短的例子;



#define 等待 ++SAFE_MOD;
++SAFE_MOD;
++SAFE_MOD

void WS_SendByte(UINT8 buffer)
{
LED = (buffer&0x80);
等待;
LED = (缓冲区&0x40);
等待;
LED = (缓冲区&0x20);
等待;
LED = (缓冲区&0x10);
等待;
LED = (缓冲区&0x08);
等待;
LED = (缓冲区&0x04);
等待;
LED = (缓冲区&0x02);
等待;
LED = (缓冲区 &0x01);
等待;
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分