`
mmdev
  • 浏览: 13251249 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

【.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_Initialize LCD初始化

LCD_Controller_Uninitialize

LCD_Controller_Enable LCD使能

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 BGR 0x0000 RGB */

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

/* 数据填充方向(I/D):0x0000 0x0010 0x0020 0x0030 */

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_WIDTH 240

#define ILI9320_SCREEN_HEIGHT 320

#define ILI9320_ENABLE_TFT TRUE

#define ILI9320_ENABLE_COLOR TRUE

#define ILI9320_PIXEL_POLARITY FALSE

#define ILI9320_FIRST_LINE_POLARITY FALSE

#define ILI9320_LINE_PULSE_POLARITY FALSE

#define ILI9320_SHIFT_CLK_POLARITY FALSE

#define ILI9320_OUTPUT_ENABLE_POLARITY FALSE

#define ILI9320_CLK_IDLE_ENABLE TRUE

#define ILI9320_CLK_SELECT_ENABLE TRUE

#define ILI9320_PIXELCLOCKDIVIDER 9

#define ILI9320_BUS_WIDTH 16

#define ILI9320_BITS_PER_PIXEL 16

#define ILI9320_ORIENTATION 0

这时候也许有人会问,何必这么麻烦,把一个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

分享到:
评论

相关推荐

    Expert .NET Micro Framework

    It begins with the basics of accessing hardware and networking before delving deep into the less well–known areas such as cryptography and globalization, and how to use technologies such as wireless ...

    Microsoft .net micro framework 4.0 SDK 含源码

    在开发过程中,使用MicroFrameworkSDK.MSI这个安装文件,开发者可以在自己的机器上安装.NET Micro Framework 4.0 SDK,从而开始创建、构建和调试针对小型设备的应用程序。安装后,开发者可以在Visual Studio环境中...

    Microsoft .NET Micro Framework嵌入式编程(美 汤普逊)

    这本书旨在帮助读者理解和掌握如何在嵌入式系统中应用.NET Micro Framework进行高效开发。 .NET Micro Framework 是微软推出的一个轻量级的.NET运行时环境,专门设计用于资源受限的设备,如物联网(IoT)中的传感器、...

    《玩转.NET Micro Framework移植-基于STM32F10x处理器》源程序.rar

    《玩转.NET Micro Framework移植-基于STM32F10x处理器》这本书的主题聚焦于将.NET Micro Framework(简称.NET MF)应用到STM32F10x系列微控制器上,这是一个涉及嵌入式系统开发、C#编程以及硬件平台集成的重要技术...

    Microsoft .NET Micro Framework 2.5 SDK

    - **嵌入式开发**:.NET Micro Framework提供了一种在嵌入式设备上运行.NET应用的方法,使开发者能够利用.NET的强大功能开发低功耗、高性能的设备。 - **C#与.NET编程**:使用C#作为主要编程语言,开发者可以利用...

    .Net Micro Framework 移植说明文档

    2. **C#或C++编程能力**:.NET Micro Framework支持C#和C++编程语言,因此开发人员需要熟练掌握至少一种。 3. **硬件知识**:理解目标硬件的工作原理和技术规格,能够编写驱动程序和配置硬件参数。 4. **操作系统...

    Expert .NET Micro Framework(德 Jens Kühner)

    《Expert .NET Micro Framework》是由Jens Kühner编著的一本专著,该书深入探讨了.NET Micro Framework这一小巧而强大的嵌入式系统开发框架。.NET Micro Framework是微软推出的一个开源平台,旨在为资源有限的设备...

    .net micro framework file

    .NET Micro Framework(简称.NET MF)是微软开发的一个轻量级.NET框架,主要针对嵌入式设备和物联网(IoT)应用。它提供了基础的.NET编程模型,使得开发者能够使用C#、VB.NET或其他.NET语言来编写高效能的嵌入式程序。...

    .NET Micro Framework for Windows 7(X64) USB驱动安装说明

    总结起来,.NET Micro Framework为开发者提供了一种高效且便捷的方式来开发针对小型设备的应用,而USB驱动的正确安装则是确保设备与开发环境顺畅通信的基础。通过遵循上述步骤,你可以在Windows 7(64位)系统上成功...

    .NET Micro Framework Key文件部署说明

    在使用.NET Micro Framework进行开发时,为了确保软件的安全性和合法性,开发者需要对开发板进行注册并获取相应的Key文件(MFKey.bin)。本文档旨在详细介绍如何获取及部署Key文件的过程。 #### 二、获取芯片ID与...

    GHI .NET Micro Framework培训教材(英文版)

    本教材《GHI .NET Micro Framework培训教材》专为初学者设计,旨在介绍.NET Micro Framework及其在嵌入式系统开发中的应用。教材详细介绍了如何使用C#语言进行编程,并提供了丰富的实例来帮助读者理解和掌握.NET ...

    .NET Micro Framework开发板使用手册(红牛开发板)

    红牛开发板是一款基于.NET Micro Framework的开发工具,便于开发者进行硬件原型设计和软件调试。本使用手册将详细讲解如何利用.NET Micro Framework在红牛开发板上进行应用程序的开发与运行。 首先,了解.NET Micro...

    expert .net micro framework

    expert .net micro frameworkexpert .net micro frameworkexpert .net micro framework

    .NET Micro Framework Testing Batch File Generator

    .NET Micro Framework自动化测试工具,需.NET Micro Framework3.0和.NET Micro Framework Test Kit支持...

    微软.NET Micro Framework首次在ADI公司的Blackfin处理器上亮相.pdf

    .NET Micro Framework是微软开发的一个轻量级的.NET运行环境,特别设计用于资源有限的嵌入式设备。这个框架首次被引入到ADI(Analog Devices, Inc.)公司的Blackfin处理器上,为开发者提供了一种新的、高效的方式来...

    基于Cortex-M3处理器的.Net Micro Framework移植.pdf

    通过这样的移植过程,开发者可以利用.NET Micro Framework的高级语言和工具(如Visual Studio)开发嵌入式应用程序,提高开发效率并降低维护成本。同时,结合Cortex-M3处理器的强大性能和低功耗特性,能够构建出高效...

Global site tag (gtag.js) - Google Analytics