三星S6D1121主控彩屏(240*320*18bit,262K)驱动程序
这个是三星的主控S6D1121彩屏(240*320*18bit,262Kcr)的彩屏的驱动程序.
采用的是80System+16bit接口
不知道是什么原因, 这个主控网上很少有资料,我也是看了好久的DS才明白了一些(全英文, 基本没中文资料, 反正是不好找到)
这是我接触的第一块彩屏哦~~
如果有用这个芯片的, 可能会有些方便, 也方便交流下使用经验.
这里总共分4个文件:
common.c,common.h:一些公共的包含与定义,函数
s6d1121.c,s6d1121.h:主控芯片驱动程序
这里只是驱动,关于图形接口将在下一篇文章中贴出代码
(图形接口已经写好了,见这里:http://www.cnblogs.com/nbsofer/archive/2012/12/09/2809401.html)
该代码仅供51单片机测试使用, 需要大量的优化, 我已经把优化后的代码移植到MSP430上去了.
由于51刷屏太慢,加上没时间,所以没有更新51版本的源代码,见谅~
//common.h - 一些公用的定义,函数等 #ifndef __COMMON_H__ #define __COMMON_H__ #include <reg52.h> #include <intrins.h> typedef unsigned int uint; typedef unsigned char uchar; void delay_us(uint us); void delay_ms(uint ms); #endif// !__COMMON_H__
//common.c #include "common.h" void delay_ms(uint ms) { uchar k; while(ms--){ for(k=125; k>0; k--){ _nop_(); } } } void delay_us(uint us) { while(us--){ _nop_(); } }
//s6d1121.h //S6D1121.h //S6D1121驱动程序 //应用层请不要调用 //应调用GDI接口 // //女孩不哭 QQ:191035066 //2012-11-05 #ifndef __S6D1121_H__ #define __S6D1121_H__ #include "common.h" void LCD_SetAddress(uint x, uint y, uint width, uint height); void LCD_WriteBus(uint dat); void LCD_WriteCmdWithData(uchar cmd, uint value); void LCD_WriteData(uint dat); void LCD_WriteCmd(uchar cmd); uint LCD_ReadBus(void); uint LCD_ReadData(void); void LCD_Init(void); #endif// !__S6D1121_H__
//s6d1121.c /* 文件:S6D1121.c * 功能:三星S6D1121主控彩屏驱动程序 * 版本:1.0 * 作者:女孩不哭 * Q--Q:191035066 * 时间:2012-11-05 * 说明:这里是底层驱动程序,用户不应该随便调用 * 请调用编写的图形接口程序 * 参考:http://www.elecfreaks.com/wiki/index.php?title=2.4%22_TFT_LCD:_TFT01-2.4 */ #include "common.h" #include "s6d1121.h" //I/O口定义,除*_RST外,均Active Low sbit LCD_RST= P2^0; //复位 sbit LCD_CS = P2^1; //片选 sbit LCD_RD = P2^2; //读取 sbit LCD_WR = P2^3; //写入 sbit LCD_RS = P2^4; //寄存器/数据选择 //数据总线端口定义 //如果使用16位总线,需要宏定义:BUS_16 //当使用8位总线时,仅*_HI有效 #define LCD_DATA_PORT_HI P0 #define LCD_DATA_PORT_LOW P1 //初始化,初始化之前 //MCU应该延时一段时间 //以使电源稳定 void LCD_Init(void) { LCD_RST = 1; delay_ms(5); LCD_RST = 0; delay_ms(5); LCD_RST = 1; LCD_CS = 1; LCD_RD = 1; LCD_WR = 1; delay_ms(5); LCD_CS = 0;//片选使能 //详细的说明见一开始的网址 LCD_WriteCmdWithData(0x11,0x2004); LCD_WriteCmdWithData(0x13,0xcc00); LCD_WriteCmdWithData(0x15,0x2600); LCD_WriteCmdWithData(0x14,0x252a); LCD_WriteCmdWithData(0x12,0x0033); LCD_WriteCmdWithData(0x13,0xcc04); delay_ms(1); LCD_WriteCmdWithData(0x13,0xcc06); delay_ms(1); LCD_WriteCmdWithData(0x13,0xcc4f); delay_ms(1); LCD_WriteCmdWithData(0x13,0x674f); LCD_WriteCmdWithData(0x11,0x2003); delay_ms(1); LCD_WriteCmdWithData(0x30,0x2609); LCD_WriteCmdWithData(0x31,0x242c); LCD_WriteCmdWithData(0x32,0x1F23); LCD_WriteCmdWithData(0x33,0x2425); LCD_WriteCmdWithData(0x34,0x2226); LCD_WriteCmdWithData(0x35,0x2523); LCD_WriteCmdWithData(0x36,0x1C1A); LCD_WriteCmdWithData(0x37,0x131D); LCD_WriteCmdWithData(0x38,0x0B11); LCD_WriteCmdWithData(0x39,0x1210); LCD_WriteCmdWithData(0x3A,0x1315); LCD_WriteCmdWithData(0x3B,0x3619); LCD_WriteCmdWithData(0x3C,0x0D00); LCD_WriteCmdWithData(0x3D,0x000D); LCD_WriteCmdWithData(0x16,0x0007); LCD_WriteCmdWithData(0x02,0x0013); LCD_WriteCmdWithData(0x03,0x0003); LCD_WriteCmdWithData(0x01,0x0127); delay_ms(1); LCD_WriteCmdWithData(0x08,0x0303); LCD_WriteCmdWithData(0x0A,0x000B); LCD_WriteCmdWithData(0x0B,0x0003); LCD_WriteCmdWithData(0x0C,0x0000); LCD_WriteCmdWithData(0x41,0x0000); LCD_WriteCmdWithData(0x50,0x0000); LCD_WriteCmdWithData(0x60,0x0005); LCD_WriteCmdWithData(0x70,0x000B); LCD_WriteCmdWithData(0x71,0x0000); LCD_WriteCmdWithData(0x78,0x0000); LCD_WriteCmdWithData(0x7A,0x0000); LCD_WriteCmdWithData(0x79,0x0007); LCD_WriteCmdWithData(0x07,0x0053); LCD_WriteCmdWithData(0x79,0x0000); LCD_WriteCmd(0x22); LCD_CS = 1;//关闭片选 delay_ms(50); LCD_CS = 0; } /* 函数:写命令 * 参数:uchar cmd:寄存器地址 * 返回:(无) * 说明:RS为低为写寄存器 */ void LCD_WriteCmd(uchar cmd) { LCD_RS = 0;//写命令模 LCD_WriteBus((uint)cmd); } /* 函数:写数据值 * 参数:uint dat:16位的数据 * 返回:(无) * 说明:RS应为高 */ void LCD_WriteData(uint dat) { LCD_RS = 1;//写数据 LCD_WriteBus(dat); } /*uint LCD_ReadData(void) { LCD_RS = 1; return LCD_ReadBus(); } uint LCD_ReadBus(void) { uint ret=0; #ifdef BUS_16 LCD_RD = 0; LCD_RD = 1; ret = LCD_DATA_PORT_HI; ret <<= 8; ret |= LCD_DATA_PORT_LOW; #else LCD_RD = 0; LCD_RD = 1; ret = LCD_DATA_PORT_HI; ret <<= 8; LCD_RD = 0; LCD_RD = 1; ret |= LCD_DATA_PORT_HI; #endif return ret; }*/ /* 函数:写寄存器 * 参数: * uchar cmd:寄存器地址(8位) * uint value:写给寄存器的值(16位) * 返回:(无) */ void LCD_WriteCmdWithData(uchar cmd, uint value) { LCD_WriteCmd((uchar)cmd); //写寄存器地址 LCD_WriteData(value); //写寄存器值 } //把命令/数据向总线写入 void LCD_WriteBus(uint dat) { #ifdef BUS_16 //16位总线模式 LCD_DATA_PORT_HI = (uchar)(dat>>8); LCD_DATA_PORT_LOW = (uchar)dat; LCD_WR = 0; LCD_WR = 1; //S6D1121在每次的WR的上升沿读取数据 #else //此时仅高字节有效 //先写高字节,再写低字节 LCD_DATA_PORT_HI = (uchar)(dat>>8); LCD_WR = 0; LCD_WR = 1; LCD_DATA_PORT_HI = (uchar)dat; LCD_WR = 0; LCD_WR = 1; #endif } /* * 函数:设定写入数据的区域 * 参数: * int x:X坐标(范围:0~239) * int y:Y坐标(范围:0~319) * uint width:宽 * uint height:高 * 返回:(无) * 说明:(x1,y1; x2,y2)两点构成一个矩形 * 设定好区域后,在下一个指令前应该写缓冲区 */ void LCD_SetAddress(uint x, uint y, uint width, uint height) { LCD_WriteCmdWithData(0x46, (x+width-1)<<8|x); //一次性设定x1,x2(高) LCD_WriteCmdWithData(0x47, y+height-1); //y2 LCD_WriteCmdWithData(0x48, y); //y1 LCD_WriteCmdWithData(0x20, x); //设定RAM开始写的地址 LCD_WriteCmdWithData(0x21, y); LCD_WriteCmd(0x22); //设定好写寄存器,开始写 }
女孩不哭(QQ:191035066)@2012-11-26 16:16:55 http://www.cnblogs.com/nbsofer