十六条指令不是很多;我不希望C编译器能够生成足够高效的代码来对内存转储进行bit-bang。如果你对输出位模式不太挑剔,我认为32字节就足够了:
ldr r1,=Port1 ; Address of IO Port mov r3,#1 str r3,[r1+IOCR0] lsl r0,r3,#27 bytes: mov r5,#9 strb r5,[r1+OUT] add r0,#1 ldrb r4,[r0] bits: strb r4,[r1+OUT] lsr r4,#1 sub r5,#1 bne bits b bytes
每个字节将作为高脉冲输出,然后是8位可能为高或低(取决于数据读取),然后是位时间始终为零,以确保下一个高脉冲的上升沿可见。基本上类似于异步串行通信,但水平相反。
如果Port1的高位在此过程中没有改变,并且您可以确保在时钟变高后稍微读取数据位,您可以尝试这样的事情:
#define P1_DEFAULT = ?//constant high bits of port 1, zeros in low two bits int* dp=0; //maybe use a register which is known to be zeroed. PORT1->IOCR0 = 0x8080; //should be 3 ins for(;;){ int i=32; // int data=*(dp++); //LDMIA instruction may do load and increment in 1 step. do{ PORT1->OUT = P1_DEFAULT #clock low PORT1->OUT = P1_DEFAULT + 2+ (data&1); #clock high with data data>>=1; } while (--i>0); }
这应该删除三个端口读取,一个端口写入和条件。 在一个函数中完成所有操作以避免任何调用开销。我将从生成的程序集开始,看看你可以做些什么来改进它。