t6963驱动调试通过,个人感觉很好移植(M128)
最近一段时间,间断的搞了一下T6963 240*128的屏。 开始在坛子里面找了一个坛友JIMO转载的一个驱动。后来发现如果要移植的话觉的很麻烦。我用的是ICC的编译环境,ICC不支持位域。
这个程序已经调试过了,大家放心的用,能像51那样定义引脚直接操作,移植的时候改引脚定义就行。很方便。
当时搞的时候出了点小问题。感谢老孟,UNIWERSAL指导。
下面把程序贴出来:
/***********************************************************
内置T6963C液晶控制器驱动程序(间接方式)
***********************************************************/
#define uchar unsigned char
#define uintunsigned int
/******************************/
typedef struct _bit_struct
{
unsignedbit0 : 1 ;
unsignedbit1 : 1 ;
unsignedbit2 : 1 ;
unsignedbit3 : 1 ;
unsignedbit4 : 1 ;
unsignedbit5 : 1 ;
unsignedbit6 : 1 ;
unsignedbit7 : 1 ;
}bit_field;
/************引脚定义(可根据自己的硬件修改)*********/
#definePORT (*((volatilebit_field *) (&PORTC)))
#define CD PORT.bit4
#define RD PORT.bit3
#define WR PORT.bit2
#define Lcd_Date PORTA
#define R_Lcd_Date PINA
#define Lcd_In_Out DDRA
/****************************************************/
//读取LCD状态字
uchar readstate(void)
{
uchar lcd_state;
Lcd_In_Out=0x00;
CD=1;
RD=0;
lcd_state=R_Lcd_Date&0xff; // 读取引脚A物理电平
NOP();
NOP();
RD=1;
return lcd_state;
}
//判断指令(数据)读写状态
void st01(void)
{
while((readstate()&0x03)!=3)
;
}
//判断数据自动读状态
void st2(void)
{
while((readstate()&0x04)!=4)
;
}
//判断数据自动写状态
void st3(void)
{
while((readstate()&0x08)!=8)
;
}
//指令写入函数
void writecode(uchar comd0)
{
st01();
Lcd_In_Out=0xff; //A口方向为输出
Lcd_Date=comd0; //送数据到A口寄存器
WR=0;
NOP();
WR=1;
}
//数据写入函数
void writedata(uchar onedata)
{
st01();
CD=0;//,数据通道
Lcd_In_Out=0xff; //A口方向为输出
Lcd_Date=onedata;//送数据到A口寄存器
WR=0;
NOP();
WR=1;
}
//数据自动写入函数
void writeauto(uchar onedata)
{
st3();
CD=0;//,数据通道
Lcd_In_Out=0xff; //A口方向为输出
Lcd_Date=onedata;//送数据到A口寄存器
WR=0;
NOP();
WR=1;
}
//一字节参数指令写入函数
void oneparameter(uchar onep1,uchar comd1)
{
writedata(onep1);
writecode(comd1);
}
//两字节参数指令写入函数
void twoparameter(uchar twop1,uchar twop2,uchar comd2)
{
writedata(twop1);
writedata(twop2);
writecode(comd2);
}
/***********************************************************
液晶初始化,清屏
***********************************************************/
//内置T6963C控制器液晶初始化函数
void lcd_init(void)
{
twoparameter(0x00,0x00,0x40);//文本显示区域首地址0x0000
twoparameter(0x20,0x00,0x41);//文本显示区域宽度32字节
twoparameter(0x00,0x08,0x42);//图形显示区域首地址0x0800
twoparameter(0x20,0x00,0x43);//图形显示区域宽度32字节
writecode(0xa7);//光标形状
writecode(0x80);//显示方式设置(使用内部CGROM,逻辑或合成)
writecode(0x9c);//显示开关(开文本和图形显示方式,禁止光标显示和闪烁)
}
//清除屏幕(清所有8K存储空间)
void lcd_clear(void)
{
uint cl_count;
twoparameter(0x00,0x00,0x24);//设置显示存储器首地址
writecode(0xb0);//设置自动写状态
for(cl_count=8192;cl_count>0;cl_count--)
writeauto(0x00);
writecode(0xb2);//关闭自动写状态
}
/********************************************************
西文字符,汉字,点阵显示函数
********************************************************/
//西文字符写入函数
//x_asc:0~29;y_asc:0~15
void writeasc(uchar x_asc,uchar y_asc,uchar code_asc)
{
uint address;
address=y_asc*32+x_asc;
twoparameter((uchar)(address),(uchar)(address>>8),0x24);//设置显示存储器地址
oneparameter(code_asc,0xc4);//装入字符代码,写入数据,地址不变
}
//显示一个点函数
//x:0~239;y:0~127(消除点)128~255(显示点)
void writepoint(uchar x,uchar y)
{
uchar x_pt,y_pt;
uint address;
x_pt=x;
y_pt=y;
address=(y_pt&0x7f)*32+x_pt/8+0x0800;//计算显示存储器地址
twoparameter((uchar)(address),(uchar)(address>>8),0x24);//设置显示存储器地址
x_pt=(~(x_pt%8))&0x07;
y_pt=((y_pt&0x80)>>4)|0xf0;
writecode(x_pt|y_pt);//写入数据
}
//显示矩形框
//x:0~239;y:0~127
void rectangle(uchar xstar,uchar xend,uchar ystar,uchar yend)
{
uchar i;
ystar+=128;//显示点
yend+=128;
for(i=xstar;i<=xend;i++)//两水平线
{
writepoint(i,ystar);
writepoint(i,yend);
}
for(i=ystar;i<=yend;i++)//两垂直线
{
writepoint(xstar,i);
writepoint(xend,i);
}
}
//擦除矩形框
//x:0~239;y:0~127
void clrrect(uchar xstar,uchar xend,uchar ystar,uchar yend)
{
uchar i;
for(i=xstar;i<=xend;i++)//两水平线
{
writepoint(i,ystar);
writepoint(i,yend);
}
for(i=ystar;i<=yend;i++)//两垂直线
{
writepoint(xstar,i);
writepoint(xend,i);
}
}
//8*8点阵显示
//x:0~239;y:0~127
void disp88(uchar x,uchar y, const uchar *ptr0)
{
uchar i,datpt,x_temp,y_temp;
y_temp=y;
for(i=8;i>0;i--)
{
datpt=*ptr0++;//取数据
x_temp=x;//重装x值
if(datpt&0x80)
writepoint(x_temp++,(y_temp+128));
else writepoint(x_temp++,y_temp);
if(datpt&0x40)
writepoint(x_temp++,(y_temp+128));
else writepoint(x_temp++,y_temp);
if(datpt&0x20)
writepoint(x_temp++,(y_temp+128));
else writepoint(x_temp++,y_temp);
if(datpt&0x10)
writepoint(x_temp++,(y_temp+128));
else writepoint(x_temp++,y_temp);
if(datpt&0x08)
writepoint(x_temp++,(y_temp+128));
else writepoint(x_temp++,y_temp);
if(datpt&0x04)
writepoint(x_temp++,(y_temp+128));
else writepoint(x_temp++,y_temp);
if(datpt&0x02)
writepoint(x_temp++,(y_temp+128));
else writepoint(x_temp++,y_temp);
if(datpt&0x01)
writepoint(x_temp++,(y_temp+128));
else writepoint(x_temp++,y_temp);
y_temp++;
}
}
//16*8点阵显示
//x:0~29;y:0~127
void disp168(uchar x,uchar y,const uchar *ptr0)
{
uchar i;
uint address;
address=y*32+x+0x0800;//计算显示存储器地址
for(i=8;i>0;i--)
{
twoparameter((uchar)(address),(uchar)(address>>8),0x24);//设置显示存储器地址
oneparameter(*ptr0++,0xc0);//点阵左部
oneparameter(*ptr0++,0xc0);//点阵右部
address+=32;//修改显示存储器地址
}
}
//连续写点阵
//x:0~29;y:0~127
void dispauto(uchar x,uchar y,uchar line,uchar column,const uchar *ptr0)
{
uchar i,j;
uint address;
address=y*32+x+0x0800;//计算显示存储器地址
for(i=line;i>0;i--)//显示line行
{
twoparameter((uchar)(address),(uchar)(address>>8),0x24);//设置显示存储器地址
writecode(0xb0);//数据自动写状态
for(j=column;j>0;j--)//共column列
{
writeauto(*ptr0++);//自动写入数据
}
writecode(0xb2);//关闭自动写状态
address+=32;//修改显示存储器地址
}
} 自己顶一个。 楼主上图吧
哈哈 , 无图无真相啊 这样做更方便
#define LCD_C_ADD (*(volatile unsigned char *)0xfd00)//指令地址
#define LCD_D_ADD (*(volatile unsigned char *)0xfc00)//数据地址
--------------------------------------------------------------------
//**********************读状态字**********************//
void LcdTest(void)
{
uchar temp=0;
do
{
temp = (LCD_C_ADD)&0x03 ;
}
while(temp!=0x03);//直到数据、指令读写状态准备好
}
//****************************************************
void LcdTest1(void)//数据自动写状态 准备好
{
uchar temp;
do
{
temp = (LCD_C_ADD)&0x08 ;
}
while(temp!=0x08);//
}
//****************************************************
void LcdTest2(void) //数据自动读状态准备好
{
uchar temp;
do
{
temp = (LCD_C_ADD)&0x04 ;
}
while(temp!=0x04);
}
//******************************************************
void LcdWrdat(uchar dat1 )//写数据,一个数据
{
LcdTest();
delay1us(5);
LCD_D_ADD = dat1;
asm("nop");
}
//*******************************************************
void LcdWrdat1(uchar dat1 )//数据自动写,之前检验状态位
{ asm("nop");
LcdTest1();
delay1us(5);
LCD_D_ADD = dat1;
asm("nop");
}
//*******************************************************
voidLcdWrcon(uchar dat1 )//写指令
{
LcdTest();
delay1us(5);
LCD_C_ADD = dat1;
asm("nop");
}
//****************************************************
void LcdInit(void)// 液晶初始化程序
{
LcdWrdat(0x10); //文本区一行16字节
LcdWrdat (0x00);
LcdWrcon (0x41);//设置文本区宽度:16字节/行
//LcdWrdat (0);
//LcdWrdat (0x08);
//LcdWrcon (0x42);
//LcdWrdat(0x10);
//LcdWrdat (0x00);
//LcdWrcon (0x43);
//LcdWrcon (0x88);
}
//******************************************************
void LcdClear(void) // 清屏8K
{
uint i;
i = 8193;//8193
LcdWrdat (0x00);
LcdWrdat (0x00);
LcdWrcon (0x24);//地址指针设置为0000
LcdWrcon (0xb0); //自动写设置
asm("nop");
do
{
LcdWrdat1(0);//数据自动写0x00
}
while( --i != 0 );
LcdWrcon (0xb2); //数据自动写结束
// dog();
}
利用m128的总线接口,驱动T6963C,速度是很快的。可惜T6963C没有字库,用起来不爽,得自己做需要用到的字库,麻烦很~~~~~~~~~~ 回老孟:你这是挂到总线的写法吧?你太有才了……
回RENMA:
/************引脚定义(可根据自己的硬件修改)*********/
#definePORT (*((volatilebit_field *) (&PORTC)))
#define CD PORT.bit4
#define RD PORT.bit3
#define WR PORT.bit2
#define Lcd_Date PORTA
#define R_Lcd_Date PINA
#define Lcd_In_Out DDRA
/****************************************************/
C口有3位是控制线,A口是数据线
LCD接法是接的最简单的那种
我的是21PIN的
接法如下:
1角 FG 接GND边框地 VCC
2角VSS 接GND地 |
3角VDD 接VCC V0---->|
|
VEE
4角V0如图(调分辨率)
5角 WR
6角 RD
7角 CE 片选,接GND
8角 CD
9角RST 接VCC
10---17角DB0--DB1 数据线
18角 FS H=8*16L=8*8我接的是GND
19角 VEE如图
20角 A接VCC
21角 未定义,接GND 正在用这个
标记下,谢谢 标记下,谢谢
页:
[1]