LCD是liquid crystal display 的简称,液晶显示器按驱动方式分为静态驱动,简单矩阵驱动以及主动矩阵驱动。
简单矩阵驱动分为扭转向列型(TN)和超扭转向列型(STN)两种。
主动矩阵驱动则以TFT为主。
(1)、 TN型驱动液晶,是LCD中最基本的,其他LCD都以TN型改进。他只能将入射光旋转90度,视角只有30度,色彩单一,对比度低,用于电子表和电子计算机。
(2)、 STN型驱动液晶。可将入射光旋转180度至270度,也改善了视角,通过塔配色滤光片,将单色矩阵的任意像素分成3个子像素,红绿蓝。
(3)、1,2都采用场电压驱动方式,如果现实尺寸加大,中心部分对电极变化的反应时间就会变长,显示器的速度跟不上,为了解决这个问题,主动矩阵驱动TFT
被提出,他通过晶体管显示信号开启或者关闭液晶分子电压,从而避免了显示器对电场效应的依靠。
LCD颜色显示
显示器上的每个像素的颜色都有3部分组成:
红绿蓝。他们被称为三原色。
这三者的混合几乎可以产生出任何我们能识别的颜色。比如根据颜色的浓烈程度将三原色都分为256个级别(0~255),混合255级的红色,255级的绿色,255级的蓝色,可以产生出白色。
LCD系统结构
S3C2440LCD控制器
LCD控制器
(1)、REGBANK有17个可编程寄存器组成,用来配置LCD控制器的各项参数。
(2)、LCDCDMA是专用DMA通道,自动从帧缓冲中传输视频数据到LCD控制器,利用DMA,视频数据可不经过CPU干扰就显示在屏幕上。
(3)、VIDPRCS接受从LCDCDMA来的视频数据并在将其改变到适合数据格式后经VD[23:0]将之送到LCD驱动器。
(4)、TIMEGEN产生LCD屏所需要的VFRAME,VLINE,VCLK,VM等控制信号。
时序图
(1)、VSYNV:帧同步信号
每发出一个脉冲,表示新的一屏图像数据开始传送。
(2)、HSYNC:行同步信号
每发出一个脉冲,表示新的一行图像数据开始传输。
(3)、VCLK:像素时钟信号
每发出一个脉冲,表示新的一个点图像数据开始传送。
(4)、LEND:行结束信号
(5)、VBPD:表示在一帧图像开始时,帧同步信号以后的无效的行数,对应驱动中的upper_margin;
(6)、VFBD:表示在一帧图像结束后,帧同步信号以前的无效的行数,对应驱动中的lower_margin;
(7)、VSPW:表示垂直同步脉冲的宽度,用行数计算,对应驱动中的vsync_len;
(8)、HBPD:表示从水平同步信号开始到一行的有效数据开始之间的VCLK的个数,对应驱动中的left_margin
(9)、HFPD:表示一行的有效数据结束到下一个水平同步信号开始逐渐的VCLK的个数,对应驱动中的right_margin
(10)、HSPW:表示水平同步信号的宽度,用VCLK计算,对应驱动中的hsync_len
(11)、通过VM信号改变控制像素点的显示或者熄灭
驱动程序流程
初始化流程
端口初始化
显示模式-LCDCON1
帧缓冲初始化
代码:
#define GLOBAL_CLK 1
#include #include #include "def.h" #include "option.h" #include "2440addr.h" #include "2440lib.h" #include "2440slib.h" #include "mmu.h" #include "profile.h" #include "memtest.h" #define LCD_N35 //NEC 256K色240*320/3.5英寸TFT真彩液晶屏,每一条水平线上包含240个像素点,共有320条这样的线 #if defined(LCD_N35) #define LCD_WIDTH 240 #define LCD_HEIGHT 320 #define LCD_PIXCLOCK 4 #define LCD_RIGHT_MARGIN 39 #define LCD_LEFT_MARGIN 16 #define LCD_HSYNC_LEN 5 #define LCD_UPPER_MARGIN 1 #define LCD_LOWER_MARGIN 5 #define LCD_VSYNC_LEN 1 #endif void TFT_LCD_Test(void); #define LCD_XSIZE LCD_WIDTH #define LCD_YSIZE LCD_HEIGHT #define SCR_XSIZE LCD_WIDTH #define SCR_YSIZE LCD_HEIGHT volatile static unsigned short LCD_BUFFER[SCR_YSIZE][SCR_XSIZE]; //定义320行,240列的数组,用于存放显示数据 //320*240*2为帧缓冲大小,320×240等于点,每个点是2个字节 extern unsigned char sunflower_240x320[]; #define M5D(n) ((n)&0x1fffff) #define LCD_ADDR ((U32)LCD_BUFFER) #define ADC_FREQ 2500000 volatile U32 preScaler; static void cal_cpu_bus_clk(void); void Set_Clk(void); /*演示函数*/ void delay(int times) { int i,j; for(i=0;i } /*在屏幕上画图*/ static void Pait_Bmp(int x0,int y0,int h,int l,const unsigned char *bmp) { int x,y; U32 c; int p = 0; for( y = 0 ; y < l ; y++ ) { for( x = 0 ; x < h ; x++ ) { c = bmp[p+1] | (bmp[p]<<8) ; if ( ( (x0+x) < SCR_XSIZE) && ( (y0+y) < SCR_YSIZE) ) LCD_BUFFER[y0+y][x0+x] = c ; p = p + 2 ; //一个点为两个字节 } } } /*填充全屏为某一颜色*/ static void Lcd_ClearScr( U16 c) { unsigned int x,y ; for( y = 0 ; y < SCR_YSIZE ; y++ ) { for( x = 0 ; x < SCR_XSIZE ; x++ ) { LCD_BUFFER[y][x] = c ; //填入数组,就自动在屏幕上显示了 } } } /*LCD开关*/ static void Lcd_EnvidOnOff(int onoff) { if(onoff==1) rLCDCON1|=1; // ENVID=ON else rLCDCON1 =rLCDCON1 & 0x3fffe; // ENVID Off } /*端口初始化*/ static void Lcd_Port_Init( void ) { rGPCUP=0xffffffff; // Disable Pull-up register rGPCCON=0xaaaa02a8; //Initialize VD[7:0],VM,VFRAME,VLINE,VCLK rGPDUP=0xffffffff; // Disable Pull-up register rGPDCON=0xaaaaaaaa; //Initialize VD[15:8] } /*LCD初始化*/ static void LCD_Init(void) { Lcd_Port_Init(); /*显示模式初始化*/ /*bit[17:8](4:CLKVAL);bit[6:5](11:TFT LCD panel);bit[4:1](1100:16 bpp for TFT)*/ rLCDCON1 = (LCD_PIXCLOCK << 8) | (3 << 5) | (12 << 1); /*bit[31:24](1:VBPD);bit[23:14](320-1:行数);bit[13:6](5:VFPD);bit[5:0](1:VSPW)*/ rLCDCON2 = (LCD_UPPER_MARGIN << 24) | ((LCD_HEIGHT - 1) << 14) | (LCD_LOWER_MARGIN << 6) | (LCD_VSYNC_LEN << 0); /*bit[25:19](36:HBPD);bit[18:8](240-1:列数);bit[7:0](19:HFPD)*/ rLCDCON3 = (LCD_RIGHT_MARGIN << 19) | ((LCD_WIDTH - 1) << 8) | (LCD_LEFT_MARGIN << 0); /*bit[15:8](13:MVAL,只有当LCDCON1 bit[7]MMODE=1才有效);bit[7:0](5:HSPW)*/ rLCDCON4 = (13 << 8) | (LCD_HSYNC_LEN << 0); /*bit[11](5:6:5 Format);bit[9](VLINE/HSYNC polarity inverted);bit[8](VFRAME/VSYNC inverted) bit[3](Enalbe PWERN signal),bit[1](half-word swap control bit)*/ rLCDCON5 = (1<<11) | (1 << 9) | (1 << 8) | (1 << 3) | (1 << 0); /*帧缓冲地址初始化*/ /* LCDBANK: 视频帧缓冲区内存地址30-22位 LCDBASEU: 视频帧缓冲区的开始地址21-1位 LCDBASEL: 视频帧缓冲区的结束地址21-1位 */ /*bit[29:21]:LCDBANK,bit[20:0]:LCDBASEU*/ rLCDSADDR1 = ((LCD_ADDR >> 22) << 21) | ((M5D(LCD_ADDR >> 1)) << 0); //M5D为一个宏定义 /*bit[20:0]:LCDBASEL*/ rLCDSADDR2 = M5D((LCD_ADDR + LCD_WIDTH * LCD_HEIGHT * 2) >> 1); /*PAGEWIDTH:虚拟屏幕一行的字节数,如果不使用虚拟屏幕,设置为实际屏幕的行字节数 OFFSIZE:虚拟屏幕左侧偏移的字节数,如果不使用虚拟屏幕,设置为0 */ /*bit[21:11]:OFFSIZE; bit[10:0]:PAGEWIDTH*/ rLCDSADDR3 = LCD_WIDTH; /*屏蔽中断*/ rLCDINTMSK |= 3; rTCONSEL &= (~7); /*disable调色板*/ rTPAL = 0x0; /*禁止LPC3600/LCC3600模式*/ rTCONSEL &= ~((1<<4) | 1); /*打开LCD*/ Lcd_EnvidOnOff(1); } void TFT_LCD_Show(void) { /*红(255:0:0);绿(0:255:0);蓝(0:0:255);黑(0:0:0);白(255,255,255)*/ /*在屏幕上显示三基色*/ Lcd_ClearScr( (0x00<<11) | (0x00<<5) | (0x00) ) ; //clear screen black delay(10000); Lcd_ClearScr((0x1f<<11) | (0x00<<5) | (0x00)); //red delay(10000); Lcd_ClearScr((0x00<<11) | (0x3f<<5) | (0x00)); //green delay(10000); Lcd_ClearScr((0x00<<11) | (0x00<<5) | (0x1f)); //blue delay(10000); Lcd_ClearScr( (0x1f<<11) | (0x3f<<5) | (0x1f) ) ; //clear screen white delay(10000); /*显示一副图片在屏幕上*/ Pait_Bmp(0, 0, 240, 320, sunflower_240x320); } /************************************************* Function name: Set_Clk() Parameter : void Description : 设置CPU的时钟频率 Return : void Argument : void Autor & date : Daniel **************************************************/ void Set_Clk(void) { int i; U8 key; U32 mpll_val = 0 ; i = 2 ; //don't use 100M! //boot_params.cpu_clk.val = 3; switch ( i ) { case 0: //200 key = 12; mpll_val = (92<<12)|(4<<4)|(1); break; case 1: //300 key = 13; mpll_val = (67<<12)|(1<<4)|(1); break; case 2: //400 key = 14; mpll_val = (92<<12)|(1<<4)|(1); break; case 3: //440!!! key = 14; mpll_val = (102<<12)|(1<<4)|(1); break; default: key = 14; mpll_val = (92<<12)|(1<<4)|(1); break; } //init FCLK=400M, so change MPLL first ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3); //set the register--rMPLLCON ChangeClockDivider(key, 12); //the result of rCLKDIVN [0:1:0:1] 3-0 bit cal_cpu_bus_clk(); //HCLK=100M PCLK=50M } /************************************************* Function name: cal_cpu_bus_clk Parameter : void Description : 设置PCLKHCLKFCLK的频率 Return : void Argument : void Autor & date : Daniel **************************************************/ static void cal_cpu_bus_clk(void) { static U32 cpu_freq; static U32 UPLL; U32 val; U8 m, p, s; val = rMPLLCON; m = (val>>12)&0xff; p = (val>>4)&0x3f; s = val&3; //(m+8)*FIN*2 不要超出32位数! FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1< val = rCLKDIVN; m = (val>>1)&3; p = val&1; val = rCAMDIVN; s = val>>8; switch (m) { case 0: HCLK = FCLK; break; case 1: HCLK = FCLK>>1; break; case 2: if(s&2) HCLK = FCLK>>3; else HCLK = FCLK>>2; break; case 3: if(s&1) HCLK = FCLK/6; else HCLK = FCLK/3; break; } if(p) PCLK = HCLK>>1; else PCLK = HCLK; if(s&0x10) cpu_freq = HCLK; else cpu_freq = FCLK; val = rUPLLCON; m = (val>>12)&0xff; p = (val>>4)&0x3f; s = val&3;
上一篇:ARM汇编语言与C/C++的混合编程
下一篇:ARM9(S3C2440) Touch Screen
推荐阅读最新更新时间:2024-11-13 06:41
推荐帖子
- 在子函数中关闭中断,回到主函数也是关闭的吧
- 在子函数中关闭中断,回到主函数也是关闭的吧如果不是,那是为什么呢谢谢在子函数中关闭中断,回到主函数也是关闭的吧_BIS_SR_IRQ(GIE);是什么意思他和_EINT();有什么不同还有一点问题你这个提问有点别扭首先要进中断GIE肯定要被置位因为GIE是SR寄存器里的一个位在中断之前SR是被圧栈的进入中断服务程序的时候GIE是自动关闭的(如果强行打开可能会出现中断嵌套)退出中断后SR被弹出所以恢复到进中断之前(还是置位的)。_BIS_SR_IRQ(GIE);这
- yingguol 微控制器 MCU
- 找彩信外包
- 需要在arm9下的彩信收发功能。联系方式yuexianhanshu@yahoo.com找彩信外包只要彩信收发的程序,硬件已经有了找我们吧,刚做了6410下的彩信收发功能忘记了,联系QQ是:290052638
- born 嵌入式系统
- TM4C123GH6PZ单片机烧写HEX文件错误
- 用JFLASH烧写时出现如下错误:Endofpreparingflashprogramming-Startofdeterminingdirtyareasinflashcache-Endofdeterminingdirtyareas-CPUisrunningat15844kHz.-Startoferasingchip-Endoferasingchip-Startofrestoring-ERR
- kbbwww1 微控制器 MCU
- 工业级4G路由器需要满足哪些要求
- 第一:通信接口的规范性 设计者在设计工业级4G路由器过程中要求设备模块化结构之间的通信接口要规范化,工业级4G路由器模块的维护与更新以及新模块的追加都不应影响元件其他通信模块。此外,工业4G路由器软件应要具备较高的容错能力以至于一般小的软件故障不应引起各类严重的系统再启动。第二:相对的独立性 及其重要的是,性能稳定的工业级4G路由器设计过程中配置的数据与处理程序应具备相对的独立性,而配置数据的任何变更都不应引起设备运行版本程序的变更以利于处理程序与任何局的配置数据的相适
- 蓝先生 工控电子
- 开关电源设计(2本PDF),运算放大器指南(1本PDF)
- 精通开关电源设计(中文版)开关电源设计(第3版)运算放大器权威指南开关电源设计(2本PDF),运算放大器指南(1本PDF)thankyou!!! 很好的资料,非常感谢分享,楼主辛苦了,很受用! 非常感谢老师无私奉献,我个人也是新手刚刚接触,希望能够给我惊喜
- cute1996 电子竞赛
- 电路板故障汇总及维修技术的8个绝招
- 一、工控电路板电容损坏的故障特点及维修电容损坏引发的故障在电子设备中是最高的,其中尤其以电解电容的损坏最为常见。电容损坏表现为:容量变小;完全失去容量;漏电;短路。电容在电路中所起的作用不同,引起的故障也各有特点。在工控电路板中,数字电路占绝大多数,电容多用做电源滤波,用做信号耦合和振荡电路的电容较少。用在开关电源中的电解电容如果损坏,则开关电源可能不起振,没有电压输出;或者输出电压滤波不好,电路因电压不稳而发生逻辑混乱,表现为
- 吾妻思萌 开关电源学习小组
设计资源 培训 开发板 精华推荐
- DI-53 - 50 W DC-DC 双输出转换器
- 能量机关模块版(点阵灯条等受控模块)
- LT3477IFE 87% 效率、4W LED 驱动器的典型应用电路
- 通用8位S08/RS08 MCU塔式系统模块
- KIT33907AEEVB: 评估板 - MC33907,安全DC/DC,高达800 mA
- 51单片机篮球计时器课程设计
- LT8710 的典型应用 - 具有输出电流控制功能的同步 SEPIC/反相/升压控制器
- KIT33903BD5EVBE: 评估套件 - MC33903BD5,带CAN和LIN的第二代SBC
- SP7652EB,用于分布式电源系统的 3.3V DC 到 DC 单路输出电源的评估板
- LTC3442 锂离子至 3.3V 转换器提供 1.2A 电流,具有自动突发模式操作