1. 程式人生 > >【.Net Micro Framework PortingKit – 13】LCD驅動開發

【.Net Micro Framework PortingKit – 13】LCD驅動開發

LCD驅動其實對TinyCLR並無必要,特別是在EM-STM3210E開發板上,因為該開發板上的記憶體太小了,片內64K,片外擴充套件了128K,加起來也不過172K,而我們知道針對320*240的顯示大小,16bit的點陣圖所佔的大小就是150K,很顯然.Net Micro Framework所提供的圖形庫如不加修改是很難正常執行的,不過對我們來說在LCD螢幕上顯示文字資訊也是值得期待的,如果修改一下圖形庫,在LCD上畫個線、畫個圓和顯示個位圖也絕不成問題。

和我們以前開發的驅動相比,LCD的驅動開發還是比較繁瑣一些的,因為LCD的驅動程式碼分散在三個目錄中(題外話,我覺得針對.Net Micro Framework

來說,最難的驅動是網絡卡驅動(特別是wifi驅動)、其次是USB驅動,和它們相比,LCD驅動就是小菜了)。

和其它驅動類似,在具體寫LCD驅動之前,我們先在CortexM3.h標頭檔案裡,寫一個和LCD暫存器相關的結構體,以便以於操作LCD暫存器,這種做法其實也是.Net Micro Framework驅動程式碼的一種風格。

struct CortexM3_LCD

{

//LCD /CS is CE4 - Bank 4 of NOR/SRAM Bank 1~4

static const UINT32 c_Base = 0x6C000000;

/****/ volatile UINT16 REG;

/****/ volatile UINT16 RAM;

void WriteReg(UINT8 Reg,UINT16 Value)

{

REG = Reg;

RAM = Value;

}

UINT16 ReadReg(UINT8 Reg)

{

REG = Reg;

return RAM;

}

void SetCursor(UINT16 x,UINT16 y)

{

WriteReg(32,x);

WriteReg(33,y);

}

void SetPixel(UINT16 x,UINT16 y,UINT16 c)

{

WriteReg(32,x);

WriteReg(33,y);

WriteReg(34,c);

}

void WriteRAM_Prepare()

{

REG = 34;

}

};

首先我們在/DeviceCode/Targets/Native/CortexM3/DeviceCode目錄建立LCD子目錄,該驅動檔案其實實現的功能很簡單,歸結起來就如下四個函式。

LCD_Controller_InitializeLCD初始化

LCD_Controller_Uninitialize

LCD_Controller_EnableLCD使能

LCD_GetFrameBuffer獲得LCD顯示緩衝區首地址

但是對我們的ILI9320 LCD來說,LCD_Controller_EnableLCD_GetFrameBuffer都不是必要的,從我們開發板附送的LCD示例上看,LCD顯示緩衝區首地址的概念似乎是不存在的,我們直接寫RAM即可,至於寫入座標是通過程式碼WriteReg(32,x)WriteReg(33,y)來控制(其實LCD驅動並不像我想象的那麼簡單,有很多功能需要仔細研究技術手冊才能發現,不過為了簡單起見,我們先按示例提供的方式來顯示)。

LCD_Controller_Initialize初始化程式碼中需要幾個延時(我在寫SysTick驅動的文章中提到了這一點),如下程式碼所示:

CortexM3_LCD &LCD = CortexM3::LCD();

HAL_Time_Sleep_MicroSeconds_InterruptEnabled(50000);

LCD.WriteReg(227, 0x3008);// Set internal timing

LCD.WriteReg(231, 0x0012);// Set internal timing

LCD.WriteReg(239, 0x1231);// Set internal timing

LCD.WriteReg(1, 0x0100);// set SS=1:0x0100 and SM=0:0x0400 bit

LCD.WriteReg(2, 0x0700);// set 1 line inversion

LCD.WriteReg(3, 0x1030);// set GRAM write direction and BGR=1.

//放縮 0x0000 0x0001 1/2 0x0003 1/4

LCD.WriteReg(4, 0x0000);// Resize register

LCD.WriteReg(8, 0x0207);// set the back porch and front porch

LCD.WriteReg(9, 0x0000);// set non-display area refresh cycle ISC[3:0]

LCD.WriteReg(10 , 0x0000);// FMARK function

//0x0000 18bit RGB介面 0x0001 16bit RGB介面0x0002 6bit RGB介面

LCD.WriteReg(12 , 0x0000);// RGB interface setting

LCD.WriteReg(13 , 0x0000);// Frame marker Position

LCD.WriteReg(15 , 0x0000);// RGB interface polarity

/**************Power On sequence ****************/

LCD.WriteReg(16 , 0x0000);// SAP, BT[3:0], AP, DSTB, SLP, STB

LCD.WriteReg(17 , 0x0007);// DC1[2:0], DC0[2:0], VC[2:0]

LCD.WriteReg(18 , 0x0000);// VREG1OUT voltage

LCD.WriteReg(19 , 0x0000);// VDV[4:0] for VCOM amplitude

HAL_Time_Sleep_MicroSeconds_InterruptEnabled(200000);// Delay 200 MS , Dis-charge capacitor power voltage

LCD.WriteReg(16 , 0x1690);// SAP, BT[3:0], AP, DSTB, SLP, STB

LCD.WriteReg(17 , 0x0227);// R11H=0x0221 at VCI=3.3V, DC1[2:0], DC0[2:0], VC[2:0]

HAL_Time_Sleep_MicroSeconds_InterruptEnabled(50000);// Delay 50ms

LCD.WriteReg(18 , 0x001D);// External reference voltage= Vci;

HAL_Time_Sleep_MicroSeconds_InterruptEnabled(50000);// Delay 50ms

LCD.WriteReg(19 , 0x0800);// R13H=1D00 when R12H=009D;VDV[4:0] for VCOM amplitude

LCD.WriteReg(41 , 0x0014);// R29H=0013 when R12H=009D;VCM[5:0] for VCOMH

LCD.WriteReg(43 , 0x000B);// Frame Rate = 96Hz

HAL_Time_Sleep_MicroSeconds_InterruptEnabled(50000);// Delay 50ms

LCD.WriteReg(32 , 0x0000);// GRAM horizontal Address

LCD.WriteReg(33 , 0x0000);// GRAM Vertical Address

NativeSample專案來說,在debug版本直接使用HAL_Time_Sleep_MicroSeconds_InterruptEnabled是沒有問題的,但是在Release版本上面的函式前面要加一句GLOBAL_LOCK(irq)程式碼,也就是迴圈期間要關閉中斷,才能正常執行。不過無論加不加這句程式碼,在TinyCLR專案中,Release版本也是無法正常執行的,甚至是直接用for迴圈也不行,不知道MDK的編譯優化到底改變了些什麼,有時間需要深入研究一下(當然上班之後,我也可以在RVDS上除錯看看,有時候就是這樣,同樣的程式碼用MDK除錯通不過,但是用RVDS就沒有問題)。

接下來我們要在/DeviceCode/Drivers/Display目錄下新建ILI9320子目錄,在該目錄的程式碼中我們實現文字顯示(當然指西文字元,要顯示漢字,在如此小的記憶體中我們得需要特別的技巧)。

詳細的程式碼這裡我就不貼了,不過要特別說明的是,EM-STM3210E的開發板有些問題,LCD其實是倒著裝的,按開發板的測試示例來移植我們的程式碼,最終的顯示是倒的,如下圖所示:

1

所以我們一是要重設LCD相應的暫存器,把視訊記憶體翻轉過來,程式碼如下:

/* 資料顏色序(BGR): 0x1000 BGR0x0000 RGB */

/* 掃描方向(AM): 0x0008 從右到左0x0000 從上到下 */

/* 資料填充方向(I/D):0x00000x00100x00200x0030 */

LCD.WriteReg(3, 0x1000 | 0x0000 ); //0x0030 正常模式

其次是修改WriteChar函式裡的程式碼,讓它適應這個變化,修改後的程式碼如下,注意要用LCD的寬度和高度值減去xy的座標。

const UINT8* font = Font_GetGlyph( c );

CortexM3_LCD &LCD = CortexM3::LCD();

int cx=0,ry=0;

for(int y = 0; y < Font_Height(); y++)

{

for(int x = 0; x < Font_Width(); x+=2)

{

cx=g_ILI9320_Config.ControllerConfig.Width-(col+x)-1;

ry=g_ILI9320_Config.ControllerConfig.Height-(row+y)-1;

// the font data is mirrored

if(ILI9320_GETBIT(Font_Width() -x,y,font,1)) LCD.SetPixel(cx, ry,0x07e0);

else LCD.SetPixel(cx, ry,0);

if(ILI9320_GETBIT(Font_Width() - (x+1),y,font,1)) LCD.SetPixel(cx-1, ry,0x07e0);

else LCD.SetPixel(cx-1, ry,0);

}

}

修改程式碼後,我們的顯示就已經翻轉了,如下圖所示:

2

最後我們還要在/Solutions/STM3210E/DeviceCode目錄下新建子目錄Display,在該目錄下新建ILI9320_config.cpp檔案,該檔案主要完成LCD的一些引數配置,主要配置如下:

#define ILI9320_SCREEN_WIDTH240

#define ILI9320_SCREEN_HEIGHT320

#define ILI9320_ENABLE_TFTTRUE

#define ILI9320_ENABLE_COLORTRUE

#define ILI9320_PIXEL_POLARITYFALSE

#define ILI9320_FIRST_LINE_POLARITYFALSE

#define ILI9320_LINE_PULSE_POLARITYFALSE

#define ILI9320_SHIFT_CLK_POLARITYFALSE

#define ILI9320_OUTPUT_ENABLE_POLARITYFALSE

#define ILI9320_CLK_IDLE_ENABLETRUE

#define ILI9320_CLK_SELECT_ENABLETRUE

#define ILI9320_PIXELCLOCKDIVIDER9

#define ILI9320_BUS_WIDTH16

#define ILI9320_BITS_PER_PIXEL16

#define ILI9320_ORIENTATION0

這時候也許有人會問,何必這麼麻煩,把一個LCD驅動分解到三個目錄中,都放在一個目錄行不行?當然這是可以的,這樣做的目的就是,針對不同開發板,有些程式碼可以方便地複用。

開發完LCD驅動,如果僅僅顯示文字,不顯示一個位圖,總覺得缺少點什麼。說幹就幹,我顯示一個320*240的點陣圖。

但說起來容易做起來難,一個16bit320*240的點陣圖要150k,先不說如何去顯示它,光說它放在什麼地方,就是一個頭疼的地方,如果把它編寫到程式碼中,我們的片內Flash512k,很顯然放不下,放到NandFlash中,我們沒有實現檔案系統,在說也沒有實現UsbMassStorage功能,我們也無法把圖片拷貝到NandFlash中。

幸好在開發wifi驅動過程中我實現了一個MFDeploy的外掛,通過該外掛可以把點陣圖下載到NandFlash中(因為Ti提供的wifi開發板,wifi初始化時需要載入三個檔案,原先是放在檔案系統中的,單這樣做代價高了點,不僅要實現檔案系統,還要實現UsbMassStorage功能,否則檔案也是沒法放到NandFlash上的,所以才開發了這個外掛)。至於這個外掛是如何實現的,我在以後準備要寫的【玩轉.Net MF】系列文章中我會詳細介紹的。

在下載點陣圖之前,我們先做一張320*240的點陣圖,儲存時要做如下選擇,如下圖:

3

要選擇R5G6B5,此外要勾選翻轉行序(也可以不勾選,不過程式碼要做些調整,否則圖形是倒的)。

我們的實現思路是,從NandFlash中先讀一部分資料,然後再顯示一部分圖形,最終完成一幅圖的顯示,這樣就避開了內容小的問題。

LCD驅動中點陣圖顯示函式LCD_BitBltEx中的程式碼如下:

UINT16 * StartOfLine_src = (UINT16 *)&data[0];

CortexM3_LCD &LCD = CortexM3::LCD();

if(x==0 && y==0) LCD.SetCursor(g_ILI9320_Config.ControllerConfig.Width-1,g_ILI9320_Config.ControllerConfig.Height-1);

LCD.WriteRAM_Prepare();

for(int i=0;i<width*height;i++)

{

LCD.RAM = *StartOfLine_src++;

}

NativeSample.cpp中的測試程式碼如下:

BYTE bytReadData[15360];

UINT32 index=0x00520046;

BlockStorageDevice *device= BlockStorageList::GetFirstDevice();

for(int y=0;y<320;y+=32)

{

device->Read(index,15360,bytReadData);

LCD_BitBltEx(0,y,240,32,(UINT32 *)bytReadData);

index+=15360;

}

最終的效果圖如下:

4 

相關推薦

.Net Micro Framework PortingKit13LCD驅動開發

LCD驅動其實對TinyCLR並無必要,特別是在EM-STM3210E開發板上,因為該開發板上的記憶體太小了,片內64K,片外擴充套件了128K,加起來也不過172K,而我們知道針對320*240的顯示大小,16bit的點陣圖所佔的大小就是150K,很顯然.Net Micro

Net Micro Framework PortingKit - 02STM3210E平臺構建

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

.net開發者自學java系列使用Eclipse開發SpringMVC(1)

領域驅動設計 cuc HR 代碼 swagger cli FQ bdd http 第一篇隨筆,有點緊張。有錯別字是正常的。。。。 好了,自我描述下。我是一個有幾年.net開發經驗的老菜鳥。是的,老菜鳥。別跟我討論底層,別跟我討論協議。TMD啥都不會。 為什麽要學JAVA,我

專欄 - .NET Micro Framework

.NET Micro Framework Microsoft .NET Micro Framework 將 .NET 的可靠性和效率與 Visual Studio的高生產率結合起來,以針對價格較低、資源受限的小型裝置開發應用程式,

BBC micro:bit基礎教程02-micro:bit與人體運動檢測傳感器

bbc image strong img spa www 訪問 info bit 【所需材料】 BBC micro:bit 主板 x 1 Micro USB 線 x 1 能容納2節7號(AAA)電池的電池盒 x 1 7號(AAA)電池 x 2 人體運動檢測傳感器 x

BBC micro:bit基礎教程04-micro:bit讀取光敏電阻

www. inf 訪問 主板 bit 讀取 藍色 電路 問題 【所需材料】 BBC micro:bit 主板 x 1 Micro USB 線 x 1 能容納2節7號(AAA)電池的電池盒 x 1 7號(AAA)電池 x 2 光敏電阻 x 1 10kΩ 電阻 x 1 鱷

Net Micro Framework - USB Mass Storage功能實現

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

從壹開始前後端分離 .NET Core2.0 +Vue2.0 框架之十二 || 三種跨域方式比較,DTOs(資料傳輸物件)初探

更新反饋 1、博友@童鞋說到了,Nginx反向代理實現跨域,因為我目前還沒有使用到,給忽略了,這次記錄下,為下次補充。 程式碼已上傳Github+Gitee,文末有地址   今天忙著給小夥伴們提出的問題解答,時間上沒把握好,都快下班了,趕緊釋出:書說上文《從壹開始前

省內訓練2018-09-13Hamilton Path

【思路要點】 有一種樸素的 O(N∗M)O(N∗M) 的做法,首先列舉路徑開始的位置,那麼從這個點開始的每一個點必須只存在一個沒有被訪問的後繼,因此我們可以在 O(M)O(M) 的時間內確定一個起始點出發是否有解,若有解,我們會找到一組唯一的解。

BBC micro:bit基礎教程01-如何用按鍵控制一個LED

【所需材料】 BBC micro:bit 主機板 x 1 Micro USB 線   x 1 能容納2節7號(AAA)電池的電池盒 x 1 7號(AAA)電池 x 2 紅色LED燈 x 1 100歐姆限流電阻 x 1  鱷魚夾 x 3 ​【認識LED】 如圖所示,LED有連個引腳,一長一短,LED發光二

從壹開始前後端分離 .NET Core2.0 +Vue2.0 框架之六 || API專案整體搭建 6.1 倉儲模式

 程式碼已上傳Github+Gitee,文末有地址   書接上文:前幾回文章中,我們花了三天的時間簡單瞭解了下介面文件Swagger框架,已經完全解放了我們的以前的Word說明文件,並且可以線上進行除錯,而且當專案開始之中,我們可以定義一些空的介面,或者可以返回假資料,這樣真正達到了前後端不等待的缺陷,還是

從壹開始前後端分離 .NET Core2.0 +Vue2.0 框架之四 || Swagger的使用 3.2

更新 如果想直接在域名的根目錄直接載入 swagger 比如訪問:localhost:8001 就能訪問,可以這樣設定: app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp

從壹開始前後端分離 .NET Core2.0 +Vue2.0 框架之十 || AOP面向切面程式設計淺解析:簡單日誌記錄 + 服務切面快取

  今天的講解就到了這裡了,通過這兩個小栗子,大家應該能對面向切面程式設計有一些朦朧的感覺了吧

從壹開始前後端分離 .NET Core2.0 +Vue2.0 框架之十三 || DTOs 物件對映使用,專案部署Windows+Linux完整版

 程式碼已上傳Github+Gitee,文末有地址 番外:時間真快,今天終於到了系統打包的日子,雖然專案還是有很多問題,雖然後邊還有很多的內容要說要學,但是想著初級基本的.Net Core 用到的基本至少就這麼多了(介面文件,專案框架,持久化ORM,依賴注入,AOP,分散式快取,CORS跨域等等),中高

從壹開始前後端分離 .NET Core2.0 +Vue2.0 框架之五 || Swagger的使用 3.3 JWT許可權驗證修改

重大更新: 兩個是上下銜接的,主要是解決本文中,過期時間無效的問題。 群友反饋: 群裡有小夥伴反饋,在Swagger使用的時候報錯,無法看到列表,這裡我說下如何除錯和主要問題: 1、如果遇到問題,這樣的: 請在瀏覽器 =》 F12 ==》 console 控制檯 ==》點選錯誤資

從壹開始前後端分離 .NET Core2.0 +Vue2.0 框架之二 || 後端專案搭建

WHY     至於為什麼要搭建.Net Core 平臺,這個網上的解釋以及鋪天蓋地,想了想,還是感覺重要的一點,跨平臺,嗯!沒錯,而且比.Net 更容易搭建,速度也更快,所有的包均有Nuget提供,不再像以前的單純引入元件,比如是這樣的:

從壹開始前後端分離 .NET Core2.0 +Vue2.0 框架之十一 || AOP自定義篩選,Redis入門 11.1

大神留步 先說下一個窩心的問題,求大神幫忙,如何在AOP中去使用泛型,有償幫助,這裡謝謝,文末有詳細問題說明,可以留言或者私信都可以。 當然我也會一直思考,大家持續關注本帖,如果我想到好辦法,會及時更新,並通知大家。 程式碼已上傳Github+Gitee,文末有地址   傳統的快取是在Co

從壹開始前後端分離 .NET Core2.0 +Vue2.0 框架之三 || Swagger的使用 3.1

更新 經常有小夥伴遇到這個錯誤 這是因為介面json文件定義和呼叫不是一個 1、定義: ConfigureServices 方法中的  services.AddSwaggerGen 註冊的一個名字 c.SwaggerDoc("v1",  2、呼叫: Configure 方法中的 app.Use

從壹開始前後端分離 .NET Core2.0 +Vue2.0 框架之七 || API專案整體搭建 6.2 輕量級ORM

更新 1、在使用的時候,特別是 update 的時候,如果不知道哪裡有問題,記得檢視資料庫 和 實體類 的欄位,是否大小寫一致,比如 name 和 Name 要學會使用資料庫監控分析器 程式碼已上傳Github+Gitee,文末有地址   書接上文:《從壹開始前後端分離【 .NET

從壹開始前後端分離 .NET Core2.0 +Vue2.0 框架之八 || API專案整體搭建 6.3 非同步泛型倉儲+依賴注入初探

程式碼已上傳Github+Gitee,文末有地址   番外:在上文中,也是遇到了大家見仁見智的評論和反對,嗯~說實話,積極性稍微受到了一丟丟的打擊,不過還好,還是有很多很多很多人的贊同的,所以會一直堅持下去,歡迎提出各種建議,問題,意見等,我這個系列呢,只是一個拋磚引玉的文章,大家可以自定義的去擴充套件學習