/***************************************************
指令集
[1] RS RW = 0 0
+ 00000001 : 清屏 1.64us
+ 0000001* : 归位 1.64us
+ 000001AB : 输入方式设置 40us
+ A=0 位置-1 A=1 位置+1
+ B=0 画面不动 B=0 画面平移
+ 00001ABC : 显示开关设置 40us
+ A=0 显示关 A=1 显示开
+ B=0 光标关 B=1 光标开
+ C=0 闪烁关 C=1 闪烁开
+ 0001AB** : 光标画面位移 40us
+ A=0 光标平移 A=1 画面平移
+ B=0 左移 B=1 右移
+ 001ABC** : 功能设置 40us
+ A=0 4位数据 A=1 8位数据
+ B=0 一行显示 B=1 两行显示
+ C=0 5X7点阵 C=1 5X10点阵
+ 01ABCDEF : CGRAM 设置 40us
+ A~F=0~3FH
+ 1ABCDEFG : DDRAM 设置 40us
+ 一行显示 0~4FH
+ 两行显示 0~2FH 40H~67H
[2] RS RW = 0 1 40us
+ XA~G : 读BF及AC值
+ X=0 准备好 X=1 忙
+ AC只为最近一次地址设置
[3] RS RW = 0 1 40us
+ A~H :写数据
[4] RS RW = 1 1 40us
+ A~H :读数据
******************************************************/
#include <intrins.h>
#define LCD_IO P0 //IO端口
typedef unsigned char uchar;
typedef unsigned int uint;
typedef bit bool;
sbit rs = P2^4; //复位端
sbit rw = P2^5; //写数据端
sbit ep = P2^6; //使能端
void delayms(uint ms);
bool lcd_busy(void);
void lcd_wcmd(uint cmd) ;
void lcd_wdat(uchar dat);
void lcd_pos(uint pos);
void lcd_init(void);
void lcd_setxy(uint x,uint y);
/*******************延时函数********************/
void delayms(uint ms)
{
uint i;
while(ms--)
{
for(i = 0; i< 250; i++)
{
_nop_();
_nop_(); //空执行消耗CPU时间达到等待的效果
_nop_();
_nop_();
}
}
}
/*******************LCD侧忙函数********************/
bool lcd_busy(void)
{
bool result;
rs = 0;
rw = 1;
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bool)(P0 & 0x80); //检测P0最高位是否为1
ep = 0;
return result;//返回侧忙结果
}
void lcd_wcmd(uint cmd)
{ // 写入指令数据到LCD
while(lcd_busy());
rs = 0;
rw = 0;
ep = 0;
_nop_();
_nop_();
P0 = cmd; //将8位指令通过P0口传给1602
_nop_();
_nop_();//用于产生一个脉冲宽度
_nop_();
_nop_();
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 0;
}
void lcd_pos(uint pos)
{ //设定显示位置
lcd_wcmd(pos | 0x80);
}
void lcd_setxy(uint x,uint y)
{
lcd_wcmd( 0x80 | ((y-1) ? 0x39+x : x-1));
}
void lcd_wdat(uchar dat)
{ //写入字符显示数据到LCD
while(lcd_busy());
rs = 1;
rw = 0;
ep = 0;
P0 = dat;//将8位数据通过P0口传给1602
_nop_();
_nop_();
_nop_(); //用于产生一个脉冲宽度
_nop_();
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 0;
}
void lcd_init(void)
{ //LCD初始化设定
lcd_wcmd(0x38); ////16*2显示,5*7点阵,8位数据
delayms(1);
lcd_wcmd(0x0c); //显示开,关光标
delayms(1);
lcd_wcmd(0x06); //移动光标
delayms(1);
lcd_wcmd(0x01); //清除LCD的显示内容
delayms(1);
}