/**************************************************/
/*硬件说明:CS,SID,SCLK,PSB,RES分别为LCM12864的片选端
串行数据口、串行时钟口、串并通讯选择口、复位口,以下
程序直接用这些字母表示,实用是要注意定义好单片机*/
/*************************************************/
#include <stdio.h>
#include <reg51.h>
#include <string.h>
sbit CS = P0^0; //串行片选端
sbit SID =P0^1; //串行数据口
sbit SCLK=P0^2; //串行时钟
sbit PSB =P0^3 ; //串行并行数据选择端
sbit RES =P0^4; //复位
void delaynms(unsigned int di);
void lcm_w_byte(unsigned char bbyte);
void cheak_busy();
void lcm_w_DOT(unsigned char form,unsigned char ddate);
unsigned char lcm_r_date();
void lcm_init();
void lcm_w_LandS(unsigned char x,unsigned char y,unsigned char *ASC);
void lcm_clear(void) ;
void lcm_location_xy(unsigned char x,unsigned char y);
void lcm_funEnable(bit mode) ;
void main()
{
unsigned char code *string="zhangyuchao";
unsigned char code *chinese="张宇超!";
delaynms(40);
lcm_init();
lcm_w_LandS(1,2,string);
lcm_w_LandS(1,1,chinese);
while(1);
}
/*************************************************/
/*延时函数*/
/*************************************************/
void delaynms(unsigned int di)
{
unsigned int da,db;
for(da=0;da<di;da++);
for(db=0;db<10;db++);
}
/*************************************************/
/*发送一个字节的函数(一级函数)
bbyte为要发送的字节*/
/*************************************************/
void lcm_w_byte(unsigned char bbyte)
{
unsigned char i;
CS=1;
for(i=0;i<8;i++)
{
SCLK=0;
SID=(bbyte&0x80)/128; /*取最高位*/
SCLK=1;
SCLK=0;
bbyte=(bbyte<<1);/*左移一位*/
}
}
/**********************************************/
/*忙0状态检测函数(二级函数)
busy返回值为1;反之为0*/
/*********************************************/
void cheak_busy()
{
lcm_w_byte(0xfc);//输入指令
do {lcm_r_date();}//返回值判断
while(0x80&lcm_r_date());
}
/*********************************************/
/*写指令或数据函数(三级函数)
form=0x00为写指令,form=0x01为写数据,
其中RW,RS分别为00、01
ddate为原始数据,通过函数封装为通信协议格式
*/
/*********************************************/
void lcm_w_DOT(unsigned char form,unsigned char ddate)
{
unsigned char form_date,Hdate,Ldate;
form_date=((form<<1)|0xf8);//计算出格式的式
Hdate=ddate&0xf0; //高四位
Ldate=(ddate<<4)&0xf0; //低四位
cheak_busy();
lcm_w_byte(form_date);//发送
lcm_w_byte(Hdate);
lcm_w_byte(Ldate);
}
/**************************************************/
/*读一字节数据函数(三级函数)
返回一字节数据*/
/**************************************************/
unsigned char lcm_r_date()
{
unsigned char i,temp1,temp2;
temp1=temp2=0;
for(i=0;i<8;i++) //高4位
{
temp1=temp1<<1;
SCLK=0;
SCLK= 1;
SCLK= 0;
if(SID) temp1++;
}
for(i=0;i<8;i++) //低4位
{
temp2=temp2<<1;
SCLK = 0;
SCLK = 1;
SCLK = 0;
if(SID) temp2++;
}
return ((0xf0&temp1)+(0xf0&temp2)/16);
}
/************************************************/
/*初始化显示屏函数(四级函数)*/
/************************************************/
void lcm_init()
{
RES=1;
PSB=0;
CS=1;
lcm_w_DOT(0x00,0x30);
lcm_w_DOT(0x00,0x30); //发送指令30H,设置使用8位控制界面
lcm_w_DOT(0x00,0x0c); //发送指令0CH,整体显示ON,并默认不显示光标
lcm_w_DOT(0x00,0x01); //发送指令01H,清屏
delaynms(40) ;
lcm_w_DOT(0x00,0x06); //发送指令06H,设置显示光标自动右移
}
/*****************************************************/
/*输入位置和字符串*/
/*****************************************************/
void lcm_w_LandS(unsigned char x,unsigned char y,unsigned char *ASC)
{
while((*ASC) !='/0') //判断字是否结束
{ if(8==x)
{x=0;
y++;}
if(4==y)
break;
lcm_location_xy(x,y);
lcm_w_DOT(0x01,*ASC); //向lcd写入字符串
ASC++;
if((*ASC)=='/0')
break;
lcm_w_DOT(0x01,*ASC); //向lcd写入字符串
ASC++;
x++; //移下一个字符
}
}
/*************************************************************/
/*设置扩展指令集模式,mode=1则进入,0则退出*/
/************************************************************/
void lcm_funEnable(bit mode)
{
if(mode)
lcm_w_DOT(0x00,0x34); //发送指令34H
else
lcm_w_DOT(0x00,0x30); //发送指令30H
}
/*************************************************************/
/*液晶屏清屏*/
/*************************************************************/
void lcm_clear(void)
{
lcm_w_DOT(0x00,0x01);//发送指令01H
}
/**************************************************/
/*设置光标位置(四级函数)
其中x和y为行和列的参数;x=0~7,y=0~3*/
/**************************************************/
void lcm_location_xy(unsigned char x,unsigned char y)
{ unsigned char aaa,bbb;
aaa=x;bbb=y;
switch(y)
{
case 0:
y=0x80;break;
case 1:
y=0x90;break;
case 2:
y=0x88;break;
case 3:
y=0x98;break;
default:
break;
}
x=x&0x07;
lcm_w_DOT(0x00,0x30);
lcm_w_DOT(0x00,x+y);
x=aaa;y=bbb;
}