Написание неблокирующего кода для FSMC LCD

Я пытаюсь связать STM32F1 с ЖК-дисплеем с помощью FSMC. Я пытался сделать анимацию с двойным буфером и скопировать массив кадрового буфера в LCD-буфер. Дело в том, что при написании блокирующего кода, подобного следующему, он потребляет много циклов ожидания ЦП из-за интерфейса и т. д. Есть ли другая идея или обходной путь?

void LCD_Flip(void) {
    //   LCD_SetCursor(0x00, 0x0000);
    static u8 s_chState = 0;

    switch (s_chState) {
    case LCD_FLIP_START:
        s_chState = LCD_FLIP_INIT;
        break;
    case LCD_FLIP_INIT:
        s_chState = LCD_FLIP_REFRESH;
        break;

    case LCD_FLIP_REFRESH:
        LCD_WriteRegister(32, 0);
        LCD_WriteRegister(33, 0);
        LCD_WriteRegister(0x0050,0x00);//GRAM horizontal start position
        LCD_WriteRegister(0x0051,fbWidth - 1);//GRAM horizontal end position
        LCD_WriteRegister(0x0052,0);//Vertical GRAM Start position
        LCD_WriteRegister(0x0053,fbHeight - 1);//Vertical GRAM end position
        LCD_WriteIndex(0x0022);

        for (uint16_t pixel = 0; pixel < fbHeight * fbWidth; pixel++) {

            *(__IO uint16_t *) (Bank1_LCD_D) = frameBuffer[pixel];
        }

        break;
    }

}

Я попытался написать небольшой FSM с простым счетчиком, который используется в основном цикле суперцикла, который сохраняет приращение, пока вы не дойдете до конца буфера кадра, затем вы перестанете копировать, но кажется, что операция настолько быстрая, что ЖК-контроллер может справиться.

Что-то такое:

case LCD_FLIP_REFRESH:
        LCD_WriteRegister(32, 0);
        LCD_WriteRegister(33, 0);
        LCD_WriteRegister(0x0050,0x00);//GRAM horizontal start position
        LCD_WriteRegister(0x0051,fbWidth - 1);//GRAM horizontal end position
        LCD_WriteRegister(0x0052,0);//Vertical GRAM Start position
        LCD_WriteRegister(0x0053,fbHeight - 1);//Vertical GRAM end position
        LCD_WriteIndex(0x0022);



        static int pixel = 0;
           if ( pixel > fbWidth*fbHeight )
            {
                pixel = 0;
            }
        *(__IO uint16_t *) (Bank1_LCD_D) = frameBuffer[pixel];
         pixel++;
        break;
    }

person Ahmed Saleh    schedule 14.06.2014    source источник


Ответы (1)


Используйте контроллер прямого доступа к памяти. Он может скопировать память на периферийный адрес для вас, а затем сгенерировать прерывание, когда это будет сделано.

Это описано в главе 13 справочное руководство STM32F1.

person Community    schedule 14.06.2014
comment
DMA является опцией, но проблема заключается в том, что, согласно примечаниям по применению ЖК-интерфейса STM32, производительность будет не такой высокой. st.com/st-web-ui/static/active/en/resource/technical/document/ с кодом блокировки я получаю 11FPS. - person Ahmed Saleh; 15.06.2014
comment
11 FPS звучит непривычно медленно. Возможно, вы захотите проверить параметры синхронизации FSMC, чтобы убедиться, что вы не используете его на более низкой скорости, чем он может выдержать. - person ; 15.06.2014
comment
Я пробовал все, чтобы проверить время FSMC, и это кажется правильным. Весь код репозитория находится здесь: code.google.com/p/ asteroid-on-stm32/source/browse Я уверен, что он работает на частоте 72 МГц, а FSMC должен работать на частоте 32 МГц. - person Ahmed Saleh; 15.06.2014