Escribir en FSMC es extremadamente lento

0

Tengo un ARM Cortex M3 STMF32F103VE enlace , y estoy usando una pantalla LCD con controlador ILI9320 enlace

Estoy usando el control de la pantalla LCD usando el FSMC, y estoy tratando de escribir, por ejemplo, 240 * 100 * 16 bits, y toma aproximadamente 0.1 segundos para esa operación y el reloj es de 72Mhz.

for(i=0;i<240*100;i++)
    {
      *(__IO uint16_t *) (Bank1_LCD_D) = frameBuffer[i];
    }

El código para inicializar el FSMC se copia y pega de la nota de la aplicación STMF32 para usar un LCD TFT con FSMC:

#define Bank1_LCD_D    ((uint32_t)0x60020000)    //disp Data ADDR
#define Bank1_LCD_C    ((uint32_t)0x60000000)    //disp Reg ADDR

/**
  * @brief  Configures the FSMC and GPIOs to interface with the SRAM memory.
  *         This function must be called before any write/read operation
  *         on the SRAM.
  * @param  None 
  * @retval : None
  */
void FSMC_LCD_Init(void)
{
  FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
  FSMC_NORSRAMTimingInitTypeDef  p;
  //GPIO_InitTypeDef GPIO_InitStructure; 



  p.FSMC_AddressSetupTime = 0x02;
  p.FSMC_AddressHoldTime = 0x00;
  p.FSMC_DataSetupTime = 0x05;
  p.FSMC_BusTurnAroundDuration = 0x00;
  p.FSMC_CLKDivision = 0x00;
  p.FSMC_DataLatency = 0x00;
  p.FSMC_AccessMode = FSMC_AccessMode_B;

  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
  FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
  FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
  FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
  FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
  FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;      





  FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); 

  /* Enable FSMC Bank1_SRAM Bank */
  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);  
}

y en el código de inicio principal:

solo una llamada a SystemInit(); y RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);

    
pregunta Ahmed Saleh

1 respuesta

2

¿Cómo está transfiriendo los datos al espacio de direcciones del FSMC? ¿Lo estás copiando manualmente desde la memoria RAM? ¿Construyéndolo sobre la marcha y escribiéndolo en el espacio de direcciones?

Para transferirlo en el menor tiempo posible y sin la intervención de la CPU, yo:

  1. Reserve los 48kB de RAM necesarios para almacenar un marco LCD completo (un "buffer de marco").
  2. Use DMA en un bucle continuo para transferir el búfer de cuadros al espacio de direcciones del FSMC.
  3. Actualice manualmente el contenido del búfer de cuadros según sea necesario; La contención de DMA / CPU se resolverá por sí misma.

El mayor problema con este enfoque es que es posible que no tenga 48kB de RAM de repuesto, dado que el STM32F1 tiene como máximo 64kB de RAM.

    
respondido por el markt

Lea otras preguntas en las etiquetas