这是我接触的第一块彩屏哦~~
如果有用这个芯片的, 可能会有些方便, 也方便交流下使用经验.
这里总共分4个文件:
common.c,common.h:一些公共的包含与定义,函数
s6d1121.c,s6d1121.h:主控芯片驱动程序
这里只是驱动,关于图形接口将在下一篇文章中贴出代码.
该代码仅供51单片机测试使用, 需要大量的优化, 我已经把优化后的代码移植到MSP430上去了.
由于51刷屏太慢,加上没时间,所以没有更新51版本的源代码,见谅~
//common.h - 一些公用的定义,函数等
#ifndef __COMMON_H__
#define __COMMON_H__
#include
#include
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接口
#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
* 作者:女孩不哭
* 说明:这里是底层驱动程序,用户不应该随便调用
* 请调用编写的图形接口程序
*/
#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); //设定好写寄存器,开始写
}