1. 程式人生 > >STM32學習之路-FSMC與LCD

STM32學習之路-FSMC與LCD

哎..這些天忙著準備四六級,整天呆在自習室,都快傻了,而且特別累,回來還沒心情搞STM32,趁今天有點心情,趕快把前面的東西給補上吧

以下的資料都是從別的大蝦那裡偷來的.在此謝謝人家的分析.讓我們站在巨人的肩膀上學習.

開發板:奮鬥V5

FSMC全稱“靜態儲存器控制器”。

使用FSMC控制器後,可以把FSMC提供的FSMC_A[25:0]作為地址線,而把FSMC提供的FSMC_D[15:0]作為資料匯流排。

(1)當儲存資料設為8位時,(FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b)

 地址各位對應FSMC_A[25:0],資料位對應FSMC_D[7:0]


(2)當儲存資料設為16位時,(FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b)

地址各位對應FSMC_A[24:0],資料位對應FSMC_D[15:0]

FSMC 包括4個模組:

(1)AHB介面(包括FSMC配置暫存器)

(2)NOR快閃記憶體和PSRAM控制器(驅動LCD的時候LCD就好像一個PSRAM的裡面只有2個16位的儲存空間,一個是DATA RAM 一個是CMD RAM)

(3)NAND快閃記憶體和PC卡控制器

(4)外部裝置介面

:FSMC可以請求AHB進行資料寬度的操作。如果AHB操作的資料寬度大於外部裝置(NOR或NAND或LCD)的寬度,此時FSMC將AHB操作分割成幾個連續的較小的資料寬度,以適應外部裝置的資料寬度。



FSMC對外部裝置的地址映像從0x6000 0000開始,到0x9FFF FFFF結束,共分4個地址塊,每個地址塊256M位元組。可以看出,每個地址塊又分為4個分地址塊,大小64M。對NOR的地址映像來說,我們可以通過選擇HADDR[27:26]來確定當前使用的是哪個64M的分地址塊,如下頁表格。而這四個分儲存塊的片選,則使用NE[4:1]來選擇。資料線/地址線/控制線是共享的。

NE1 ->Bank1   NE2->Bank2  NE3->Bank3  NE4->Bank4

若 NE1 連線, 則


每小塊NOR/PSRAM 64M

第一塊:6000 0000h--63ff ffffh (DATA長度為8位情況下,由地址線FSMC_A[25:0]決定;DATA長度為16位情況下,由地址線FSMC_A[24:0]決定)


第二塊:6400 0000h--67ff ffffh

第二塊:6800 0000h--6bff ffffh

第三塊:6c00 0000h--6fff ffffh

注:這裡的HADDR是需要轉換到外部裝置的內部AHB地址線,每個地址對應一個位元組單元。因此,若外部裝置的地址寬度是8位的,則HADDR[25:0]與STM32的CPU引腳FSMC_A[25:0]一一對應,最大可以訪問64M位元組的空間。若外部裝置的地址寬度是16位的,則是HADDR[25:1]與STM32的CPU引腳FSMC_A[24:0]一一對應。在應用的時候,可以將FSMC_A匯流排連線到儲存器或其他外設的地址匯流排引腳上.

例:STM32F10XX FCMS控制LCD的驅動

FSMC提供了所有的LCD控制器的訊號:

FSMC_D[16:0]

FSMC NEx:分配給NOR的256M,再分為4個區,每個區用來分配一個外設,這四個外設的片選分為是NE1-NE4,對應的引腳為:PD7—NE1,PG9—NE2,PG10-NE3,PG12-NE4

FSMC NOE:輸出使能,連線LCD的RD腳。

FSMC NWE:寫使能,連線LCD的RW腳。

FSMC Ax:用在LCD顯示RAM和暫存器之間進行選擇的地址線,即該線用於選擇LCD的RS腳,該線可用地址線的任意一根線,範圍:FSMC_A[25:0]。

注:RS = 0時,表示讀寫暫存器;RS = 1表示讀寫資料RAM。

舉例1:選擇NOR的第一個儲存區,並且使用FSMC_A16來控制LCD的RS引腳,則我們訪問LCD顯示RAM的基址為0x6002 0000,訪問LCD暫存器的地址為:0x6000 0000。因為資料長度為16bit,所以FSMC_A[24:0]對應HADDR[25:1]  所以顯示RAM的基址=0x60000000+2^16*2=0x60000000+0x2 0000=0x60020000

舉例2:選擇NOR的第四個儲存區,使用FSMC_A0控制LCD的RS腳,則訪問LCD顯示RAM的基址為0x6c00 0002,訪問LCD暫存器的地址為:0x6c00 0000。

FSMC_D[15:0],連16bit資料線;FSMC_NE1,連片選:只有bank1可用

FSMC NOE:輸出使能

FSMC NEW:FSMC寫使能

FSMC Ax:連線RS,可用範圍FSMC_A[24:0]

一般使用模式B來做LCD的介面控制,不適用外擴模式。並且讀寫操作的時序一樣。此種情況下,我們需要使用三個引數:ADDSET,DATAST,ADDHOLD。這三個引數在位域FSMC_TCRx中設定

下面是奮鬥給的例子

void FSMC_LCD_Init(void)
{
  FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
  FSMC_NORSRAMTimingInitTypeDef  p;	
  GPIO_InitTypeDef GPIO_InitStructure;	    
  //使能FSMC外設時鐘
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);   
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
                         RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE , ENABLE);  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; 			  //LCD背光控制
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOD, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ; 	 		  //LCD復位
  GPIO_Init(GPIOE, &GPIO_InitStructure);   	   	
  // 複用埠為FSMC介面 FSMC-D0--D15
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
                                GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 | 
                                GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOD, &GPIO_InitStructure);   
   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | 
                                GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | 
                                GPIO_Pin_15;
  GPIO_Init(GPIOE, &GPIO_InitStructure);    
  //FSMC NE1  LCD片選
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; 
  GPIO_Init(GPIOD, &GPIO_InitStructure);
  
  //FSMC RS---LCD指令 指令/資料	切換
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ; 
  GPIO_Init(GPIOD, &GPIO_InitStructure); 	
  GPIO_SetBits(GPIOD, GPIO_Pin_13);			           //LCD背光開啟
  
  
  //FSMC介面特性配置
  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);  
}
其他的沒什麼好說的,看看這兩個東西
 p.FSMC_AddressSetupTime = 0x02;
<pre name="code" class="cpp" style="color: rgb(75, 75, 75); font-size: 13px; line-height: 20px;"> p.FSMC_DataSetupTime = 0x05;
根據下面的公式來算,雖然NOR FLASH晶片不一樣但是計算公式應該是一樣的 


還有就是一些關於FSMC與LCD連線的問題

謝謝人家的分析!