1

我目前正在编写代码以逐个像素地在 LCD 屏幕上写入。代码工作正常,但是处理代码的速度非常慢。目标只是在 LCD 屏幕上写入数字,因此我使用带有“for 循环”的“开关”功能来读取我将激活的每个位。我想知道是否有人可以告诉我一种加快代码速度的方法...

int* switch_library_number_1(int num, int octet) {

switch(num)
{

case 0 : ;
    int number_0 [] = {0x80, 0x08,
              0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x88,
              0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, ...};

        int * pNumber_0 = &number_0[octet];

        return pNumber_0;
          break;

case 1 : ;
    int number_1 [] = {0x80, 0x08,
              0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x88, ...};

    int * pNumber_1 = &number_1[octet];

    return pNumber_1;
      break;
}

然后像那样上升到九个,我认为您不需要查看所有情况。另外,即使我删除了其中的大部分,我也有 522 个字节。其余代码如下:

int main(void)
{
ADC_Initialization();
SPI_Initialization();
int nombre_octet = 522;
int premier_nombre;
int deuxieme_nombre;

while(1)
{
    GPIOA->BSRRL = CS;
    for(int i = 0; i < nombre_octet; i++)
    {
        write_spi(*switch_library_number_1(0, i));
    }
    GPIOA -> BSRRH = CS;

    for(int i = 0; i < 100; i++)
            {
            }

    GPIOA->BSRRL = CS;
    for(int i = 0; i < nombre_octet; i++)
    {
        write_spi(*switch_library_number_2(1, i));
    }
    GPIOA -> BSRRH = CS;

    }
}

最后,这里是 write_SPI 函数,但由于它的简单性,我认为不是问题所在。

void write_spi(char data)
{
    SPI1->DR = data;

    while (!(SPI1->SR & SPI_I2S_FLAG_TXE));
    while (!(SPI1->SR & SPI_I2S_FLAG_RXNE));
    while (SPI1->SR & SPI_I2S_FLAG_BSY);
}

提前致谢!

4

2 回答 2

1

我非常喜欢您将代码分成三个片段的方式。我可以对它们中的每一个提出改进建议:

switch_library_number_1()

  • 这可能只是一个 2D 数组,number[][]或者如果number_0, number_1... 的长度不同,它可能是指向这些的指针数组。需要检查有效numoffset。这可能是一个小的速度改进。
  • 您的number_0... 数组当前在堆栈上,并且可以读写。制作它们const,这样它们就不会使用 RAM。
  • 目前,您正在返回一个指向堆栈上内存位置的指针 - 这通常不起作用,如果它这样做是幸运和偶然的。当您超出定义的范围(函数)时,您不应该访问堆栈数据。static const会让这个安全,因为它不会再在堆栈上。

主循环

  • switch_library_number_1/2调用每个循环迭代有点奇怪。你知道你的数据只是在数组中。write_spi(number[0][i]);如果number数组设置正确,这可能会被替换。这应该可以提高您的速度,因为它大大简化了数据获取。
  • 您似乎有一个繁忙的循环。这是一个棘手的做法(我打赌这100是一个猜测,并注意编译器可以优化这个循环)。如果可能使用某些库提供的延迟函数或计时器来获得精确的延迟。这是SPI从机的实际要求吗?

write_spi(字符数据)

  • char应该在unsigned char这里。chars 可能是有符号或无符号的,因此当您将它们用作字节(不是实际的字符串字符)时,您应该指定有符号性。
  • 您似乎在等待每个字节传输完成,这是安全的,但有点慢。通常,这可以重写为更快的替代方案wait_for_SPI_ready_for_TX; SPI_TX,您只需在发送下一个字节之前等待。请注意,您还需要等待字节完全传输,然后再将 CS 拉回高电平。这可能是一个很大的速度改进。

其他一些需要考虑的事情:

  • 实际的 SPI 时钟是多少?如果时钟增加,可能会有巨大的速度提升。
  • 你如何衡量这是“慢”?它是否指向代码的慢部分(那是什么?如果从 C 语言中不明显,它们被组装成什么?)
  • 您有示波器/逻辑分析仪来查看线上的实际信号吗?这可以提供有用的数据。
于 2019-03-13T09:16:13.690 回答
0

我在 STM32F207 系列 Cortex-M3 控制器上遇到了类似的问题,当我通过振荡器观察 TX 线时,我看到 CHIP_SELECT disable 在所有数据发送后需要太多时间才能设置。我发现它与标志控制所以我稍微玩一下控制标志,这对我来说效果很好;

static void SPI_Send(uint16_t len,uint8_t* data)
{
   uint16_t i;

   for(i = 0;i<len;i++)
   {        
     SPI_I2S_SendData(SPI1,*(data+i));
     while(!(SPI1->SR & SPI_SR_TXE));   
   }    
   while(SPI1->SR & SPI_SR_BSY);
   CHIP_SEL_DISABLE;
}

我相信这很慢,因为您还在不需要的地方检查“接收缓冲区非空”。

于 2019-03-13T09:54:44.347 回答