怎么才能把单片机里的数据在LCD上显示

allen30   2007-4-12 16:05 楼主
小弟初学单片机,对芯片如何调用LCD控制器一窍不通,写了个程序进单片机毫无反映
芯片是AT89c55,LCD是VTM12864D2
rs(DI) equ p11
e  equ p10
r/w equ 0(接地)
cs1 equ p3.3
cs2 equ p3.2
rest equ p3.4
DB1~7 equ p0.0~7
请问如何才能在显示器上显示字母等等
控制器是ks0107,ks0108
单片机怎样初始化LCD并使其有显示忘高手指教不胜感激

回复评论 (10)

LCD控制都是那么个流程.
初始化->写指令,传数据->传命令

这就完成显示了.
呵呵,具体的驱动,得好好看驱动芯片.
点赞  2007-4-12 16:11
LZ可以网上找找

12864 液晶程序

满世界都是
点赞  2007-4-12 16:21
DataSheet
点赞  2007-4-12 16:28
#include "absacc.h"
#include "intrins.h"

//自定义库 在"C:\comp51\UserLib\"文件夹中
#include ".\inc\ASCII816.h" //标准ASCII库
#include ".\inc\HZTable.h" //汉字点阵库(自做)
#include ".\inc\Menu.h" //菜单库(自做)


// LCD128*64 数据线
#define LCD12864DataPort P1

// LCD128*64 I/O 信号管脚
sbit di =P3^1; // 数据\指令 选择
sbit rw =P3^3; // 读\写 选择
sbit en =P3^2; // 读\写使能
sbit cs1 =P3^4; // 片选1,低有效(前64列)
sbit cs2 =P3^5; // 片选2,低有效(后64列)

sbit reset=P0^7; // 复位

//开关显示
void SetOnOff(unsigned char onoff)

//选择屏幕
//screen: 0-全屏,1-左屏,2-右
void SelectScreen(unsigned char screen)

//清屏
//screen: 0-全屏,1-左屏,2-右
void ClearScreen(unsigned char screen)

//显示8*8点阵
//旋转90度:字模被竖着切分
//lin:行(0-7), column: 列(0-15)
//address : 字模区首地址
void Show88(unsigned char lin,unsigned char column,unsigned int address)

//显示8*16字符
//旋转90度:字模被竖着切分
//lin:行(0-3), column: 列(0-15)
//character:字符代码(标准ASCII码)
void ShowChar(unsigned char lin,unsigned char column,unsigned char character)

//显示8*16字符串
//!!!只能显示在一行上即: 串长+column <=15
//旋转90度:字模被竖着切分
//lin:行(0-3), column: 列(0-15)
//address : 字模区首地址
void ShowString(unsigned char lin,unsigned char column, unsigned char *string)

//显示一个汉字
//旋转90度:字模被竖着切分
//lin:行(0-3), column: 列(0-15)
//hzcode: 汉字代码(自定义的)
void ShowHZ(unsigned char lin,unsigned char column,unsigned int hzcode)

//显示图片
//旋转90度 :字模被竖着切分
//startline :开始行
//startcolumn:开始列
//linechar :图片行点除8(图片以8*8点阵为单位)
//columnchar :图片列点除8(图片以8*8点阵为单位)
//address : 字模区首地址
void ShowPicture(unsigned char startline,unsigned char startcolumn,unsigned char linechar,unsigned char columnchar,unsigned int address)
//!!问题大户
//显示一行汉字
//lin:行
//lineheadaddr: 此行汉字代码区首地址
void ShowLine(unsigned char lin,unsigned int lineheadaddr)

//显示一屏汉字
//pageheadaddr:此屏汉字代码地址区首地址
void ShowPage(unsigned int pageheadaddr)

//反显一个8*8字块
//lin:行(0-3), column: 列(0-7)
void ReverseShow88(unsigned char lin,unsigned char column)


//反显一个字符
//lin:行(0-4), column: 列(0-15)
void ReverseShowChar(unsigned char lin,unsigned char column)


//反显一个汉字
//lin:行(0-3), column: 列(0-7)
ReverseShowHZ(unsigned char lin,unsigned char column)

//反显一行汉字
//lin:行
ReverseShow(unsigned char lin)

//初始化LCD
void InitLCD()

//延时
Lcd12864delay()
{
unsigned int i=500;
while(i--) {;}
}

//状态检查
void CheckState()
{
unsigned char dat;
di=0;
rw=1;
do{
LCD12864DataPort=0xff;
en=1; dat=LCD12864DataPort; en=0;
dat=0x90 & dat; //仅当第4,7位为0时才可操作
}while(!(dat==0x00));
}

//写显示数据
//dat:显示数据
void WriteByte(unsigned char dat)
{
CheckState();
di=1; rw=0;
LCD12864DataPort=dat;
en=1; en=0;
}

//向LCD发送命令
//command :命令
SendCommandToLCD(unsigned char command)
{
CheckState();
rw=0;
LCD12864DataPort=command;
en=1; en=0;
}

//设定行地址(页)--X 0-7
void SetLine(unsigned char line)
{
line=line & 0x07; // 0<=line<=7
line=line|0xb8; //1011 1xxx
SendCommandToLCD(line);
}
//设定列地址--Y 0-63
void SetColumn(unsigned char column)
{
column=column &0x3f; // 0= column=column | 0x40; //01xx xxxx
SendCommandToLCD(column);
}
//设定显示开始行--XX
void SetStartLine(unsigned char startline) //0--63
{
startline=startline & 0x07;
startline=startline|0xc0; //1100 0000
SendCommandToLCD(startline);
}
//开关显示
void SetOnOff(unsigned char onoff)
{
onoff=0x3e | onoff; //0011 111x
SendCommandToLCD(onoff);
}

//选择屏幕
//screen: 0-全屏,1-左屏,2-右屏
void SelectScreen(unsigned char screen)
{ //北京显示器:负有效 cs1: 0--右; cs2: 0--左
switch(screen)
{ case 0: cs1=0;//全屏
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
cs2=0;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
break;
case 1: cs1=1;//左屏
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
cs2=0;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
break;
case 2: cs1=0;//右屏
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
cs2=1;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
break;
}
}

//清屏
//screen: 0-全屏,1-左屏,2-右
void ClearScreen(unsigned char screen)
{ unsigned char i,j;
SelectScreen(screen);
for(i=0;i<8;i++)
{ SetLine(i);
for(j=0;j<64;j++)
{
WriteByte(0x00);
}
}
}

//显示8*8点阵
//旋转90度:字模被竖着切分
//lin:行(0-7), column: 列(0-15)
//address : 字模区首地址
void Show88(unsigned char lin,unsigned char column,unsigned int address)
{ unsigned char i;
if(column>16) {return;}
if(column<8) SelectScreen(1); //如果列数<8(0,1,2,3,4,5,6,7)则写在第一屏上
else {
SelectScreen(2); //否则 (8,9,10,11,12,13,14,15)写在第二屏上
column=column & 0x07; //防止越界
}
SetLine(lin);
SetColumn(column<<3);
for(i=0;i<8;i++) WriteByte( CBYTE[address+i] );
}

//显示8*16字符
//旋转90度:字模被竖着切分
//lin:行(0-3), column: 列(0-15)
//character:字符代码(标准ASCII码)
void ShowChar(unsigned char lin,unsigned char column,unsigned char character)
{ lin=lin<<1;
Show88(lin ,column,ASCII816[character-0x20] );
Show88(lin+1,column,ASCII816[character-0x20]+8 );
}

点赞  2007-4-12 16:30
/*
//显示8*16字符串
//!!!只能显示在一行上即: 串长+column <=15
//旋转90度:字模被竖着切分
//lin:行(0-3), column: 列(0-15)
//address : 字模区首地址
void ShowString(unsigned char lin,unsigned char column, unsigned char *string)
{ unsigned char ch;
unsigned char i=0;

while(*string!='\0')
{
ch=*string;
if(i+column >15) break; //(只能显示在一行上即: 串长+column <=15)
ShowChar(lin,i+column,ch);
string++; i++;
}
}
*/

//显示一个汉字
//旋转90度:字模被竖着切分
//lin:行(0-3), column: 列(0-7)
//hzcode: 汉字代码(自定义的)
//uchar code HZtable
void ShowHZ(unsigned char lin,unsigned char column,unsigned int hzcode)
{
lin=lin<<1; //lin*2

Show88(lin,column,HZTable[hzcode]);
Show88(lin,column+1,HZTable[hzcode]+8);
Show88(lin+1,column,HZTable[hzcode]+16);
Show88(lin+1,column+1,HZTable[hzcode]+24);
}

//显示图片
//旋转90度 :字模被竖着切分
//startline :开始行
//startcolumn:开始列
//linechar :图片行点除8(图片以8*8点阵为单位)
//columnchar :图片列点除8(图片以8*8点阵为单位)
//address : 字模区首地址
void ShowPicture(unsigned char startline,unsigned char startcolumn,unsigned char linechar,unsigned char columnchar,unsigned int address)
{ unsigned char i,j;
for(i=0;i for(j=0;j Show88(startline+i , startcolumn+j , address+(i*linechar+j)*8 );
}

//显示一行字符串(汉字,字母混排,一行16字节)
//lin:行
//lineheadaddr: 此行汉字代码区首地址
void ShowLine(unsigned char lin,unsigned char linehead[])
{ unsigned char i;
unsigned char byte;
unsigned int hzcode;
for( i=0; i<16; )
{ byte=linehead;
if(byte < 0x80) //字母
{
if(i>15) return; //!!编译器有问题,须强制退出

ShowChar(lin, i , byte);
i=i+1;

}
else // byte >= 0x80(汉字)
{
if(i>15) return; //!!编译器有问题,须强制退出

byte=byte & 0x7f; //最高位置0,即:减去0x8000
hzcode=(unsigned int)byte<<8; //?? //高8位
hzcode=hzcode+linehead[i+1]; //加低8位,组合成整型数地址
ShowHZ( lin,i,hzcode);
i=i+2;
}
}
}

//显示一屏汉字
//pageheadaddr:此屏汉字代码地址区首地址
void ShowPage(unsigned char pagehead[][16])
{ unsigned char i;
for(i=0;i<4;i++) ShowLine(i,pagehead); //1行8个汉字,16字节
}

//读显示数据
unsigned char ReadByte()
{
unsigned char dat;
CheckState();
di=1; rw=1;
LCD12864DataPort=0xff;
en=1; dat=LCD12864DataPort; en=0;
return(dat);
}


//反显一个8*8字块
//lin:行(0-3), column: 列(0-7)
void ReverseShow88(unsigned char lin,unsigned char column)
{ unsigned char i;
unsigned char tab[8];

if(column<8) SelectScreen(1); //如果列数<4(0,1,2,3),则写在第一屏上
else SelectScreen(2); //否则 (4,5,6,7), 写在第二屏上
//读上部8列
column=column<<3; //每个方块8*8大小
SetLine(lin);
SetColumn(column);
tab[0]=ReadByte(); //空读!!!!! //?
for(i=0;i<8;i++) tab=~ReadByte();
//写回
SetLine(lin);
SetColumn(column);
for(i=0;i<8;i++) WriteByte(tab);
}

//反显一个字符
//lin:行(0-4), column: 列(0-15)
void ReverseShowChar(unsigned char lin,unsigned char column)
{ lin=lin<<1;
ReverseShow88(lin ,column);
ReverseShow88(lin+1,column);
}

//反显一个汉字
//lin:行(0-3), column: 列(0-7)
ReverseShowHZ(unsigned char lin,unsigned char column)
{
lin=lin<<1;
column=column<<1;
ReverseShow88(lin ,column );
ReverseShow88(lin ,column+1);
ReverseShow88(lin+1,column );
ReverseShow88(lin+1,column+1);
}

//反显一行汉字
//lin:行
ReverseShow(unsigned char lin)
{ unsigned char i;
for(i=0;i<8;i++) ReverseShowHZ(lin,i);
}

void InitLCD() //初始化LCD
{ unsigned char i=250; //延时
while(i--);

//reset=0;//复位
//reset=1;

SelectScreen(0);
SetOnOff(0); //关显示

ClearScreen(1);//清屏
ClearScreen(2);

SelectScreen(0);
SetOnOff(1); //开显示
SelectScreen(0);
SetStartLine(0); //开始行:0
}

void Reset() //液晶复位
{
//reset 低复位 _|-
reset=0;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
reset=1;

//全屏
cs1=0;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
cs2=0;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
SendCommandToLCD(0x3F);

}
点赞  2007-4-12 16:31
/*------------------------------------------------------------------------------------------
[文件名] 12864.c
[功能] 128X64驱动程序
[版本] 2.0
[作者] 鞠春阳
[最后修改时间] 2003年5月12日
[版权所有] www.mcuzb.com
[资料] 请到www.mcuzb.com下载
===========================================================================================*/

补上版权声明,呵呵
点赞  2007-4-12 16:32
谢谢楼上ibing7,主要问题是汇编后的程序写入单片机驱动不了LCD,网上的那些程序套用了但觉得不得要领,没有成功
点赞  2007-4-12 16:32
我现在要求很简单只要能有个汇编程序能点亮LCD显示哪怕显示一个字母也行
点赞  2007-4-12 16:35
程序只是描述的工具,事物的本质没有改变

也就是说,C语言里操作驱动芯片的过程和方式是不变的,你看懂了这个,按这个要求用汇编去操作驱动芯片就OK了,呵呵

点赞  2007-4-12 16:42
恩,谢谢ibing7,看来我得去温习下c语言
点赞  2007-4-12 16:45
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复