自制51单片机常用头文件(LCD1602) C51 2008-09-24 20:11:05 阅读946 评论0 字号:大中小 订阅 /*-------------------------------------------------------------------------- LCD1602.H The user function is C51. Copyright (c) 1988-2004 Keil Elektronik GmbH sum zhaojun All rights reserved. --------------------------------------------------------------------------*/ #ifndef __LCD1602_H__ #define __LCD1602_H__ /*连接线图: --------------------------------------------------- | LCM-----51 | LCM-----51 | LCM------51 | | ----------------------------------------------- | | DB0-----P0.0 | DB4-----P0.4 | RS-------P2.0 | | DB1-----P0.1 | DB5-----P0.5 | RW-------P2.1 | | DB2-----P0.2 | DB6-----P0.6 | E--------P2.2 | | DB3-----P0.3 | DB7-----P0.7 | VLCD接1K电阻到GND | ---------------------------------------------------*/ /****************** LCD1602指令 ***********************************/ //输入方式设置 #define LCD_AC_AUTO_INCREMENT 0x06 // 数据读、写操作后,AC自动增一 #define LCD_AC_AUTO_DECREASE 0x04 // 数据读、写操作后,AC自动减一 #define LCD_MOVE_ENABLE 0x05 // 数据读、写操作,画面平移 #define LCD_MOVE_DISENABLE 0x04 // 数据读、写操作,画面不动 #define LCD_GO_HOME 0x02 // AC=0,光标、画面回HOME位 //设置显示、光标及闪烁开、关 #define LCD_DISPLAY_ON 0x0C // 显示开 #define LCD_DISPLAY_OFF 0x08 // 显示关 #define LCD_CURSOR_ON 0x0A // 光标显示 #define LCD_CURSOR_OFF 0x08 // 光标不显示 #define LCD_CURSOR_BLINK_ON 0x09 // 光标闪烁 #define LCD_CURSOR_BLINK_OFF 0x08 // 光标不闪烁 //光标、画面移动,不影响DDRAM #define LCD_LEFT_MOVE 0x18 // LCD显示左移一位 #define LCD_RIGHT_MOVE 0x1C // LCD显示右移一位 #define LCD_CURSOR_LEFT_MOVE 0x10 // 光标左移一位 #define LCD_CURSOR_RIGHT_MOVE 0x14 // 光标右移一位 //工作方式设置 #define LCD_DISPLAY_DOUBLE_LINE 0x38 // 两行显示 #define LCD_DISPLAY_SINGLE_LINE 0x30 // 单行显示 #define LCD_CLEAR_SCREEN 0x01 // 清屏 /***********************LCD1602地址相关******************************/ #define LINE1_HEAD 0x80 // 第一行DDRAM起始地址 #define LINE2_HEAD 0xc0 // 第二行DDRAM起始地址 #define LINE1 0 // 第一行 #define LINE2 1 // 第二行 #define LINE_LENGTH 8 // 每行的最大字符长度 /***********************LCD1602接线引脚定义**************************/ #define LCM_RS P2_0 // 数据/命令选择信号 #define LCM_RW P2_1 // 读/写选择信号 #define LCM_E P2_2 // 使能信号 #define LCM_Data P0 // 显示数据端口 #define Busy 0x80 // 用于检测LCM状态字中的Busy标识 #define uchar unsigned char #define uint unsigned int //================================ LCM1602控制部分 ========================================================= /***************************************************** 函 数 名:void Delay_LCD(void) 功 能:5ms延时 说 明:LCD显示延时 入口参数:无 返 回 值:无 *****************************************************/ void Delay_LCD(void) { uint TempCyc = 5552; // 放入延时数据 while(TempCyc--) { ; } } /***************************************************** 函 数 名:uchar ReadStatusLCM() 功 能:读忙状态 说 明:判断LCM的工作状态;也可以不用此函数,用一段延时程序代替 入口参数:无 返 回 值:LCM_Data *****************************************************/ //读状态 uchar ReadStatusLCM(void) { LCM_Data = 0xFF; // LCM数据口先置1 LCM_RS = 0; LCM_RW = 1; LCM_E = 0; LCM_E = 0; LCM_E = 1; while (LCM_Data & Busy) // 检测忙信号.如果忙,则不执行 { ; } return (LCM_Data); // 不忙返回读取数据 } /***************************************************** 函 数 名:void WriteDataLCM() 功 能:向LCM1602中写入数据 说 明:将形参WDLCM中的数据写入LCM中 入口参数:WDLCM 返 回 值:无 *****************************************************/ //写数据 void WriteDataLCM(uchar WDLCM) { ReadStatusLCM(); // 检测忙 LCM_Data = WDLCM; // 写入数据到LCM LCM_RS = 1; LCM_RW = 0; LCM_E = 0; // 若晶振速度太高可以在这后加小的延时 LCM_E = 0; // 延时 LCM_E = 1; } /***************************************************** 函 数 名:void WriteCommandLCM() 功 能:向LCM1602中写入指令 说 明:向LCM中写入指令;如果BuysC=0时,忽略忙检测,如果BuysC=1时,不忽略忙检测 入口参数:WCLCM,BuysC 返 回 值:无 *****************************************************/ //写指令 void WriteCommandLCM(uchar WCLCM,BuysC) // BuysC为0时忽略忙检测 { if (BuysC) { ReadStatusLCM(); // 根据需要检测忙 } LCM_Data = WCLCM; // 写入指令 LCM_RS = 0; LCM_RW = 0; LCM_E = 0; LCM_E = 0; LCM_E = 1; } /***************************************************** 函 数 名:void LCMInit() 功 能:初始化LCM1602 说 明:LCM在工作前先要对显示屏初始化,否则模块无法正常工作 入口参数:无 返 回 值:无 *****************************************************/ //LCM初始化 void LCMInit(void) { LCM_Data = 0; WriteCommandLCM(LCD_DISPLAY_DOUBLE_LINE,0); // 三次显示模式设置,不检测忙信号 Delay_LCD(); WriteCommandLCM(LCD_DISPLAY_DOUBLE_LINE,0); // 0x38指令表示:8位数据显示模式,俩行多显示 Delay_LCD(); WriteCommandLCM(LCD_DISPLAY_DOUBLE_LINE,0); Delay_LCD(); WriteCommandLCM(LCD_DISPLAY_DOUBLE_LINE,1); // 显示模式设置,开始要求每次检测忙信号 WriteCommandLCM(LCD_DISPLAY_OFF,1); // 关闭显示 WriteCommandLCM(LCD_CLEAR_SCREEN,1); // 显示清屏 WriteCommandLCM(LCD_AC_AUTO_INCREMENT,1); // 显示光标移动设置 WriteCommandLCM(LCD_DISPLAY_ON,1); // 显示开及光标设置 } /***************************************************** 函 数 名:void DisplayOneChar() 功 能:按指定坐标中写入数据 说 明:X-横坐标,Y-纵坐标,DData为ASCII值 入口参数:X,Y,DData 返 回 值:无 *****************************************************/ //按指定位置显示一个字符 void DisplayOneChar(uchar X, uchar Y, uchar DData) { Y &= 0x01; X &= 0x0F; // 限制X不能大于15,Y不能大于1 if (Y) { X |= LINE2_HEAD; // 当要显示第二行时地址码:0xc0 } X |= LINE1_HEAD; // 第一行的地址码:0x80 WriteCommandLCM(X, 0); // 这里不检测忙信号,发送地址码 WriteDataLCM(DData); } /*在LCD1602中使用此函数,在DIPS082中使用下面的函数 /***************************************************** 函 数 名:void DisplayListChar(uchar x,uchar y,uchar *DData) 功 能:向指定坐标中写入字符串(在LCD1602中使用此函数) 说 明:X-横坐标,Y-纵坐标 入口参数:X,Y,*DData 返 回 值:无 ***************************************************** //按指定位置显示字符串 void DisplayListChar(uchar x,uchar y,uchar *DData) { if (y == LINE1) // 判断是否写入第1行 { if (x < LINE_LENGTH) // 写入位数 { WriteCommandLCM(LINE1_HEAD+x,0); // 写入第1行地址 for (; x