【轉】STM32 FSMC總線深入研究


由於CPU與FPGA通信的需要,以及對8080總線的熟悉,首選采用了STM32的FSMC總線,作為片間通信接口。FSMC能達到16MHz的寫入速度,理論上能寫20fps的1024*768的圖片哈哈。(當然實際上是不可能的,就算是DMA傳輸,數據源也跟不上,實際上刷模擬的圖片每秒10fps,刷的很high)當然這不是本篇的要點,這里主要研究STM32的FSMC接口,將速度提升到極限。

1. FSMC協議分析

如下為ILI9325的8080接口的協議

wps_clip_image-31672

CS(片選信號):低電平片選有效,高電平失能(默認為高:失能)

RS(數據寄存器):低電平寫寄存器,高電平寫數據(默認為高:寫數據)FSMC默認為低。。。。

RD(讀信號) :低電平有效,上升沿寫入數據,高電平失能(默認為高,失能)

WR(寫信號) :低電平有效,上升沿寫入數據,高電平失能(默認為高,失能)

FSMC寫SRAM模式如下:

(1)讀操作

wps_clip_image-19780

(2)寫操作

wps_clip_image-29686

wps_clip_image-8205

wps_clip_image-9397

wps_clip_image-32678

HCLK為系統時鍾72MHz

wps_clip_image-26889

綜上,分析出FSMC與8080接口協議異同點

(1)同:CS,RS,RD有效電平都一樣,單個字節的寫入與讀取時序完全一樣

(2)異:

A:8080 默認RS為高,而FSMC默認RS為低

B:8080接口協議能保持CS,RS等有效,連續寫數據,而FSMC以此只能輸出一個數據。

C:8080協議沒有地址線,而FSMC還有地址線,這使得數據輸出不連續。

2. FSMC時序研究

下圖為FSMC寫命令與數據的時序圖,從中根據上圖可以分析出FSMC可以實現16M的數據寫入。FSMC的信號線翻轉非常快,這使得IC或者FPGA時序設計上得非常嚴謹。FSMC最大實現了72MHz(66.7到100MHz之間,實際為72MHz,HCLK)的翻轉速度,這要求外部器件支持那么高的速率。

wps_clip_image-24428

wps_clip_image-16654

寄存器配置(寄存器+數據)

wps_clip_image-30839

連續數據寫入(0xBB:寫數據開始),命令后,RS默認拉低(FSMC和標准不一樣的地方)

wps_clip_image-32061

數據建立很快

wps_clip_image-28180

寫數據,然后默認RS拉低

wps_clip_image-23941

wps_clip_image-19205

整體的時序可模擬為:

task task_writecmd;

input [15:0] cmd;

begin

mcu_cs = 0;

mcu_rs = 0;

mcu_data = cmd;

#20;

mcu_we = 0;

#20;

mcu_we = 1;

#15;

mcu_rs = 1;

mcu_cs = 1;

#20;

end

endtask

task task_writedata;

input [15:0] data;

begin

mcu_cs = 0;

mcu_rs = 1;

mcu_data = data;

#20;

mcu_we = 0;

#20;

mcu_we = 1;

#15;

mcu_rs = 1;

mcu_cs = 1;

#20;

end

endtask

3. FSMC接口初始化

wps_clip_image-2557

根據手冊,相關參數如下表所示。這里我發現所謂最小值還能設置為最小,但實際速度差不多。FSMC協議時間參數如下所示:

wps_clip_image-17879

有人跟我說,手冊是保守的;有人跟我說,在小就是默認值了。我不太理解。感覺速度每提升,應該在小就是默認了。不過,反正我追求速度的極限。

以下是FSMC-SRAM模式下的初始化代碼,分享的同時,希望對你有用。

 

 
/* Private typedef -----------------------------------------------------------*/

typedef struct

{

    vu16 LCD_REG;

    vu16 LCD_RAM;

} LCD_TypeDef;

#define LCD_WriteCmd(cmd) LCD->LCD_REG = cmd

#define LCD_WriteData(data) LCD->LCD_RAM = data

/* LCD is connected to the FSMC_Bank1_NOR/SRAM4 and NE4 is used as ship select signal */
#define LCD_BASE ((u32)(0x60000000 | 0x0C000000))
#define LCD ((LCD_TypeDef *) LCD_BASE)
void LCD_FSMCConfig(void)
{
    FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
    FSMC_NORSRAMTimingInitTypeDef p;
    /*-- FSMC Configuration ------------------------------------------------------*/
    /*----------------------- SRAM Bank 4 ----------------------------------------*/
    /* FSMC_Bank1_NORSRAM4 configuration */
    //標准
    // p.FSMC_AddressSetupTime = 1;
    // p.FSMC_AddressHoldTime = 2;
    // p.FSMC_DataSetupTime = 2;
    // p.FSMC_BusTurnAroundDuration = 1;
    // p.FSMC_CLKDivision = 1;
    // p.FSMC_DataLatency = 2;
    //超快
    p.FSMC_AddressSetupTime = 0;
    p.FSMC_AddressHoldTime = 0;
    p.FSMC_DataSetupTime = 1;
    p.FSMC_BusTurnAroundDuration = 0;
    p.FSMC_CLKDivision = 0;
    p.FSMC_DataLatency = 0;
    p.FSMC_AccessMode = FSMC_AccessMode_A;
    /* Color LCD configuration ------------------------------------
    LCD configured as follow:
    - Data/Address MUX = Disable
    - Memory Type = SRAM
    - Data Width = 16bit
    - Write Operation = Enable
    - Extended Mode = Enable
    - Asynchronous Wait = Disable */
    FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;
    FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
    FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
    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_AsynchronousWait = FSMC_AsynchronousWait_Disable; //2.0
    FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
    FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
    FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
    FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
    /* BANK 4 (of NOR/SRAM Bank 1~4) is enabled */
    FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM