51驱动1602液晶显示器的程序
//1602.h #include <reg52.h> //数据类型定义 typedef unsigned char uchar; typedef unsigned int uint; //1602指令定义 //屏幕初始化 #define SCREEN_INIT 0x38 //屏幕设置:16*2行,5*7点阵,8位数据接口 //光标及屏幕显示设置 #define SHOW_SCREEN 0x0C //屏幕显示 #define HIDE_SCREEN 0x08 //屏幕不显示 #define SHOW_CURSOR 0x02 //显示光标 #define FLASH_CURSOR 0x01 //光标闪烁 //地址指针及滚动设置 #define DPTR_INC 0x06 //读/写一个字节地址指针+1,光标+1 #define DPTR_DEC 0x04 //读/写一个字节地址指针-1,光标-1 #define SCREEN_SCR 0x01 //写一个字符,整屏左移/右移 //ADDR设置 #define ADDR_LINE1 0x80 //第一行 #define ADDR_LINE2 0xC0 //第二行 #define LINE1_END 0x10 #define LINE2_END 0x50 //忙碌状态 #define BUSY 0x80 //清屏 #define CLR_SCR 0x01 //清屏 //DPTR清零 #define CLR_DPTR 0x02 //数据指针清零
//1602.c #include <reg52.h> #include <intrins.h> #include "1602.h" //女孩不哭 //2012-10-25 //ts=sts=sw=4 //以下是端口定义,自行修改 sbit RS = P0^0; //数据/指令选择 sbit RW = P0^1; //读/写控制 sbit E = P0^2; //使能 #define DATA P2 //数据端口 P[0~7] -> DATA[0~7] /* 函数:微秒延时 参数: us[uchar]:微秒 返回:(无) */ void delay_us(uchar us) { for(; us>0; us--) _nop_(); } /* 函数:10毫秒延时 参数: ms10[uint]:10毫秒 返回:(无) */ void delay_10ms(uint ms10) { uchar x,y,z; while(ms10--){ for(x=5; x>0; x--); for(y=4; y>0; y--); for(z=248; z>0; z--); } } /* 函数:读取1602状态 参数:(无) 返回:(无) 说明:最高位为忙碌状态位,1代表忙碌 */ uchar read_state(void) { DATA = 0xff; RW = 1; RS = 0; E = 1; return DATA; } /* 函数:执行一条命令 参数: cmd[uchar]:命令 返回:(无) */ void do_cmd(uchar cmd) { while(read_state()&BUSY) _nop_(); RS = 0; RW = 0; DATA = cmd; E = 1; delay_us(50); E = 0; delay_us(50); } /* 函数:1602初始化 参数:(无) 返回:(无) */ void init_lcd(void) { do_cmd(CLR_SCR);//清屏 do_cmd(SCREEN_INIT);//显示模式设置 do_cmd(SHOW_SCREEN|SHOW_CURSOR/*|FLASH_CURSOR*/); do_cmd(DPTR_INC); } /* 函数:写一个字节到显存 参数: ch[uchar]:显示字符ASCII码 返回:(无) */ void write(uchar ch) { uchar addr; while(read_state()&BUSY) ; //换行处理 addr = read_state()&~BUSY; if(addr == LINE1_END) do_cmd(ADDR_LINE2); else if(addr == LINE2_END) do_cmd(ADDR_LINE1); RW = 0; RS = 1; DATA = ch; E = 1; delay_us(50); E = 0; delay_us(50); } void write_str(uchar line, uchar pos, uchar* str) { uchar addr; uchar* ptr; if(line!=1 && line!=2) return;//只能是第1,2行 if(pos>16) return;//只能是第 1~16 个字符 //pos=0表示从当前位置开始写,忽略行 if(pos){ addr = (line==1?ADDR_LINE1:ADDR_LINE2)+pos-1; do_cmd(addr); } for(ptr=str; *ptr; ptr++){ write(*ptr); delay_10ms(80); } } #if 0 void main(void) { uchar str[16] = {0}; uchar x; delay_10ms(10); init_lcd(); write_str(1,1,"012345671"); delay_10ms(200); write_str(2,1,"AbCdEfGhIjK"); delay_10ms(200); write_str(1,1,"Nv Hai Bu Ku!"); delay_10ms(200); do_cmd(CLR_SCR); do_cmd(SHOW_SCREEN|FLASH_CURSOR); write_str(1,1,"this is a very very very long string!"); for(x=0; x<4; x++){ do_cmd(HIDE_SCREEN); delay_10ms(300); do_cmd(SHOW_SCREEN); delay_10ms(300); } do_cmd(SHOW_SCREEN); delay_10ms(200); do_cmd(CLR_SCR); write_str(1,1,"Screen will now Scroll...."); delay_10ms(300); do_cmd(DPTR_INC|SCREEN_SCR); write_str(1,0,"Screen Scrolling"); do_cmd(DPTR_DEC|SCREEN_SCR); write_str(1,0,"Screen Scrolling"); do_cmd(DPTR_INC); delay_10ms(200); do_cmd(CLR_SCR); for(x=0x20; x<0xdf; x++){ write(x); delay_10ms(80); } delay_10ms(200); do_cmd(CLR_SCR); write_str(2,1," ... what??"); for(;;){ } } #endif
女孩不哭(QQ:191035066) @ 2012-11-09 20:02:49 @ http://www.cnblogs.com/nbsofer