首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何设置fast STM32 F4 FSMC以控制STM32F4Discovery板上的显示?

如何设置fast STM32 F4 FSMC以控制STM32F4Discovery板上的显示?
EN

Stack Overflow用户
提问于 2017-01-23 05:03:04
回答 3查看 9K关注 0票数 2

我正在将ILI9341显示控制器连接到STM32F407vg微控制器(STM32发现板)。显示器通过16位并行数据总线连接到STM32。

为了实现高数据率,我使用了STM32的FSMC。FSMC配置为静态RAM控制器。我不使用芯片选择或读取。接口工作,我可以发送数据到显示器,但它很慢。

我尝试使用for循环写入LCD,但也尝试在内存到内存模式下使用DMA。我尝试过从闪存写入数据,也尝试从RAM写入数据。优化各种DMA设置。所有这些改变根本没有影响速度。因此,对我来说,这似乎是一个巨大的瓶颈。

下图显示了16位字传输的测量结果(仅测量了前8行)。如您所见,显示器的WR线切换频率仅为558 the。

下图显示了参考手册中说明的FSMC时序。在我的测量中,NWE (写启用)是WRA16D/C

ADDSET和DATAST采用HCLK (AHB时钟)周期。AHB时钟配置为最大速度为168 AHB。ADDSET和DATAST分别设置为0和1,因此我将速度配置为84 are。我不期望达到84 the,因为DMA控制器比较慢(见下文)。但我至少希望能达到DMA速度。

使用ST的HAL v1.6.0.0库,我将时钟设置为最大速度:

代码语言:javascript
复制
void SystemClock_Config(void)
{

RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;

__HAL_RCC_PWR_CLK_ENABLE();

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 16;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
  Error_Handler();
}

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                            |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
  Error_Handler();
}

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

我初始化FSMC:

代码语言:javascript
复制
void init_fsmc(void){
SRAM_HandleTypeDef sram_init_struct;
FSMC_NORSRAM_TimingTypeDef fsmc_norsram_timing_struct = {0};

sram_init_struct.Instance = FSMC_NORSRAM_DEVICE;
sram_init_struct.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;

fsmc_norsram_timing_struct.AddressSetupTime       = 0;
fsmc_norsram_timing_struct.AddressHoldTime        = 1; // n/a for SRAM mode A
fsmc_norsram_timing_struct.DataSetupTime          = 1;
fsmc_norsram_timing_struct.BusTurnAroundDuration  = 0; 
fsmc_norsram_timing_struct.CLKDivision            = 2; // n/a for SRAM mode A
fsmc_norsram_timing_struct.DataLatency            = 2; // n/a for SRAM mode A
fsmc_norsram_timing_struct.AccessMode             = FSMC_ACCESS_MODE_A;

sram_init_struct.Init.NSBank             = FSMC_NORSRAM_BANK4;
sram_init_struct.Init.DataAddressMux     = FSMC_DATA_ADDRESS_MUX_DISABLE;
sram_init_struct.Init.MemoryType         = FSMC_MEMORY_TYPE_SRAM;
sram_init_struct.Init.MemoryDataWidth    = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
sram_init_struct.Init.BurstAccessMode    = FSMC_BURST_ACCESS_MODE_DISABLE;
sram_init_struct.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
sram_init_struct.Init.WrapMode           = FSMC_WRAP_MODE_DISABLE;
sram_init_struct.Init.WaitSignalActive   = FSMC_WAIT_TIMING_BEFORE_WS;
sram_init_struct.Init.WriteOperation     = FSMC_WRITE_OPERATION_ENABLE;
sram_init_struct.Init.WaitSignal         = FSMC_WAIT_SIGNAL_DISABLE;
sram_init_struct.Init.ExtendedMode       = FSMC_EXTENDED_MODE_DISABLE; // maybe enable?
sram_init_struct.Init.AsynchronousWait   = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
sram_init_struct.Init.WriteBurst         = FSMC_WRITE_BURST_DISABLE;

__HAL_RCC_FSMC_CLK_ENABLE();

HAL_SRAM_Init(&sram_init_struct, &fsmc_norsram_timing_struct, &fsmc_norsram_timing_struct);
}

我配置DMA:

代码语言:javascript
复制
void init_dma(void){
  __HAL_RCC_DMA2_CLK_ENABLE();

  /*##-2- Select the DMA functional Parameters ###############################*/
  dma_handle.Init.Channel = DMA_CHANNEL_0;
  dma_handle.Init.Direction = DMA_MEMORY_TO_MEMORY;
  dma_handle.Init.PeriphInc = DMA_PINC_DISABLE;               /* Peripheral increment mode */
  dma_handle.Init.MemInc = DMA_MINC_DISABLE;                  /* Memory increment mode */
  dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; /* Peripheral data alignment */
  dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;    /* memory data alignment */
  dma_handle.Init.Mode = DMA_NORMAL;                         /* Normal DMA mode */
  dma_handle.Init.Priority = DMA_PRIORITY_HIGH;              /* priority level */
  dma_handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;           /* FIFO mode disabled */
  dma_handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  dma_handle.Init.MemBurst = DMA_MBURST_SINGLE;              /* Memory burst */
  dma_handle.Init.PeriphBurst = DMA_PBURST_SINGLE;           /* Peripheral burst */

  dma_handle.Instance = DMA2_Stream0;

  if(HAL_DMA_Init(&dma_handle) != HAL_OK)
  {
    // @todo proper error handling.
    return;
  }

  HAL_DMA_RegisterCallback(&dma_handle, HAL_DMA_XFER_CPLT_CB_ID, dma_transfer_complete);
  // @todo proper error handling
  HAL_DMA_RegisterCallback(&dma_handle, HAL_DMA_XFER_ERROR_CB_ID, dma_transfer_error);

  /*##-6- Configure NVIC for DMA transfer complete/error interrupts ##########*/
  /* Set Interrupt Group Priority */
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 1, 0);

  /* Enable the DMA STREAM global Interrupt */
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}

下面是我开始事务的方式:

代码语言:javascript
复制
HAL_DMA_Start_IT(&dma_handle, (uint32_t)&data_buffer, (uint32_t)&LCD_RAM, pixelCount);

当我使用这种DMA配置执行从SRAM1到SRAM2的DMA传输时,我实现了~38 this的传输速度。这就是我在FSMC上期望的速度。

是什么阻碍了FSMC的发展?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-01-25 04:30:46

我发现了一段非常短的代码here,它展示了如何仅使用CMSIS来配置FSMC。

使用一行HAL代码来激活时钟,这段代码如下所示:

代码语言:javascript
复制
__HAL_RCC_FSMC_CLK_ENABLE();

int FSMC_Bank = 0;
FSMC_Bank1->BTCR[FSMC_Bank+1] = FSMC_BTR1_ADDSET_1 | FSMC_BTR1_DATAST_1;

// Bank1 NOR/SRAM control register configuration
FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;

我尝试了这个代码,现在我达到了大约27 this的速度。这在我预期的范围内。

现在我将继续使用这段代码,根本原因分析将在以后进行。

顺便说一句,如果您在STM32F4发现板上使用FSMC卡,请取消焊接电阻R50,因为它连接到FSMC的NWE引脚,并且使用此0欧姆电阻连接到STM32的电路有一个上拉,这将使传输失真。

票数 1
EN

Stack Overflow用户

发布于 2018-11-08 19:45:34

代码语言:javascript
复制
"sram_init_struct.Init.NSBank             = FSMC_NORSRAM_BANK4"

银行号码可能有误,您可以尝试使用FSMC_NORSRAM_BANK1更换FSMC_NORSRAM_BANK4。

票数 0
EN

Stack Overflow用户

发布于 2017-11-06 15:36:37

也许你应该使用HSE而不是HSI:

代码语言:javascript
复制
  /* Enable HSE Oscillator and activate PLL with HSE as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8; // 8MHz crystal frequency
  RCC_OscInitStruct.PLL.PLLN = 336; // 2*168, 168MHz PLL_Freq
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

问候

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41796128

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档