自制51單片機常用頭文件(LCD1602)
LCD1602.H
本文引用地址:http://m.butianyuan.cn/article/201611/317353.htmThe 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指令 ***********************************/
//輸入方式設(shè)置
#define LCD_AC_AUTO_INCREMENT 0x06 // 數(shù)據(jù)讀、寫操作后,AC自動增一
#define LCD_AC_AUTO_DECREASE 0x04 // 數(shù)據(jù)讀、寫操作后,AC自動減一
#define LCD_MOVE_ENABLE 0x05 // 數(shù)據(jù)讀、寫操作,畫面平移
#define LCD_MOVE_DISENABLE 0x04 // 數(shù)據(jù)讀、寫操作,畫面不動
#define LCD_GO_HOME 0x02 // AC=0,光標、畫面回HOME位
//設(shè)置顯示、光標及閃爍開、關(guān)
#define LCD_DISPLAY_ON 0x0C // 顯示開
#define LCD_DISPLAY_OFF 0x08 // 顯示關(guān)
#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 // 光標右移一位
//工作方式設(shè)置
#define LCD_DISPLAY_DOUBLE_LINE 0x38 // 兩行顯示
#define LCD_DISPLAY_SINGLE_LINE 0x30 // 單行顯示
#define LCD_CLEAR_SCREEN 0x01 // 清屏
/***********************LCD1602地址相關(guān)******************************/
#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 // 數(shù)據(jù)/命令選擇信號
#define LCM_RW P2_1 // 讀/寫選擇信號
#define LCM_E P2_2 // 使能信號
#define LCM_Data P0 // 顯示數(shù)據(jù)端口
#define Busy 0x80 // 用于檢測LCM狀態(tài)字中的Busy標識
#define uchar unsigned char
#define uint unsigned int
//================================ LCM1602控制部分 =========================================================
/*****************************************************
函 數(shù) 名:void Delay_LCD(void)
功 能:5ms延時
說 明:LCD顯示延時
入口參數(shù):無
返 回 值:無
*****************************************************/
void Delay_LCD(void)
{
uint TempCyc = 5552; // 放入延時數(shù)據(jù)
while(TempCyc--)
{
;
}
}
/*****************************************************
函 數(shù) 名:uchar ReadStatusLCM()
功 能:讀忙狀態(tài)
說 明:判斷LCM的工作狀態(tài);也可以不用此函數(shù),用一段延時程序代替
入口參數(shù):無
返 回 值:LCM_Data
*****************************************************/
//讀狀態(tài)
uchar ReadStatusLCM(void)
{
LCM_Data = 0xFF; // LCM數(shù)據(jù)口先置1
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
while (LCM_Data & Busy) // 檢測忙信號.如果忙,則不執(zhí)行
{
;
}
return (LCM_Data); // 不忙返回讀取數(shù)據(jù)
}
/*****************************************************
函 數(shù) 名:void WriteDataLCM()
功 能:向LCM1602中寫入數(shù)據(jù)
說 明:將形參WDLCM中的數(shù)據(jù)寫入LCM中
入口參數(shù):WDLCM
返 回 值:無
*****************************************************/
//寫數(shù)據(jù)
void WriteDataLCM(uchar WDLCM)
{
ReadStatusLCM(); // 檢測忙
LCM_Data = WDLCM; // 寫入數(shù)據(jù)到LCM
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0; // 若晶振速度太高可以在這后加小的延時
LCM_E = 0; // 延時
LCM_E = 1;
}
/*****************************************************
函 數(shù) 名:void WriteCommandLCM()
功 能:向LCM1602中寫入指令
說 明:向LCM中寫入指令;如果BuysC=0時,忽略忙檢測,如果BuysC=1時,不忽略忙檢測
入口參數(shù):WCLCM,BuysC
返 回 值:無
*****************************************************/
//寫指令
void WriteCommandLCM(uchar WCLCM,BuysC) // BuysC為0時忽略忙檢測
{
if (BuysC)
{
ReadStatusLCM(); // 根據(jù)需要檢測忙
}
LCM_Data = WCLCM; // 寫入指令
LCM_RS = 0;
LCM_RW = 0;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
}
/*****************************************************
函 數(shù) 名:void LCMInit()
功 能:初始化LCM1602
說 明:LCM在工作前先要對顯示屏初始化,否則模塊無法正常工作
入口參數(shù):無
返 回 值:無
*****************************************************/
//LCM初始化
void LCMInit(void)
{
LCM_Data = 0;
WriteCommandLCM(LCD_DISPLAY_DOUBLE_LINE,0); // 三次顯示模式設(shè)置,不檢測忙信號
Delay_LCD();
WriteCommandLCM(LCD_DISPLAY_DOUBLE_LINE,0); // 0x38指令表示:8位數(shù)據(jù)顯示模式,倆行多顯示
Delay_LCD();
WriteCommandLCM(LCD_DISPLAY_DOUBLE_LINE,0);
Delay_LCD();
WriteCommandLCM(LCD_DISPLAY_DOUBLE_LINE,1); // 顯示模式設(shè)置,開始要求每次檢測忙信號
WriteCommandLCM(LCD_DISPLAY_OFF,1); // 關(guān)閉顯示
WriteCommandLCM(LCD_CLEAR_SCREEN,1); // 顯示清屏
WriteCommandLCM(LCD_AC_AUTO_INCREMENT,1); // 顯示光標移動設(shè)置
WriteCommandLCM(LCD_DISPLAY_ON,1); // 顯示開及光標設(shè)置
}
/*****************************************************
函 數(shù) 名:void DisplayOneChar()
功 能:按指定坐標中寫入數(shù)據(jù)
說 明:X-橫坐標,Y-縱坐標,DData為ASCII值
入口參數(shù):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); // 這里不檢測忙信號,發(fā)送地址碼
WriteDataLCM(DData);
}
/*在LCD1602中使用此函數(shù),在DIPS082中使用下面的函數(shù)
/*****************************************************
函 數(shù) 名:void DisplayListChar(uchar x,uchar y,uchar *DData)
功 能:向指定坐標中寫入字符串(在LCD1602中使用此函數(shù))
說 明:X-橫坐標,Y-縱坐標
入口參數(shù):X,Y,*DData
返 回 值:無
*****************************************************
//按指定位置顯示字符串
void DisplayListChar(uchar x,uchar y,uchar *DData)
{
if (y == LINE1) // 判斷是否寫入第1行
{
if (x < LINE_LENGTH) // 寫入位數(shù)
{
WriteCommandLCM(LINE1_HEAD+x,0); // 寫入第1行地址
for (;x