三星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

你可能感兴趣的:(bit)