본문 바로가기

[ST_MICRO]/STM32F7

STM32F7 EVM FMC 테스트 - TFT LCD 제어 (STM32F7 에서 FMC출력 문제발생)

STM32F7 EVM FMC 테스트 - TFT LCD 제어 (STM32F7 에서 FMC출력 문제발생)




STM32F7 EVM 보드는 100핀 페키지의 STM32F767이 실장되어 있다. 100핀 페키지에서는 FMC Data/Address 16, RD, WR, NE 을 사용할 수 있어 버스 방식의 LCD 제어에 적합하다.

기존에 제작한 LCD 모듈중 버스제어 방식의 LCD모듈을 표준 핀맵으로 제작해 두었기 때문에 이 모듈로 STM32F7의 FMC를 이용한 TFT LCD를 테스트 해 보았다.




STM32F7 EVM보드의 TFT LCD는 CS -> NE1, RS->A16에 연결에 되어 있다.









STM32F7 FMC 테스트 코드 작성

STM32CubeMX 에서 FMC를 아래와 같이 핀맵에 맞게 설정 하면 된다.





STM32CubeMX에서 코드 생성을 하면 아래와 같이 기본 초기화 코드가 생성된다.



static void MX_FMC_Init(void)
{
  /* USER CODE BEGIN FMC_Init 0 */
  /* USER CODE END FMC_Init 0 */
  FMC_NORSRAM_TimingTypeDef Timing = {0};
  /* USER CODE BEGIN FMC_Init 1 */
  /* USER CODE END FMC_Init 1 */
  /** Perform the SRAM1 memory initialization sequence
  */
  hsram1.Instance = FMC_NORSRAM_DEVICE;
  hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
  /* hsram1.Init */
  hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
  hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
  hsram1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
  hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
  hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
  hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
  hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
  hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
  hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
  hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
  hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
  hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
  hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
  hsram1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
  hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
  /* Timing */
  Timing.AddressSetupTime = 25;
  Timing.AddressHoldTime = 15;
  Timing.DataSetupTime = 50;//50;//255;
  Timing.BusTurnAroundDuration = 1;//2;//15;
  Timing.CLKDivision = 2;
  Timing.DataLatency = 2;
  Timing.AccessMode = FMC_ACCESS_MODE_A;
  /* ExtTiming */
  if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
  {
    Error_Handler( );
  }
  /* USER CODE BEGIN FMC_Init 2 */
  /* USER CODE END FMC_Init 2 */
}





기존 STM32F439 FMC테스트 예제와 동일한 코드를 구동 시켰는데...

동작을 하지 않는다.


뭔가 이상하다. STM32F7에서 뭐가 달라졌나?



일단 LCD기본 테스트 코드로 파형이 정상적으로 출력이 되는지 확인 해 보자


CMD출력 할때 RS(A16)가 low가 되는것을 확인 할 수 있다.


       while(1)
       {
              Lcd_Cmd(0x0200);Lcd_Data(0x0000);        //Horizontal Address Set
              Lcd_Cmd(0x0201);Lcd_Data(0x0000);        //Vertical Address Set
              Delay(delay_time);
       }



하지만 4번의 출력이 있어야 하는 WR신호가 2번 밖에 출력되지 않는다.




타이밍 이슈 인가? 하지만 타이밍을 짧게 해도 2번 밖에 출력이 되지 않는다.






FMC 출력 할 때 딜레이를 좀 주면 어떻게 될까?


#define _LCD_TIME_DELAY                                60
#define Lcd_Cmd(reg)                    _LCD_DATA(0x0000) = reg;Delay_ns(_LCD_TIME_DELAY);

#define Lcd_Data(dat)                   _LCD_DATA(0x10000) = dat;Delay_ns(_LCD_TIME_DELAY);



정상 동작은 하지만 속도가 STM32F4에 비해 4배 이상 느리다.

딜레이 타임을 줄이면 정상 동작을 하지 않는다.







STM32F7 FMC HAL 코드를 사용해 보면 어떨까?


void Lcd_Cmd(unsigned int reg)

{
       uint16_t buf = reg;
       HAL_SRAM_Write_16b(&hsram1, (uint32_t*)(LCD_BANK_ADDR+0), &buf, 1);
}

void Lcd_Data(unsigned int reg)
{
       uint16_t buf = reg;
       HAL_SRAM_Write_16b(&hsram1, (uint32_t*)(LCD_BANK_ADDR+0x20000), &buf, 1);

}




하지만 HAL코드를 이용하면 동작은 하지만 속도가 너무 느리다.

타이밍을 짧게 해도 1프래임 출력 시간이 44ms나 소요된다.



결론적으로 보면 출력 후 바로 출력 하는것에는 문제가 있는것 같다.

무시 해 버리는듯..


속도는 느리지만 SD카드의 BMP출력하면 STM32F7에서 TFT-LCD에 이미지 출력은 되고 있다. 

하지만 속도 문제는 해결해야 할것 같다.