这里是用的并行写法,后续会更新串行 。并行缺点就是太占用io口了,我其实更喜欢用串行。不过不是比赛要求都不怎么用了。
lcd12864.c
#include"lcd12864.h"
uchar code num[]={"0123456789 e:.-"};
sbit RS = P3^5; //命令/数据选择
sbit RW = P3^6; //读写口
sbit E = P3^4; //使能端
sbit PSB = P3^7; //串并选择
void delay(uint t)
{
uint i;
while(t--)
for(i=0;i<110;i++);
}
bit busy() //查忙
{
bit result;
P0=0X00;
RS=0; //命令/数据选择,为0时选择命令
RW=1; //读/写选择,为1时选择读
E=1; //使能
delay(1);
result = (bit)(P0&0x80); //查忙标志位,等待标志位为0,即表示写入完毕
E=0; //关闭读写
return (result);
}
void wcode(uchar cmd) //向lcd写一命令
{
while(busy()); //查忙
RS=0; //命令/数据选择,为0时选择命令
RW=0; //读/写选择,为0时选择写
E=0;
_nop_();
_nop_();
P0=cmd; //送入命令
delay(1); //等待
E=1;
delay(1);
E=0;
}
void wdata(uchar dat) //向LCD写一数据
{
while(busy());
RS=1; //H为数据
RW=0;
E=0;
P0=dat;
delay(1);
E=1;
delay(1);
E=0;
}
void initlcd() //LCD初始化
{
PSB=1; //设置为8BIT并口工作模式 H并行 L串行
delay(10);
wcode(0x34);
delay(5);
wcode(0x30); //选择基本指令集
delay(5);
wcode(0x0c); //开显示,无游标
delay(5);
wcode(0x01); //清除显示,并且设定地址指针为00H
delay(5);
wcode(0x06); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位
}
void dis(uchar x,uchar y,uchar code *s) //任意位置显示字符串
{ //x为横坐标,y位纵坐标,*s表示指针,为数据的首地址
switch(y) //选择纵坐标
{
case 0:wcode(0x80+x);break; //第一行
case 1:wcode(0x90+x);break; //第二行
case 2:wcode(0x88+x);break; //第三行
case 3:wcode(0x98+x);break; //第四行
default:break;
}
while(*s>0) //写入数据,直到数据为空
{
wdata(*s); //写数据
delay(10); //下一字符
s++;
}
}
void showGB(uchar *HZ) //显示单个汉子
{
wdata(HZ[0]); //写入汉字高八位数据
wdata(HZ[1]); //写入低八位
}
void wrnum(uchar s)
{
wdata(num[s]);
delay(1);
}
数据口D0-D7统一接的P0-P7端。
比赛设备提供的连线破图……烂画质(自己不重画了,将就看吧hh)
lcd12864.h
#ifndef __LCD12864_H_
#define __LCD12864_H_
#include<reg51.h>
#include<intrins.H>
#define uchar unsigned char
#define uint unsigned int
extern void delay(uint t);
extern bit busy();
extern void wcode(uchar cmd);
extern void wdata(uchar d);
extern void initlcd();
extern void dis(uchar x,uchar y,uchar code *s);
extern void showGB(uchar *HZ);
#endif
如果换成其他单片机芯片话,速度可能不同,导致时序就不一样,需要自行更改延时。