Как ускорить прокрутку букв на светодиодной матрице Arduino ?

////********************************************* ************************************
////----------------1.Среда разработки: Arduino IDE или Visual Studio 2010----------------
////---------------- 2. Используйте модель макетной платы: Arduino UNO ----------------
////---------------- 3. MCU использует кварцевый генератор: 16M ----------------
////----------------4.Название магазина: Университетский студенческий электронный магазин/Xiaoqiang Electronic Design----------------
////----------------5. URL Taobao: Ilovemcu.taobao.com ----------------
////---------------- 52dpj.taobao.com ----------------
////----------------6.Автор: Таинственная Комната Сокровищ----------------
////****************************************************** ** ****************************

#include <Arduino.h>

// Конфигурация ввода-вывода
#define LEDARRAY_D 5
#define LEDARRAY_C 6
#define LEDARRAY_B 7
#define LEDARRAY_A 8
#define LEDARRAY_G 9
#define LEDARRAY_DI 10
#define LEDARRAY_CLK 11
#define LEDARRAY_LAT 12

#define led 13


#define Display_Num_Word 2              //Количество китайских иероглифов, которые может отображать ЖК-дисплей

unsigned char Display_Buffer[8];
unsigned char Display_Swap_Buffer[Display_Num_Word][32]={0};                    //показать буфер
bool Shift_Bit = 0;
bool Flag_Shift = 0;
unsigned char Timer0_Count = 0;
unsigned char temp = 0x80;
unsigned char Shift_Count = 0;
unsigned char Display_Word_Count = 0;

#define Num_Of_Word 33
const unsigned char Word[Num_Of_Word][32] = 
{
0xFF,0xFF,0xFF,0x07,0xBB,0xBB,0xBB,0x87,0xBB,0xBD,0xBD,0xBD,0xBB,0x07,0xFF,0xFF,/*"B",0*/
0xFF,0xFF,0xFF,0xC7,0xBB,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0xBB,0xC7,0xFF,0xFF,/*"O"*/
0xFF,0xFF,0xFF,0x83,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0x83,0xFF,0xFF,/*"I",0*/
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
0xFF,0xFF,0xFF,0xC1,0xBD,0xBD,0xBF,0xDF,0xE7,0xFB,0xFD,0xBD,0xBD,0x83,0xFF,0xFF,/*"S"*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x03,0xBD,0xBD,0xBD,0x83,0xB7,0xB7,0xBB,0xBB,0xBD,0x1C,0xFF,0xFF,/*"R",0*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x83,0xBD,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBD,0x83,0xFF,0xFF,
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x03,0xBD,0xBD,0xBD,0x83,0xB7,0xB7,0xBB,0xBB,0xBD,0x1C,0xFF,0xFF,/*"R",0*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xC1,0xBD,0xBD,0xBF,0xDF,0xE7,0xFB,0xFD,0xBD,0xBD,0x83,0xFF,0xFF,/*"S"*/
0xFF,0xFF,0xFF,0x83,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0x83,0xFF,0xFF,/*"I",0*/
0xFF,0xFF,0xFF,0xC3,0xBB,0xBB,0x7F,0x7F,0x7F,0x71,0x7B,0xBB,0xBB,0xC7,0xFF,0xFF,/*"G",0*/
0xFF,0xFF,0xFF,0xBF,0x83,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xC7,0xBB,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0xBB,0xC7,0xFF,0xFF,/*"O"*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x01,0x6D,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xC7,0xFF,0xFF,/*"T",0*/
0xFF,0xFF,0xFF,0x18,0xBD,0xBD,0xBD,0xBD,0x81,0xBD,0xBD,0xBD,0xBD,0x18,0xFF,0xFF,/*"H",0*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x07,0xBB,0xBB,0xBB,0x87,0xBB,0xBD,0xBD,0xBD,0xBB,0x07,0xFF,0xFF,/*"B",0*/
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x83,0xBD,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBD,0x83,0xFF,0xFF,
0xFF,0xFF,0xFF,0xBE,0xBD,0xBB,0xB7,0xB7,0xBB,0xBB,0xBD,0xBD,0xBE,0xBE,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x07,0xBB,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBB,0x07,0xFF,0xFF,/*"D",0*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x01,0x6D,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xC7,0xFF,0xFF,/*"T",0*/
0xFF,0xFF,0xFF,0x18,0xBD,0xBD,0xBD,0xBD,0x81,0xBD,0xBD,0xBD,0xBD,0x18,0xFF,0xFF,/*"H",0*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xDF,0xD7,0xB7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xBE,0xBD,0xBB,0xB7,0xB7,0xBB,0xBB,0xBD,0xBD,0xBE,0xBE,0xFF,0xFF,
0xFF,0xFF,0xFF,0x83,0xBD,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBD,0x83,0xFF,0xFF,
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xFF,0xFF,
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
};
void setup()
{
    pinMode(LEDARRAY_D, OUTPUT); 
    pinMode(LEDARRAY_C, OUTPUT);
    pinMode(LEDARRAY_B, OUTPUT);
    pinMode(LEDARRAY_A, OUTPUT);
    pinMode(LEDARRAY_G, OUTPUT);
    pinMode(LEDARRAY_DI, OUTPUT);
    pinMode(LEDARRAY_CLK, OUTPUT);
    pinMode(LEDARRAY_LAT, OUTPUT);

    Clear_Display();
}

void loop()
{
    unsigned int i;
    for(i = 0;i<30;i++)
    {
        Display(Display_Swap_Buffer);
    }
    Display_Word_Count = Shift_Count/16;                //计算当前显示第几个字
    Calc_Shift();                                       

    Shift_Count++;

    if(Shift_Count == (Num_Of_Word+Display_Num_Word)*16 )               //Количество смен
    {
        Shift_Count = 0;                
    }   
}

//*************************************************** ** *************
// очистить буфер
//*************************************************** ** *************
void Clear_Display()
{
    unsigned char i,j;
    for(j = 0 ; j < Display_Num_Word; j++)
    {
        for(i = 0 ; i < 32 ;i++)
        {
            Display_Swap_Buffer[j][i] = 0xff;               //0=отображать 1=не отображать
        }
    }
}

//*************************************************** ** *************
//Рассчитываем движущиеся данные, которые есть в буфере
//*************************************************** ** *************
void Calc_Shift()
{
    unsigned char i;

    for(i = 0;i < 16;i++)
    {
        if((Display_Swap_Buffer[0][16+i]&0x80) == 0)                                    // Сдвигаем первый байт каждой строки
        {
            Display_Swap_Buffer[0][i] = (Display_Swap_Buffer[0][i] << 1)&0xfe;          //Очистить младший бит
        }
        else
        {
            Display_Swap_Buffer[0][i] = (Display_Swap_Buffer[0][i] << 1)|0x01;          // Самая нижняя позиция — 1
        }

        if((Display_Swap_Buffer[1][i]&0x80) == 0)                                   // Сдвигаем второй байт каждой строки
        {
            Display_Swap_Buffer[0][16+i] = (Display_Swap_Buffer[0][16+i] << 1)&0xfe;            //Очистить младший бит
        }
        else
        {
            Display_Swap_Buffer[0][16+i] = (Display_Swap_Buffer[0][16+i] << 1)|0x01;            //Нижняя позиция 1
        }

        if((Display_Swap_Buffer[1][16+i]&0x80) == 0)                                    // Сдвигаем третий байт каждой строки
        {
            Display_Swap_Buffer[1][i] = (Display_Swap_Buffer[1][i] << 1)&0xfe;          //最低位清零
        }
        else
        {
            Display_Swap_Buffer[1][i] = (Display_Swap_Buffer[1][i] << 1)|0x01;          //最低位置一
        }

        if(Shift_Count%16 < 8 && Display_Word_Count < Num_Of_Word)
        {
            Shift_Bit = Word[Display_Word_Count][i]&temp;
        }
        else if(Shift_Count%16 < 16 && Display_Word_Count < Num_Of_Word)
        {
            Shift_Bit = Word[Display_Word_Count][16+i]&temp;
        }
        else
        {
            Shift_Bit = 1;                      // сдвигаем слово из буфера
        }

        if( Shift_Bit == 0)                                                     //Последние 8 бит сдвигаются
        {
            Display_Swap_Buffer[1][16+i] = (Display_Swap_Buffer[1][16+i] << 1)&0xfe;        //Очистить младший бит
        }
        else
        {
            Shift_Bit = 1;
            Display_Swap_Buffer[1][16+i] = (Display_Swap_Buffer[1][16+i] << 1)|0x01;        // Самая нижняя позиция
        }

    }
    temp = (temp>>1)&0x7f;
    if(temp == 0x00)
    {
        temp = 0x80;
    }
}
//*************************************************** ** *************
//число — количество слов dat[][32] — название глифа
//*************************************************** ** *************
void Display(const unsigned char dat[][32])                 
{
    unsigned char i;

    for( i = 0 ; i < 16 ; i++ )
    {
        digitalWrite(LEDARRAY_G, HIGH);     // Закрываем дисплей при обновлении данных. После обновления данных откройте 138 строку дисплея. Предотвратите ореолы.

        Display_Buffer[0] = dat[0][i];      
        Display_Buffer[1] = dat[0][i+16];
        Display_Buffer[2] = dat[1][i];
        Display_Buffer[3] = dat[1][i+16];

    Display_Buffer[4] = dat[2][i];
    Display_Buffer[5] = dat[2][i+16];
    Display_Buffer[6] = dat[3][i];
    Display_Buffer[7] = dat[3][i+16];

    Send(Display_Buffer[7]);
    Send(Display_Buffer[6]);
    Send(Display_Buffer[5]);
    Send(Display_Buffer[4]);

        Send(Display_Buffer[3]);
        Send(Display_Buffer[2]);
        Send(Display_Buffer[1]);
        Send(Display_Buffer[0]);

        digitalWrite(LEDARRAY_LAT, HIGH);                   //锁存数据
        delayMicroseconds(0.1);

        digitalWrite(LEDARRAY_LAT, LOW);
        delayMicroseconds(0.1);

        Scan_Line(i);                       //Выбираем строку i

        digitalWrite(LEDARRAY_G, LOW);

        delayMicroseconds(100);;        //Задержка на некоторое время, чтобы светодиод загорелся.
    }   
}

//*************************************************** ** ****
// сканируем строку
//*************************************************** ** ****
void Scan_Line( unsigned char m)
{   
    switch(m)
    {
        case 0:         
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);                    
            break;
        case 1:                 
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);       
            break;
        case 2:                 
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);       
            break;
        case 3:                 
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);      
            break;
        case 4:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);       
            break;
        case 5:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);      
            break;
        case 6:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);      
            break;
        case 7:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);         
            break;
        case 8:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);       
            break;
        case 9:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);      
            break;  
        case 10:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);      
            break;
        case 11:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);         
            break;
        case 12:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);      
            break;
        case 13:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);         
            break;
        case 14:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);         
            break;
        case 15:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);        
            break;
        default : break;    
    }
}

//*************************************************** ****
//发送数据
//*************************************************** ****
void Send( unsigned char dat)
{
    unsigned char i;
    digitalWrite(LEDARRAY_CLK, LOW);
    delayMicroseconds(0);;  
    digitalWrite(LEDARRAY_LAT, LOW);
    delayMicroseconds(0);;

    for( i = 0 ; i < 8 ; i++ )
    {
        if( dat&0x01 )
        {
            digitalWrite(LEDARRAY_DI, HIGH);    
        }
        else
        {
            digitalWrite(LEDARRAY_DI, LOW);
        }


        digitalWrite(LEDARRAY_CLK, HIGH);               // 上升沿发送数据
            delayMicroseconds(0);;
        digitalWrite(LEDARRAY_CLK, LOW);
            delayMicroseconds(0);;      
        dat >>= 1;

    }           
}

, 👍1

Обсуждение

уменьшите любые задержки настолько, насколько это возможно - если вы сократили их настолько, насколько это возможно, то вы достигли максимальной скорости, которую позволяет ваш код - если это недостаточно быстро, используйте более быстрый MCU, или, возможно, ваш код может быть написан лучше, но это неизвестно, так как код почти не читается в его нынешнем виде, @Jaromanda X

Начните с измерения времени обновления (в микросекундах). После этого вы можете подумать об оптимизации, например, о более быстрой цифровой записи, прямом доступе к порту, SPI и т. д., @Mikael Patel


2 ответа


1

У вас есть 30-кратный цикл, вызывающий Display(), который внутри 16-кратного цикла вызывает восемь вызовов Send(), которые внутри 8-кратного цикла выполняют три цифровых записи, каждая из которых занимает не менее 2 мкс для завершения. Как минимум, только digitalWrite занимает 180 мс за один проход.

Используйте SPI, если возможно, или выполните поиск в Google по запросу "arduino speed up digitalWrite" , здесь есть хорошая статья о этот.

Кроме того, развертывание цикла 8x внутри Send() может сэкономить немного мс:

   if( dat&0x01 ) digitalWrite(LEDARRAY_DI, HIGH);    
   else digitalWrite(LEDARRAY_DI, LOW);
   digitalWrite(LEDARRAY_CLK, HIGH);               // 上升沿发送数据
   delayMicroseconds(0);;
   digitalWrite(LEDARRAY_CLK, LOW);
   delayMicroseconds(0);   
   if( dat&0x02 ) digitalWrite(LEDARRAY_DI, HIGH);    
   else digitalWrite(LEDARRAY_DI, LOW);
   digitalWrite(LEDARRAY_CLK, HIGH);               // 上升沿发送数据
   delayMicroseconds(0);;
   digitalWrite(LEDARRAY_CLK, LOW);
   delayMicroseconds(0);  
   ........      
   if( dat&0x80 ) digitalWrite(LEDARRAY_DI, HIGH);    
   else digitalWrite(LEDARRAY_DI, LOW);
   digitalWrite(LEDARRAY_CLK, HIGH);               // 上升沿发送数据
   delayMicroseconds(0);;
   digitalWrite(LEDARRAY_CLK, LOW);
   delayMicroseconds(0);    
,

0

Эти строки

    digitalWrite(LEDARRAY_LAT, HIGH);                   //Зафиксировать данные
    delayMicroseconds(0.1);

    digitalWrite(LEDARRAY_LAT, LOW);
    delayMicroseconds(0.1);

    Scan_Line(i);                       // Выбираем строку i

    digitalWrite(LEDARRAY_G, LOW);

    delayMicroseconds(100);;        //Задержка на некоторое время, чтобы светодиод загорелся.

Уменьшите время в последнем. Я не думаю, что delayMicroseconds(0.1); делает что-либо, равно как и delayMicroseconds(0); не найдено где-либо еще.

Я вижу, что отдельные пины контролируются

#define LEDARRAY_D 5
#define LEDARRAY_C 6
#define LEDARRAY_B 7
#define LEDARRAY_A 8
#define LEDARRAY_G 9
#define LEDARRAY_DI 10
#define LEDARRAY_CLK 11
#define LEDARRAY_LAT 12

Вы не говорите, что это за аппаратное обеспечение, но держу пари, что вы заменяете запись отдельных выводов последовательной передачей данных в сдвиговый регистр с тактовой частотой SPI 8 МГц, чтобы ускорить процесс. Или, если у вас есть плата 1284P или 2560, вы также можете выполнять запись портов.

,