一、準備工作
1、STM32CubeMx 我使用的是4.25版本的,軟件還沒裝上的自己去下載安裝就可以了
2、下載F103最新的固件庫,新建工程的時候,會自動提示讓你下載的,不用另行下載
下載保存的地方可以在軟件的project -> setting 頁面的最底下看到
3、TFT屏幕,瞭解清楚平模的驅動IC型號(後面會用到),同時準備好此屏幕的驅動。注意這裏只說明支持FSMC驅動的LCD屏幕(數據輸出最少16個),爲避免其它錯誤操作,應先確保驅動文件和屏幕都是好的,比如先跑個例程之類的。
4、編譯環境Keil uVision5
二、添加文件
1、新建工程,我這裏是F103VET6的芯片
2、配置FSMC,這裏只有NE1可以選,那就選NE1了,不同的選擇,會導致不同的代碼,後面再說,這裏先選上NE1
,寄存器的選擇就選A16,也可以選其它,同樣,不同的選擇,會導致不同的代碼,後面再說。注意數據選16位(這裏只講16位,8位的其實一樣)。
注意一定要選上CRC校驗,這裏是ST的一個保護機制,沒什麼卵用,強制要求的,選上就是了。
屏幕一般都是由22個引腳來控制的,其中16個引腳是數據,6個是控制,對應關係:
FSMC_NOE LCD_RD 讀
FSMC_NWE LCD_WR 寫
FSMC_NEx LCD_CS 片選
FSMC_Ax LCD_RS 寄存器選擇,注意不是復位
FSMC_D00~D15 對應 LCD_D0~D15 數據引腳
到這裏,已經配置了LCD屏幕的20個引腳了,(16個數據引腳,4個控制引腳),還需要在配置LCD的RST和BK引腳,也就是復位和背光燈引腳,沒有的話可以不配置,我這裏有,配置爲輸出即可(默認推輓輸出)
至此,引腳配置完。把時鐘配置一下,就可以生成了。
3、把STemwin複製到工程文件
把整個STemwin複製到工程文件裏面,要把SemWin文件夾改個名稱,否則的話,在重新生成代碼的時候,改文件夾可能會被刪除
再工程新建一個分組STemwin,把這幾個文件添加到工程:
- GUI_X.C:\OS 文件夾
- GUIConf.c,LCDConf_FlexColor_Template.c:\Config 文件夾
- STemWin522_CM3_Keil.lib :\Lib 文件夾
把LCD驅動文件也放到工程裏面,注意驅動文件的名稱不能爲lcd.c、lcd.h,因爲emwin裏有一個文件也叫lcd.c,改一下名稱就好,我這裏改爲:
其中,ili9341是我屏幕的驅動IC,再次提醒,記住這個IC芯片的型號,把相應的頭文件也加進去(個人習慣把頭文件和源文件分開兩個文件夾存放)
添加到工程裏面,把相應的頭文件路徑加進去:
然後編譯一下:
一堆錯誤(錯誤數量跟LCD的驅動文件有關),前面的都是一些體力活,真正要改代碼的工作終於開始了。
三、修改代碼
1、GUI_X.c
這裏只需要修改一個代碼,源碼裏面由這麼一個變量:volatile GUI_TIMER_TIME OS_TimeMS;
這是整個emwin的心跳,必須要讓它跳起來(我是直接把它放到了系統時鐘裏面,由興趣的朋友可以放在定時器裏面,注意是1ms的心跳):
這裏系統會報錯,提示GUI_TIMER_TIME這個數據類型未定義,很簡單,在文件里加上 #include “GUI.h”就可以了
2、GUIConf.c
只需要把這個數據改小一點就可以了,我這裏改成10*1024,也就是10K字節,具體看芯片的內存空間大小,大點小點都無所謂。
3、LCDConf_FlexColor_Template.c
先把LCD驅動頭文件加進來:#include "bsp_ili9341_lcd.h"
屏幕分辨率,按實際屏幕分辨率大小修改就可以了
然後要修改這4個函數:
static void LcdWriteReg(U16 Data) ;
static void LcdWriteData(U16 Data);
static void LcdWriteDataMultiple(U16 * pData, int NumItems);
static void LcdReadDataMultiple(U16 * pData, int NumItems);
這時候需要回去看我們LCD的驅動代碼了,先看頭文件bsp_ili9341_lcd.h,找到類似下面定義的東西:
#define macFSMC_Addr_ILI9341_CMD ( ( uint32_t ) 0x60000000 ) //FSMC_Bank1_NORSRAM1用於LCD命令操作的地址
#define macFSMC_Addr_ILI9341_DATA ( ( uint32_t ) 0x60020000 ) //FSMC_Bank1_NORSRAM1用於LCD數據操作的地址
爲何是0x60000000?這又牽連到了一開始我們配置的FSCM了,具體可以查看FSMC的相關時序,我們的LCD驅動協議,實際上跟FSMC是一毛一樣的。這裏只介紹怎麼決定這個值就好:
NE1 0x600000000
NE2 0x640000000
NE3 0x680000000
NE4 0x6C0000000
然後0x60020000的決定方式:
0x600000000 | ( 0x1<<( 16 + 1 ) ) = 0x60020000;
其中的16就是A16,如果是A17,那就是17+1,結果爲0x60040000
現在只要記住,寫LCD命令是小的數值,寫LCD數據是大的數值就好了。
然後定義兩個宏定義:
#define LCD_WRITE_REG ( *(__IO uint16_t *) (macFSMC_Addr_ILI9341_CMD) )
#define LCD_WRITE_DATA ( *(__IO uint16_t *) (macFSMC_Addr_ILI9341_DATA) )
然後,寫上代碼:
static void LcdWriteReg(U16 Data) {
// ... TBD by user
LCD_WRITE_REG = Data;
}
static void LcdWriteData(U16 Data) {
// ... TBD by user
LCD_WRITE_DATA = Data;
}
static void LcdWriteDataMultiple(U16 * pData, int NumItems) {
while (NumItems--) {
// ... TBD by user
LCD_WRITE_DATA = *pData++;
}
}
static void LcdReadDataMultiple(U16 * pData, int NumItems) {
while (NumItems--) {
// ... TBD by user
*pData++ = LCD_WRITE_DATA;
}
}
在LCD_X_Config函數裏面,加入一行代碼
Config.NumDummyReads = 2;
表示第二個數據纔是真實數據(不理解的話就先記住,以後慢慢會清楚)
第二個紅框的就是由驅動芯片決定的,打開這個文檔:
在1127頁左右,找到你對應的芯片驅動IC,然後決定紅框中的值取什麼:
我這裏是ili9341,所以要改成GUIDRV_FLEXCOLOR_F66709
GUIDRV_FLEXCOLOR_M16C0B16的意思頁可以在文檔中找到:
然後,把驅動文件的初始化函數放在這裏:
剩下的,就是把LCD的驅動代碼修改爲HAL庫的了,沒什麼難度,自行修改吧,注意要細心點。
至此,移植代碼做完了,寫個測試代碼
四、測試代碼
先加入頭文件 #include "GUI.h"和lcd驅動#include "bsp_ili9341_lcd.h"
寫入代碼: