深入理解ARM体系架构(S3C6410)---lcd 显示图片
本文引用地址:https://www.eepw.com.cn/article/201611/317829.htm
显示控制器由VSFR,VDMA,VPRCS,VTIME,和视频时钟产生器。VSFR包含一些可编程的寄存器和两个256x25的调色板内存。这些都是用于配置显示控制器的。VDMA专用于显示DMA。它能将一帧的视频数据发送到VPRCS。通过这些特定DMA,这些视频数据可以在CPU不调停的情况下,显示到显示屏上。VPRCS从VDMA接收视频数据,并把接收的数据转化成合适的数据格式,从而再发送到显示器件上(LCD)。VTIME包含一些可编程的逻辑器件以满足不同显示设备的需求,如设置接口时序和刷新频率. 产生:RGB_VSYNC,RGB_HSYNC, RGB_VCLK, RGB_VDEN,SYS_CS1, SYS_CS0等信号控制显示设备。
FIFO在VDMA中。当FIFO为空或部分为空时,VDMA就会请求数据。当内存中的总线仲裁接收到这样的传输请求时,就会从系统内存向内部FIFO传输4/8/16连续的字。每个FIFO有64个字,同时FIFO的使用大小又有数据的传输速率决定。显示控制器有5个FIFO,主要是为了满足5个图像层的使用。在每个屏幕显示模式中,只有一个FIFO被使用。VPRCS通过FIFO提取数据。VPRCS支持层功能,最多5个层。下面的图像显示了数据流从系统总线到输出缓存的过程。
再来看看mini6410中,nec43和显示控制器的连接原理图:
这样我们就可以参考相应的寄存器设置,来实现lcd的图片显示了,
原图片:
我的手机像素极差,,,,
程序如下:
初始化函数:
[cpp] view plaincopyprint?
- void
LCD_Init(void) - {
//设置VD0~15 rGPICON = 0xaaaaaaaa; //设置GPI0~15为LCD VD0~15 rGPIPUD = 0x00000000; //设置VD16~23和HSYNC、VSYNC、VDEN、VCLK rGPJCON = 0x00aaaaaa; rGPJPUD = 0x00000000; //LCD寄存器设置 rSPCON |= (1<<0); //设置RGBI/F配置 //rSPCON = rSPCON & ~(0x3) | 1; rMIFPCON &= ~(1<<3); //设置LCD支路为一般模式 rVIDCON0 = (0<<29)|(0<<27)|(0<<26)|(0<<18)|(0<<17)|(0<<16)|(9<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(1<<1)|(1<<0); rVIDCON1 = 1<<7; //1=RGB类型LCD设备在VCLK上升沿得到视频数据 //设置屏的时序 rVIDTCON0 = (0x00<<16)|(0x00<<8)|(0x02<<0); rVIDTCON1 = (0x2d<<16)|(0x04<<8)|(0x06<<0); rVIDTCON2 = (271<<11)|(479<<0); //设置窗口格式 rWINCON0 = 11<<2; //设置24BPP //设置窗口位置 rVIDOSD0A = (0<<11)|(0<<0); rVIDOSD0B = (479<<11)|(271<<0); rVIDOSD0C = (((480*272)&0xffffff)<<0); //4.3屏幕分辨率480*272 //设置Window1的开始和结束的缓存地址与地址在内存中的存放地址以及缓存的大小 rVIDW00ADD0B0 = ((addr>>24)<<24)|(addr&0xffffff); rVIDW00ADD1B0 = (addr&0xffffff + 480*272); rVIDW00ADD2 = (0<<13)|(480<<0); //设置抖动 rDITHMODE=(1<<5)|(1<<3)|(1<<1)|(1<<0); //开显示 rVIDCON0 |= (3<<0); rWINCON0 |= (1<<0); - }
画图函数:
[cpp] view plaincopyprint?
- void
LCD_DrawPixel(unsigned int x, unsigned int y, unsigned int color) - {
if((x<480) && (y<272)) LCD_BUFFER[y][x] = color; - }
- void
LCD_Paint_Bmp(int x0,int y0,int h,int l,const unsigned char *bmp) - {
int x,y; unsigned int c; int p = 0; for( y = y0 ; y < l ; y++ ) { for( x = x0 ; x < h ; x++ ) { //RGB888 c = (bmp[p]) | (bmp[p+1]<<8) | (bmp[p+2]<<16); if ( ( (x0+x) < LCD_XSIZE) && ( (y0+y) ) LCD_BUFFER[y0+y][x0+x] = c ; p = p+3; } } - }
评论