1602液晶驱动
/*************************************************** 指令集 [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); }