下面的函数使用read_page(pageIter,pageArr,PAGESIZE)一次一页地读取图像,并在DOUT和CCLK引脚上输出数据。
我被告知它效率低下,但我似乎找不到一种方法来让它更快。它基本上是一个管道,运行在64针uProcessor上,在两个内存空间之间。一个保存图像,另一个接收图像。
我使用了寄存器关键字,去掉了数组索引,取而代之的是指针算法,但它需要更快。
谢谢!
/*
Port C Pin Out
*/
#define BIT0 0x01 // CCLK
#define BIT1 0x02 // CS_B
#define BIT2 0x04 // INIT_B
#define BIT3 0x08 // PROG_B
#define BIT4 0x10 // RDRW_B
#define BIT5 0x20 // BUSY_OUT
#define BIT6 0x40 // DONE
#define BIT7 0x80 // DOUT (DIN)
/*
PAGE
*/
#define PAGESIZE 1024 // Example
void copyImage(ulong startAddress, ulong endAddress)
{
ulong pageIter;
uchar *eByte, *byteIter, pageArr[PAGESIZE];
register uchar bitIter, portCvar;
portCvar = PORTC;
/* Loops through pages in an image using ulong type*/
for(pageIter = startAddress ; pageIter <= endAddress ; pageIter += PAGESIZE)
{
read_page(pageIter, pageArr, PAGESIZE);
eByte = pageArr+PAGESIZE;
/* Loops through bytes in a page using pointer to uchar (pointer to a byte)*/
for(byteIter = pageArr; byteIter <= eByte; byteIter++)
{
/* Loops through bits in byte and writes to PORTC - DIN ANC CCLK */
for(bitIter = 0x01; bitIter != 0x00; bitIter = bitIter << 1)
{
PORTC = portCvar | BIT0;
(bitIter & *byteIter) ? (PORTC = portCvar & ~BIT7) : (PORTC = portCvar | BIT7);
PORTC = portCvar & ~BIT0;
}
}
}
}发布于 2011-05-18 04:59:50
也许您可以使用下面这样的命令来解开每个字节的传输,这样做速度会更快
PORTC = clock_1; PORTC = (value & 0x01 ? data1 : data0); PORTC = clock_0;
PORTC = clock_1; PORTC = (value & 0x02 ? data1 : data0); PORTC = clock_0;
PORTC = clock_1; PORTC = (value & 0x04 ? data1 : data0); PORTC = clock_0;
PORTC = clock_1; PORTC = (value & 0x08 ? data1 : data0); PORTC = clock_0;
PORTC = clock_1; PORTC = (value & 0x10 ? data1 : data0); PORTC = clock_0;
PORTC = clock_1; PORTC = (value & 0x20 ? data1 : data0); PORTC = clock_0;
PORTC = clock_1; PORTC = (value & 0x40 ? data1 : data0); PORTC = clock_0;
PORTC = clock_1; PORTC = (value & 0x80 ? data1 : data0); PORTC = clock_0;在图像循环之外进行一次预计算后
unsigned char clock_1 = portC | BIT0;
unsigned char clock_0 = portC & ~BIT0;
unsigned char data1 = portC | BIT7;
unsigned char data0 = portC & ~BIT7;发布于 2011-05-18 04:44:09
/* Loops through bits in byte and writes to PORTC - DIN ANC CCLK */
for(bitIter = 0x01; bitIter <= 0x80; bitIter = bitIter << 1)
{
PORTC = portC | BIT0;
(bitIter & byteIter) ? (PORTC = portC & ~BIT7) : (PORTC = portC | BIT7);
PORTC = portC & ~BIT0;
}这个循环就是关键。我会用生产优化标志编译它,然后看看反汇编。编译器可以做各种聪明的事情,比如展开循环或简化循环条件。如果我不喜欢我在那里看到的东西,我会开始调整C代码,以帮助编译器找到一个好的优化。如果这被证明是不可能的,那么我可以使用内联汇编来获得我想要的东西。
假设我们可以尽可能快地进行(循环中的延迟没有考虑到接收器的建立-保持时间),那么我会希望将循环减少到尽可能少的指令。您是否可以同时设置BIT0和数据位,或者这会在接收器处造成危险吗?如果可以的话,这将节省一两条指令。许多微优化将依赖于特定的指令集。如果数据有很多0或0xFF,你可以在特殊的展开情况下,数据位不变,BIT0切换8次。您可以为一个nybble创建16个展开的案例,并为每个字节切换两次。
发布于 2011-05-18 05:00:05
/* Loops through bits in byte and writes to PORTC - DIN ANC CCLK */
for(bitIter = 0x01; bitIter <= 0x80; bitIter = bitIter << 1)
{
PORTC = portC | BIT0;
(bitIter & byteIter) ? (PORTC = portC & ~BIT7) : (PORTC = portC | BIT7);
PORTC = portC & ~BIT0;
}首先,这个循环被打破了。bitIter是一个uchar (我假设它是一个无符号的8位字符)。通过将其向左移动,它最终将获得预期的最终迭代的值0x80。在下一次移位之后,它将获得值0。
效率的问题。根据体系结构的不同,执行PORTC = PORTC | BIT0操作可能会导致单个位集。然而,它也可能导致读取、在寄存器中设置位和存储。
如前所述,如果可能,请尝试同时设置BIT0和BIT7 (如果硬件允许)。
我会尝试这样的方法:
bitIter = 0x01;
do
{
if (byteIter & bitIter)
{
PORTC = BIT0;
}
else
{
PORTC = (BIT0 | BIT7);
}
PORTC = 0;
bitIter <<= 1;
} while (bitIter != 0x80);通过使用do ... while循环,它将终止问题,并且您将在第一次迭代之前消除不必要的循环测试比较(除非您的编译器已经将其优化)。
您可以尝试手动展开循环八次,每次一次。
https://stackoverflow.com/questions/6036713
复制相似问题