STM32 ----小談FSMC RS選擇

STM32FMSC LCD難點解析:

以下是網上和自己整理的:感覺應該可以把STM32 ----FSMCLCD中的關鍵RS說清楚~

----------------------------------------------------------------------------------------------------------------------

 

 

第一個角度理解STM32FSMC(其實其他芯片基本都有類似的總線功能),FSMC的好處就是你一旦設置好之後,WR()RD()DB0-DB15這些控制線和數據線,

都是FSMC自動控制的。打個比方,當你在程序中寫到:

 

*(volatile unsigned short int*)(0x60000000)=val;

 

那麼FSMC就會自動執行一個寫的操作,其對應的主控芯片的WERD這些腳,就會呈現出寫的時序出來(即WE=0,RD=1),數據val的值也

會通過DB0-15自動呈現出來(FSMC-D0:FSMC-D15=val )。地址0x60000000會被呈現在數據線上(即A0-A25=0,地址線的對應最麻煩,要根據具體情況來,好好看看FSMC手冊)。

 

那麼在硬件上面,我們需要做的,僅僅是MCULCD控制芯片的連接關係:

 

WE-WR,均爲低電平有效

RD-RD,均爲低電平有效

FSMC-D0-15LCD DB0-15

FSMC_NE1--CSPD7

 

連接好之後,讀寫時序都會被FSMC自動完成。但是還有一個很關鍵的問題,就是RS沒有接因爲在FSMC裏面,根本就沒有對應RS。怎麼辦呢?這個時候,有一個好方法,就是用某一根地址線來接RS。比如我們選擇了A16這根地址線來接,那麼當我們要寫寄

存器的時候,我們需要RS,也就是A16(RS爲高)置高。軟件中怎麼做呢?也就是將FSMC要寫的地址改成0x60020000如下:

 

 

*(volatile unsigned short int*)(0x60020000)=val;

 

這個時候,A16在執行其他FSMC的同時會被拉高,因爲A0-A18要呈現出地址0x600200000x60020000裏面的Bit17=1,就會導致A161

當要讀數據時,地址由0x60020000改爲了0x60000000,這個時候A16就爲0了。

 

那麼有朋友就會有疑問,第一,爲什麼地址是0x6xxxxxxx而不是0x0xxxxxxx;第二,CS怎麼接;第三,爲什麼Bit17對應A16

 

RS問題:RS0表示;讀寫寄存器;RS1,讀寫數據RAM

 

先來看前兩個問題,大家找到STM32FSMC手冊,在FSMC手冊裏面,我們很容易找到,FSMC0x60000000-0x6fffffff的地址用作NOR/PRAM

256M地址範圍)。而這個存儲塊,又被分成了四部分,每部分64M地址範圍。當對其中某個存儲塊進行讀寫時,對應的NEx就會置低。這裏,

就解決了我們兩個問題,第一,LCD的操作時序,和NOR/PRAM是一樣的(爲什麼一樣自己找找NOR/PRAM的時序看看),所以我們選擇0x6xxxxxxx

這個地址範圍(選擇這個地址範圍,操作這個地址時,FSMC就會呈現出NOR/PRAM的時序)。第二,我們可以將NEx連接到LCDCS,只要我們操作

的地址是第一個存儲塊內即可(即0-0x3ffffff地址範圍)。 

 

第三個問題再來看一看FSMC手冊關於存儲器字寬的描述,我們發現,當外部存儲器是16位時,硬件管腳A0-A24表示的是地址線A1-A25的值,所以

我們要位移一下,Bit17的值,實際會被反應到A16這根IO來。關於數據寬度及位移的問題,初學的朋友可能會比較疑惑,當你接觸了多NOR/PRAM

這樣的器件後,你會發現,很多芯片的總線,都是這樣設計的,爲的是節省地址線。

 

第二個角度理解:

 

 

FSMC總線上看,LCD只有2個地址.

Bank1_LCD_C是寫寄存器,此時RS=1,告訴LCD我在總線上輸出數據的是寄存器的地址

Bank1_LCD_D是寫數據,此時RS=0,告訴LCD我在總線上輸出地數據是寄存器的數據或者GRAM的數據.

 

寫寄存器數據按2步來:

第一步先往Bank1_LCD_C(對應RS=1),送寄存器的地址:*(__IOuint16_t *) (Bank1_LCD_C)=index; 接着在Bank1_LCD_D這個地址(對應RS=0),寫入剛指向的寄存器的數據:*(__IO uint16_t *) (Bank1_LCD_D)= val;

 

爲什麼*(__IO uint16_t *) (Bank1_LCD_C)=index; 就是往LCD 寫寄存器呢?

 

 

這是一個16位的IO賦值操作,地址是Bank1_LCD_C,這個地址就是指向FSMCBank1NE1對應的地址空間。而LCD片選正是連接到NE1,具體地址要看RS接到哪一根地址線上。當CPU執行到這一條的時候,就會通過FSMC總線控制器在數據總線上進行一個地址爲Bank1_LCD_C的數據寫操作,此操作自動完成CS信號,

RD信號,WR信號,以及地址總線數據(RS信號)的輸出以及數據總線數據的輸出.

 

其他的操作都是這兩個操作組合完成。也就是我上面所說的,

"所有的寄存器地址和寄存器數據,以及GRAM數據都是通過IO0-IO15完成傳輸的,而不是FSMC的地址.這是容易搞混的一個地方.LCDFSMC地址只有一根,就是RS."

 

----------------------------------------------------------------------------------------------------------------------第三個角度理解:

TFT看做類似SRAM的存儲器,只能接在BANK1上。對應基地址是0x60000000.

BANK1又有劃分爲四個片選,分別對應基地址:

NE1 0x600000000

NE2 0x640000000

NE3 0x680000000

NE4 0x6C0000000

所以每個NEx能尋址的空間大小爲64M,也就是對應了FSMCA0A2526根地址線.

 

假如使用NE4接到爲LCD的片選CS上,那麼就對應基地址0x6C000000,

如果RS接到地址線的A0上,那麼當RS0時對應的地址就是 LCD_REG =0x6C000000,(其實你用0x6CFFFFF0是一樣的,因爲只用到一根地址線).

RS1時對應的地址就是 LCD_RAM=0x6C000001,(0x6CFFFFF1一樣對應LCD_RAM,因爲它一樣對應 RS=1).

 

如果RS接到 其他地址線上,情況是類似的。

比如接到An上,那麼

LCD_REG=0x6C000000,

LCD_RAM= 0x6C000000 |(1<<n)

 

注意這個地址不是唯一的,只要這個地址能尋址到BANK1 NE4上而且使RS=0,那麼就是LCD_REG,使RS=1,就是LCD_RAM.

 

----------------------------------------------------------------------------------------------------------------------

 

對應Bank1_LCD_C的地址,FSMC總線控制器在RS接的那根地址線輸出的是1,而對應Bank1_LCD_D,輸出的0.

RS接的可不是GPIO,FSMC地址總線的一根.FSMC進行讀寫操作的時候會在地址總線根據要讀寫的地址輸出電平的.

RS接哪一根地址線雖然沒有固定要求,但是一旦你確定要接哪一根,那麼Bank_LCD_CBank_LCD_D也要隨之確定,這可不是“自動的".

 

雖然沒有手動操作GPIO來操作RS,但是你敲代碼的時候可是手動指定Bank1_LCD_C 或者 Bank1_LCD_D,從而確定RS的電平.

所謂的“自動”是指:不是通過操作GPIO來操作RS,而是直接根據地址總線地址的不同來完成操作RS,這兩種方法的速度差別是非常大的.

 

 

如果是GPIO方式,先要通過操作GPIO分別輸出RS,CS,等的電平,然後再通過過GPIO操作輸出數據,然後還要通過GPIO再操作RD,WR,CS等的電平。

每操作一個GPIO都要好幾個週期,加起來就非常慢了.

FSMC是在一個FSMC寫週期內就完成了這所有的動作。

 

 

 

 

*******************************************************************************

#defineBank1_LCD_R   ((uint32_t)0x60000000)   //disp Reg ADDR

#defineBank1_LCD_D   ((uint32_t)0x60020000)  //disp Data ADDR

 

 

 

STM32FMSC系統手冊可以看到:

 

FSMC其實就相當於外部總線存儲器和內部AHB總線的接口:而AHB32位的,當外接NOR/LCD時,而外部存儲器的數據寬度可以選擇8位和16位的,這時候就存在一個地址轉換的問題即32位和8位或者16位地址轉換的問題。解決這個問題STM32採用的HADDR[25:0],它的作用就是將外部存儲器地址轉換爲AHB地址線。

 

其中:

STM32 <wbr>----小談FSMC <wbr>RS選擇

STM32 <wbr>----小談FSMC <wbr>RS選擇

 並且無論外部存儲器的寬度是多少位,FSMC_A[0]始終連接到外部存儲器的A[0];

 

 

 

 

 

NOR閃存/LCD

 

1:寄存器

2RAM

 

 

 

 

             

 

 

FSMC核心控制器

(這裏就只介紹使用BANK1的塊1:這個塊1的起始地址爲0x60000000)                                                                            








                    

                                      FS FSMC_NOE(輸出使能)

 

       
    STM32 <wbr>----小談FSMC <wbr>RS選擇
 
 

 

 

 

 

STM32

AHB總線                          

 


STM32 <wbr>----小談FSMC <wbr>RS選擇                                   FSMC_NE1(片選)

STM32 <wbr>----小談FSMC <wbr>RS選擇

RS?

STM32 <wbr>----小談FSMC <wbr>RS選擇右箭頭: D[0:15]右箭頭: FSMC_A[16:25]FSMC_NWE(寫使能)

 

 
  STM32 <wbr>----小談FSMC <wbr>RS選擇

 

 

 


HADDR[25:0]總共26位線,可以尋址64M的地址空間,而AHB總線是32位寬度,所以能尋址0x00000000~0xFFFF FFFF;在這裏我們只是指定了FMSC控制器塊1的地址爲0x60000000。尋址空間0x6000 0000~0x63ff  ffff;

 

LCD手冊相關知識:(9320或者hx8312都一樣)

RS引腳決定是寄存器命令還是顯示RAM數據。寄存器指令的輸入數據是16位,前8位是地址,後8位是數據。

STM32 <wbr>----小談FSMC <wbr>RS選擇

不同的MPU類型寄存器命令和數據總線的格式不同。並且對應輸入總線:有一下對應關係:

STM32 <wbr>----小談FSMC <wbr>RS選擇

對於SPI方式,則用以下對應關係:

STM32 <wbr>----小談FSMC <wbr>RS選擇

 

(2)顯示RAM數據格式和系統接口輸入總線之間的聯繫

STM32 <wbr>----小談FSMC <wbr>RS選擇

 

 

問題:RS如何選擇: 

#defineBank1_LCD_R   ((uint32_t)0x60000000)   //disp Reg ADDR

#defineBank1_LCD_D   ((uint32_t)0x60020000)  //disp Data ADDR

這裏LCD選取的16位,將RS接在A16,則HADDR[25:1]對應FSMC_A[24:0];關鍵在於爲什麼???

 

從上面可以看出,LCD除了需要數據線之外,額外的地址線是不需要的~~~~~但是在STM32在進行FSMC總線操作時,所有的地址線還是會出現時序的,但是操縱LCD不需要額外的地址線了,也就是FSMC_A[16:25]可以解放了,但是要注意一旦配置了FSMC,這些管腳還是會出現時序的;

 

現在我們向0x60000000這個塊地址送出數據,當然這些數據肯定是16位的,因爲是16位的LCD,由於RS(A16)0,所以這個讀寫寄存器的操作;當向0x60020000寫數據時,由於總線時序是要有地址寫的,這時bit17就爲高了,也就是RS1了,這時所進行的操作就是讀寫RAM了!!!!

其中RS的選擇可以是任意的,但一般還是選擇,不用的地址線爲好~~~~~

發佈了24 篇原創文章 · 獲贊 21 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章