//LCD1602功能函数 // 51 @ 12MHz //elecfun @ 2010-11-6 //使用方法: 使用前调用Init_LCD1602()初始化,显示方法LCD1602_DispString(0, 0, "This is a test."); #ifndef _LCD1602_ #define _LCD1602_ //#define _PORT_REV_ //如果数据端口高低位交换,请去掉此注释 #include //包含_nop_()指令 sbit LCD1602_RS = P2^4; //控件引脚定义,移植请修改 sbit LCD1602_RW = P2^3; sbit LCD1602_E = P2^2; #define LCD_PORT P1 //输出数据总线端口定义,移植请修改 #define LCD_COMMAND 0 // Command #define LCD_DATA 1 // Data #define LCD_CLEAR_SCREEN 0x01 // 清屏 #define LCD_HOMING 0x02 // 光标返回原点 #define LCD_SHOW 0x04 //显示开 #define LCD_HIDE 0x00 //显示关 #define LCD_CURSOR 0x02 //显示光标 #define LCD_NO_CURSOR 0x00 //无光标 #define LCD_FLASH 0x01 //光标闪动 #define LCD_NO_FLASH 0x00 //光标不闪动 #define LCD_AC_UP 0x02 #define LCD_AC_DOWN 0x00 // default #define LCD_MOVE 0x01 // 画面可平移 #define LCD_NO_MOVE 0x00 //default /********************************************************************************************* 函数名:8位数据高低位交叉互换 调 用:uchar = DataReverse(uchar); 参 数:输入的端口(0000 0XXX 其中XXX是设置输入端口号,可用十进制0~7表示,0表示P1.0,7表示P1.7) 返回值:交换后的8位数据 结 果:交换数据高低位D7→D0,D6→D1.....,D0→D7,并返回交换后的结果 备 注: /**********************************************************************************************/ unsigned char DataReverse(unsigned char datOld) { unsigned char datNew=0,i; for (i=0; i<8; i++) { if (datOld & (1<>i); } return datNew; } /**********************************************************************************************/ /********************************************************************************************* 函数名:LCD1602等待函数 调 用:uchar = LCD_Wait(); 参 数:无 返回值:LCD1602数据总线的值 结 果:等待LCD1602内部指令执行完成 备 注:返回结果可不用 /**********************************************************************************************/ unsigned char LCD_Wait(void) { LCD1602_RS = 0; LCD1602_RW = 1; _nop_(); LCD1602_E = 1; _nop_(); #ifdef _PORT_REV_ //如果数据线高低位交换,则需要处理数据 while(DataReverse(LCD_PORT)&0x80); LCD1602_E = 0; return DataReverse(LCD_PORT); #else //正常情况下不需要交换 while(LCD_PORT&0x80); LCD1602_E = 0; return LCD_PORT; #endif } /**********************************************************************************************/ /********************************************************************************************* 函数名:LCD1602数据写函数 调 用:LCD_Wait(bit, uchar); 参 数:数据类型,数据值 返回值:无 结 果:将指定数据类型的数据写入1602 备 注:数据类型:LCD_COMMAND(0)、LCD_DATA(1) /**********************************************************************************************/ void LCD_Write(bit DataStyle, unsigned char DAT) { LCD1602_E = 0; LCD1602_RS = DataStyle; LCD1602_RW = 0; _nop_(); #ifdef _PORT_REV_ LCD_PORT = DataReverse(DAT); #else LCD_PORT = DAT; #endif _nop_(); LCD1602_E = 1; _nop_();//注意顺序 LCD1602_E = 0; _nop_(); LCD_Wait(); //等待1602内部执行完,Proteus仿真时请注释此句 } /**********************************************************************************************/ /********************************************************************************************* 函数名:LCD1602显示设置函数 调 用:LCD_SetDisplay(uchar); 参 数:显示模式 返回值:无 结 果:正常设置1602显示模式 备 注:内部函数,初始化时调用 /**********************************************************************************************/ void LCD_SetDisplay(unsigned char DisplayMode) { LCD_Write(LCD_COMMAND, 0x08|DisplayMode); } /**********************************************************************************************/ /********************************************************************************************* 函数名:LCD1602显示设置函数 调 用:LCD_SetInput(uchar); 参 数:显示模式 返回值:无 结 果:正常设置1602显示模式 备 注:内部函数,初始化时调用 /**********************************************************************************************/ void LCD_SetInput(unsigned char InputMode) { LCD_Write(LCD_COMMAND, 0x04|InputMode); } /**********************************************************************************************/ /********************************************************************************************* 函数名:LCD1602初始化函数 调 用:Init_LCD1602(); 参 数:无 返回值:无 结 果:初始化1602函数 备 注: /**********************************************************************************************/ void Init_LCD1602() { LCD_Write(LCD_COMMAND, 0x38); //8位数据端口,2行显示,5*7点阵 LCD_Write(LCD_COMMAND, 0x38); LCD_Write(LCD_COMMAND, 0x38); LCD_SetDisplay(LCD_SHOW | LCD_NO_CURSOR); //开启显示, 无光标 LCD_Write(LCD_COMMAND, LCD_CLEAR_SCREEN); //清屏 LCD_SetInput(LCD_AC_UP | LCD_NO_MOVE); //AC递增, 画面不动 } /**********************************************************************************************/ /********************************************************************************************* 函数名:LCD1602数据写函数 调 用:LCD1602_DispString(uchar, uchar, *uchar); 参 数:x坐标,y坐标,字符串 返回值:无 结 果:在指定坐标显示字符串 备 注:x: 0~15; y:0、1 /**********************************************************************************************/ void LCD1602_DispString(unsigned char x, unsigned char y, unsigned char *s) { if(y == 0) LCD_Write(LCD_COMMAND, 0x80|x); if(y == 1) LCD_Write(LCD_COMMAND, 0x80|(x-0x40)); while(*s != '\0') { LCD_Write(LCD_DATA, *s); s++; } } /**********************************************************************************************/ #endif