標(biāo)題:
單片機(jī)控制LCD1602液晶屏之模塊化編程
[打印本頁(yè)]
作者:
engineerarui
時(shí)間:
2021-4-20 09:39
標(biāo)題:
單片機(jī)控制LCD1602液晶屏之模塊化編程
這里將我寫的STC12C5A60S2控制LCD1602的程序共享一下,如有不足,敬請(qǐng)指出!
1.jpg
(63.41 KB, 下載次數(shù): 54)
下載附件
2021-4-20 16:26 上傳
代碼結(jié)構(gòu)圖:
2.png
(8.47 KB, 下載次數(shù): 63)
下載附件
2021-4-20 16:26 上傳
程序下載鏈接:
https://download.csdn.net/download/yagnruinihao/16676666
Proteus仿真圖下載鏈接:
https://download.csdn.net/download/yagnruinihao/16676677
————————————————
單片機(jī)測(cè)試程序:LCD1602測(cè)試.c
#include <string.h>
#include "common.h"
#include "LCD1602.h"
void main(void)
{
unsigned char i ;
unsigned char author[] = "Author:YangRui" ;
LCD1602_Init();
for(i=0 ; i<strlen(author) ; i++)
{
LCD1602_AddressWriteByte(LCD1602_ROW0,i,author[i]);
}
LCD1602_AddressWriteString(LCD1602_ROW1,0,"QQ:279729201") ;
while(1);
}
復(fù)制代碼
/*################LCD1602.h ################*/
#ifndef __LCD1602_H__
#define __LCD1602_H__
#include "common.h"
//硬件接口定義,與硬件電路相對(duì)應(yīng)
sbit LCD1602_RS_Bit = P2^6;//LCD1602的RS端口,高電平表示數(shù)據(jù)、低電平表示命令
sbit LCD1602_RW_Bit = P2^5;//LCD1602的RW端口,高電平表示讀操作、低電平表示寫操作
sbit LCD1602_EN_Bit = P2^7;//LCD1602的EN端口,高電平表示讀狀態(tài)或讀數(shù)據(jù)、高脈沖表示寫指令或?qū)憯?shù)據(jù)
#define LCD1602_DATA_PORT P0//LCD1602的數(shù)據(jù)口D0~D7,其中Px^0端口接DB0,Px^7端口接DB7,其他接口以此類推
/* RS與RW的設(shè)置:
RS Rw
0 0 ---->寫命令
0 1 ---->讀狀態(tài)
1 0 ---->寫數(shù)據(jù)
1 1 ---->讀數(shù)據(jù)
*/
//LCD1602的RS端口選擇
#define LCD1602_DATA_OPERATION 1//數(shù)據(jù)模式
#define LCD1602_COMMAND_OPERATION 0//命令模式
//LCD1602的RW端口選擇
#define LCD1602_READ_OPERATION 1//讀操作
#define LCD1602_WRITE_OPERATION 0//寫操作
//LCD1602的EN端口選擇
#define LCD1602_ENABLE 1//允許操作LCD1602
#define LCD1602_DISABLE 0//禁止操作LCD1602
//顯示模式:16X2個(gè)字符, 5X7點(diǎn)陣,8位數(shù)據(jù)口
#define LCD1602_DEFAULT_DISPALY_MODE 0x38
/*
====================================================
LCD1602設(shè)置:顯示允許或禁止、光標(biāo)顯示或禁止、光標(biāo)閃爍或禁止
====================================================
/*
0 0 0 0 1 D C B
| | |------光標(biāo)閃爍 : 1-->允許 ; 0-->禁止
| |----------光標(biāo)顯示 : 1-->允許 ; 0-->禁止
|-------------液晶屏顯示 : 1-->允許 ; 0-->禁止
*/
#define LCD1602_DISPLAY_ENABLE 0X04 //允許液晶顯示
#define LCD1602_DISPLAY_DISABLE (0X04 & (~(0x01<<2)))//禁止液晶顯示
#define LCD1602_CURSOR_DISPLAY_ENABLE 0X02 //允許光標(biāo)顯示
#define LCD1602_CURSOR_DISPLAY_DISABLE (0X02 & (~(0x01<<1)))//禁止光標(biāo)顯示
#define LCD1602_CURSOR_BLINK_ENABLE 0X01 //允許光標(biāo)閃爍
#define LCD1602_CURSOR_BLINK_DISABLE (0X01 & (~(0x01<<0)))//禁止光標(biāo)閃爍
//默認(rèn)設(shè)置:lcd顯示,光標(biāo)不顯示,光標(biāo)不閃爍
#define LCD1602_DEFAULT_DISPLAY_AND_CURSOR_MODE 0x08 | \
LCD1602_DISPLAY_ENABLE | \
LCD1602_CURSOR_DISPLAY_DISABLE | \
LCD1602_CURSOR_BLINK_DISABLE
/*
====================================================
LCD1602設(shè)置:指針加一或減一、光標(biāo)位置加一或減一
====================================================
0 0 0 0 0 1 N S
| |----- 屏幕移動(dòng):1-->允許 ; 0-->禁止
|--------- N=1:讀或者寫一個(gè)字符后地址指針加1,且光標(biāo)加1
N=0:讀或者寫一個(gè)字符后地址指針減1,且光標(biāo)減1
當(dāng)S=1時(shí) :
若N=1,整屏幕左移
N=0,整屏幕右移
以達(dá)到光標(biāo)不移動(dòng),而整個(gè)屏幕移動(dòng)的效果
*/
#define LCD1602_POINT_AND_CURSOR_PLUS 0X02 //指針加一、光標(biāo)加一
#define LCD1602_POINT_AND_CURSOR_MINUS (0X02 & (~(0X01<<1)))//指針減一、光標(biāo)減一
#define LCD1602_SCREEN_MOVE_ENABLE 0x01 //允許屏幕移動(dòng)
#define LCD1602_SCREEN_MOVE_DISABLE (0x01 & (~(0X01<<0)))//禁止屏幕移動(dòng)
//默認(rèn)設(shè)置:光標(biāo)和指針加一,屏幕不移動(dòng)
#define LCD1602_DEFAULT_POINT_AND_POINT_ADDRESS_MODE 0X04 | \
LCD1602_POINT_AND_CURSOR_PLUS| \
LCD1602_SCREEN_MOVE_DISABLE
//行位置參數(shù),注意行地址從0開始
#define LCD1602_ROW0 0 //第0行
#define LCD1602_ROW1 1 //第1行
#define LCD1602_MIN_ROW LCD1602_ROW0//行數(shù)的最小值,為L(zhǎng)CD1602_ROW0,即0*/
#define LCD1602_MAX_ROW LCD1602_ROW1//行數(shù)的最大值,為L(zhǎng)CD1602_ROW1,即1*/
//列位置參數(shù),注意列地址從0開始
#define LCD1602_ROW_LENGHT 0x28 //每一行的長(zhǎng)度為0x28,即40
#define LCD1602_MIN_COLUMN 0 //列數(shù)的最小值,為0
#define LCD1602_MAX_COLUMN (LCD1602_ROW_LENGHT-1)//列數(shù)的最大值,為39
//每一行的起始地址*/
#define LCD1602_ROW0_ADDRESS_START 0x80 //第0行起始地址
#define LCD1602_ROW1_ADDRESS_START (0x80+0x40) //第1行起始地址
/*每一行的結(jié)束地址*/
#define LCD1602_ROW0_ADDRESS_END (LCD1602_ROW0_ADDRESS_START+LCD1602_ROW_LENGHT)//第0行結(jié)束地址
#define LCD1602_ROW1_ADDRESS_END (LCD1602_ROW1_ADDRESS_START+LCD1602_ROW_LENGHT)//第1行結(jié)束地址
//命令集指令
#define LCD1602_CLEAN_ALL_DISPALY 0x01//清屏指令
#define LCD1602_CURSOR_RETURN_TO_ORIGIN 0x02//光標(biāo)歸位指令
/*****************外部接口函數(shù)******************/
//LCD1602初始化函數(shù)
extern void LCD1602_Init(void) ;
//清屏操作
extern void LCD1602_CleanAll(void) ;
//光標(biāo)歸位操作
extern void LCD1602_CursorHoming(void);
//LCD1602地址寫字節(jié)操作
extern char LCD1602_AddressWriteByte(unsigned char Row,unsigned char Column,unsigned char DataValue);
//LCD1602地址寫字符串操作
extern char LCD1602_AddressWriteString(unsigned char Row,unsigned char Column,unsigned char *String);
//寫命令操作
extern void LCD1602_WriteCommand(unsigned char CommandValue);
//寫數(shù)據(jù)操作
extern void LCD1602_WriteData(unsigned char DataValue);
/**********************************************/
#endif /*__LCD1602_H__*/
復(fù)制代碼
/*################ LCD1602.c################*/
/***************************************************************************
模 塊:LCD1602.c
說 明:LCD1602驅(qū)動(dòng)程序
版 本:Version3.0 2021/01/01 06:00
編譯環(huán)境:Keil_C51 V9.55
主控芯片:STC12C5A60S2 @11.0592MHZ
STC89C52RC @11.0592MHZ
AT89C51 @11.0592MHZ @Proteus8.9仿真
作 者:楊瑞
聯(lián)系方式:【 QQ 】279729201
【郵箱】279729201@qq.com
yangrui90s@163.com
【電話】13630279531
修改記錄:
=================
2021/01/01 06:06
記錄:
1.規(guī)范部分函數(shù)。
2.取消Delay80usForLcd1602(),調(diào)用函數(shù)Delay_SomeNop(10)代替消Delay80usForLcd1602()函數(shù)。
3.增加ST89C52RC @11.0592MHZ 和AT89C51 @11.0592MHZ @Proteus8.9仿真測(cè)試,經(jīng)測(cè)試此代碼
均可適用。
=================
=================
2017/01/6 12:08
記錄:
1.增加中文注釋。
2.修改函數(shù)名稱模式,由"模塊名稱"(大寫)+"_"+功能函數(shù)名稱構(gòu)成,例如lcd1602ReadStatus修改為L(zhǎng)CD1602_ReadStatus.
3.修改延時(shí)函數(shù),將Delay1msForLcd1602函數(shù)修改為Delay80usForLcd1602函數(shù)。注意,這兩個(gè)函數(shù)都是
由STC-ISP生成,Delay80usForLcd1602函數(shù)由STC-ISP V6.85Q的“軟件延時(shí)計(jì)算器”針對(duì)STC-Y3指令集
@11.0592MHZ自動(dòng)生成。經(jīng)過測(cè)試,延時(shí)59us可能會(huì)出現(xiàn)只書寫部分內(nèi)容的情況,延時(shí)60us正好可以。
為了安全,也可以將此延時(shí)修改的更長(zhǎng)。
=================
=================
2014/04/31 20:09
記錄:
1.解決大工程中,因未安裝LCD1602而導(dǎo)致的工程卡死在函數(shù)
lcd1602CheckBusy()的問題,將
do{
;
}while( (lcd1602ReadStatus()) & 0x80));
修改為
do{
i++;
}while( ((lcd1602ReadStatus()) & 0x80) && (i<10));
因?yàn)樵谖窗惭bLCD1602時(shí),通過"讀狀態(tài)"函數(shù)lcd1602ReadStatus()讀回來的永遠(yuǎn)是0xff,
如果采用第一種算法,會(huì)導(dǎo)致程序"卡死",不夠“安全”。
=================
=================
2014/02/24 23:44
記錄:
1.增加函數(shù)lcd1602AddressWriteString(...)
=================
=================
2014/02/24 15:00
記錄:
1.增加函數(shù)delay1msForLcd1602()
STC12C5A60S2單片機(jī)操作速度快比傳統(tǒng)8051快,某些操作延時(shí)必須足夠。
=================
***************************************************************************/
#include <string.h>
#include "lcd1602.h"
/*外部接口函數(shù)在lcd1602.h中聲明*/
/*****************內(nèi)部函數(shù)******************/
unsigned char LCD1602_ReadStatus(void) ;
void LCD1602_CheckBusy(void) ;
/**********************************************/
/******************************************************************
- 函數(shù)名稱:LCD1602_ReadStatus
- 功能描述:讀取LCD1602狀態(tài)值
- 函數(shù)屬性:內(nèi)部函數(shù)
- 參數(shù)說明:無
- 返回說明:LCD1602的狀態(tài)值
******************************************************************/
unsigned char LCD1602_ReadStatus(void)
{
unsigned char StatusCode ;
LCD1602_EN_Bit = LCD1602_DISABLE ; //禁止操作LCD1602
LCD1602_RS_Bit = LCD1602_COMMAND_OPERATION ;//命令模式
LCD1602_RW_Bit = LCD1602_READ_OPERATION ; //讀操作
LCD1602_DATA_PORT = 0xff ;
Delay_SomeNop(10); //注意:這里延時(shí)不能少,否則不會(huì)有效果
LCD1602_EN_Bit = LCD1602_ENABLE ; //允許操作LCD1602
Delay_SomeNop(10); //注意:這里延時(shí)不能少,否則不會(huì)有效果
StatusCode = LCD1602_DATA_PORT ; //讀取狀態(tài)值*/
LCD1602_EN_Bit = LCD1602_DISABLE ; //禁止操作LCD1602
return StatusCode ;
}
/******************************************************************
- 函數(shù)名稱:LCD1602_CheckBusy
- 功能描述:判斷LCD1602是否忙碌:若忙碌則等待;若空閑則執(zhí)行任務(wù)
- 函數(shù)屬性:內(nèi)部函數(shù)
- 參數(shù)說明:無
- 返回說明:無
- 注 :當(dāng)LCD1602_DATA_PORT[7]等于1,表示LCD1602忙碌,則需要等待一會(huì)兒
當(dāng)LCD1602_DATA_PORT[7]等于0,表示LCD1602空閑,則可以繼續(xù)執(zhí)行后面的任務(wù)
- 補(bǔ) 充:這里的“10”是經(jīng)過測(cè)試的,測(cè)試中,利用串口打印i的值為1,這里寫10已經(jīng)足夠大了。
******************************************************************/
void LCD1602_CheckBusy(void)
{
unsigned char i=0;
do{
i++;
}while( ((LCD1602_ReadStatus()) & 0x80) && (i<10));
}
/******************************************************************
- 函數(shù)名稱:LCD1602_WriteCommand
- 功能描述:LCD1602寫命令
- 函數(shù)屬性:外部函數(shù),供用戶調(diào)用
- 參數(shù)說明:CommandValue,需要發(fā)送給LCD1602的指令值
- 返回說明:無
******************************************************************/
void LCD1602_WriteCommand(unsigned char CommandValue)
{
LCD1602_CheckBusy();
LCD1602_EN_Bit = LCD1602_DISABLE ; /*禁止操作LCD1602*/
LCD1602_RS_Bit = LCD1602_COMMAND_OPERATION ;/*命令模式*/
LCD1602_RW_Bit = LCD1602_WRITE_OPERATION ; /*寫操作*/
LCD1602_DATA_PORT = CommandValue ; /*發(fā)送指令值*/
//Delay_SomeNop(10);
LCD1602_EN_Bit = LCD1602_ENABLE ; /*允許操作LCD1602*/
//Delay_SomeNop(10);
LCD1602_EN_Bit = LCD1602_DISABLE ; /*禁止操作LCD1602*/
}
/******************************************************************
- 函數(shù)名稱:LCD1602_WriteData
- 功能描述:LCD1602寫數(shù)據(jù)
- 函數(shù)屬性:外部函數(shù),供用戶調(diào)用
- 參數(shù)說明:DataValue,需要發(fā)送給LCD1602的數(shù)據(jù)
- 返回說明:無
******************************************************************/
void LCD1602_WriteData(unsigned char DataValue)
{
LCD1602_CheckBusy() ;
LCD1602_EN_Bit = LCD1602_DISABLE ; /*禁止操作LCD1602*/
LCD1602_RS_Bit = LCD1602_DATA_OPERATION ; /*數(shù)據(jù)模式*/
LCD1602_RW_Bit = LCD1602_WRITE_OPERATION ; /*寫操作*/
LCD1602_DATA_PORT = DataValue; /*發(fā)送數(shù)據(jù)*/
//Delay_SomeNop(10);
LCD1602_EN_Bit = LCD1602_ENABLE ; /*允許操作LCD1602*/
//Delay_SomeNop(10);
LCD1602_EN_Bit = LCD1602_DISABLE ; /*禁止操作LCD1602*/
}
/******************************************************************
- 函數(shù)名稱:LCD1602_CleanAll
- 功能描述:清除屏幕顯示
- 函數(shù)屬性:外部函數(shù),供用戶調(diào)用
- 參數(shù)說明:無
- 返回說明:無
- 注 :清除屏幕顯示,光標(biāo)歸位(左上角),地址計(jì)數(shù)器AC設(shè)為0
******************************************************************/
void LCD1602_CleanAll(void)
{
LCD1602_WriteCommand(LCD1602_CLEAN_ALL_DISPALY);
}
/******************************************************************
- 函數(shù)名稱:LCD1602_CursorHoming
- 功能描述:光標(biāo)歸位
- 函數(shù)屬性:外部函數(shù),供用戶調(diào)用
- 參數(shù)說明:無
- 返回說明:無
- 注 :光標(biāo)歸為,當(dāng)屏幕移動(dòng)顯示時(shí),lcd1602顯示所有數(shù)據(jù)后,
調(diào)用此函數(shù),屏幕顯示的所有東西都會(huì)歸位。光標(biāo)在第一
個(gè)位置(0x80)。
******************************************************************/
void LCD1602_CursorHoming(void)
{
LCD1602_WriteCommand(LCD1602_CURSOR_RETURN_TO_ORIGIN);
}
/******************************************************************
- 函數(shù)名稱:LCD1602_Init
- 功能描述:LCD1602初始化
- 函數(shù)屬性:外部函數(shù),供用戶調(diào)用
- 參數(shù)說明:無
- 返回說明:無
- 注 :設(shè)置(1)顯示模式
(2)液晶顯示允許或禁止、光標(biāo)顯示允許或禁止、光標(biāo)閃爍允許或禁止
(3)地址指針加一或減一、光標(biāo)指針加一或減一、屏幕左移或右移
可通過修改LCD1602.H中的LCD1602_DEFAULT_DISPALY_MODE、LCD1602_DEFAULT_DISPLAY_AND_CURSOR_MODE、
LCD1602_DEFAULT_POINT_AND_POINT_ADDRESS_MODE達(dá)到不同的顯示效果。
******************************************************************/
void LCD1602_Init(void)
{
LCD1602_CleanAll();
LCD1602_WriteCommand(LCD1602_DEFAULT_DISPALY_MODE);
LCD1602_WriteCommand(LCD1602_DEFAULT_DISPLAY_AND_CURSOR_MODE);
LCD1602_WriteCommand(LCD1602_DEFAULT_POINT_AND_POINT_ADDRESS_MODE);
/*可忽略,在LCD1602_CleanAll()中隱含了該功能*/
LCD1602_CursorHoming();
}
/******************************************************************
- 函數(shù)名稱:LCD1602_AddressWriteByte
- 功能描述:在LCD1602的Row行Column列寫入數(shù)DataValue
- 函數(shù)屬性:外部函數(shù),供用戶調(diào)用
- 參數(shù)說明:Row-->行地址,有效值為L(zhǎng)CD1602_ROW0或LCD1602_ROW1
Column-->列地址,有效值為0~39之間的整數(shù)
DataValue-->需要寫入的數(shù)據(jù)。
- 返回說明:0(成功)或者-1(失。
- 注 :1.行地址和列地址都是從0開始的。
需要在LCD1602的第0行第2列顯示阿里伯?dāng)?shù)字5,調(diào)用方式為
LCD1602_AddressWriteByte(LCD1602_ROW0,2,‘5’);
2.在DEBUG模式下,會(huì)對(duì)入?yún)⑦M(jìn)行有效性判斷,協(xié)助分析。調(diào)試后期可通過
屏蔽common.h中的"#define DEBUG 1"減小目標(biāo)文件的大小。
******************************************************************/
char LCD1602_AddressWriteByte(unsigned char Row,unsigned char Column,unsigned char DataValue)
{
#ifdef DEBUG
if((Column< LCD1602_MIN_COLUMN)|| (Column > LCD1602_MAX_COLUMN)|| \
( (Row != LCD1602_ROW0) &&(Row != LCD1602_ROW1)))
return -1 ;
#endif
if(LCD1602_ROW0 == Row) //注意這里==的兩邊順序,技巧!
LCD1602_WriteCommand(LCD1602_ROW0_ADDRESS_START+Column) ;
else if(LCD1602_ROW1 == Row)//注意這里==的兩邊順序,技巧!
LCD1602_WriteCommand(LCD1602_ROW1_ADDRESS_START+Column) ;
LCD1602_WriteData(DataValue);
return 0;
}
/******************************************************************
- 函數(shù)名稱:LCD1602_AddressWriteString
- 功能描述:從LCD1602的Row行Column列開始寫入字符串String
- 函數(shù)屬性:外部函數(shù),供用戶調(diào)用
- 參數(shù)說明:Row-->行地址,有效值為L(zhǎng)CD1602_ROW0或LCD1602_ROW1
Column-->列地址,有效值為0~39之間的整數(shù)
String-->需要寫入的字符串。
- 返回說明:0(成功)或者-1(失敗)
- 注 :行地址和列地址都是從0開始的。
想在LCD1602的第0行第2列顯示"test",調(diào)用方式為
LCD1602_AddressWriteString(LCD1602_ROW0,2,"test");
這里使用的是strlen,而不是sizeof。
在DEBUG模式下,會(huì)對(duì)入?yún)⑦M(jìn)行有效性判斷,協(xié)助分析。調(diào)試后期可通過
屏蔽common.h中的"#define DEBUG 1"減小目標(biāo)文件的大小。
******************************************************************/
char LCD1602_AddressWriteString(unsigned char Row,unsigned char Column,unsigned char *String)
{
unsigned char length = strlen(String) ;
#ifdef DEBUG
if(Column< LCD1602_MIN_COLUMN|| (Column+strlen(String)-1) > LCD1602_MAX_COLUMN|| \
( (Row != LCD1602_ROW0) &&(Row != LCD1602_ROW1)))
return -1 ;
#endif
if(LCD1602_ROW0 == Row) //注意這里==的兩邊順序,技巧!
LCD1602_WriteCommand(LCD1602_ROW0_ADDRESS_START+Column) ;
else if(LCD1602_ROW1 == Row)//注意這里==的兩邊順序,技巧!
LCD1602_WriteCommand(LCD1602_ROW1_ADDRESS_START+Column) ;
while(length--)
LCD1602_WriteData(*String++);
return 0;
}
復(fù)制代碼
/*################common.h################*/
#ifndef __COMMON_H__
#define __COMMON_H__
#include <reg51.h>
#define DEBUG 1 //用于前期調(diào)試,后期可以屏蔽本行代碼,達(dá)到減少目標(biāo)文件大小的目標(biāo)
/*****************外部接口函數(shù)******************/
//延時(shí)(不精準(zhǔn)延時(shí))函數(shù)
void Delay_SomeNop(long time);
#endif /*__COMMON_H__*/
復(fù)制代碼
/*################common.c################*/
#include <intrins.h>
#include "common.h"
/******************************************************************
- 函數(shù)名稱:Delay_SomeNop
- 功能描述:延時(shí)函數(shù)(不精準(zhǔn)延時(shí))
- 函數(shù)屬性:外部函數(shù),供用戶調(diào)用
- 參數(shù)說明:time需要延時(shí)時(shí)間
- 返回說明:無
- 注 :無
******************************************************************/
void Delay_SomeNop(long time)
{
while(time--)
{
_nop_();
}
}
復(fù)制代碼
版權(quán)聲明:本文為CSDN博主「刺客阿瑞」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:
https://blog.csdn.net/yagnruinihao/article/details/18559309
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1