lcd1602与单片机是怎么通信的(汇编程序设计LCD1602静态显示)
lcd1602与单片机是怎么通信的(汇编程序设计LCD1602静态显示)功能:主函数主程序:MAIN伪指令定义,可以写在ORG 0000H的前面。LCD_RS BIT P1.3 ; 伪指令,定义LCD的RS引脚 LCD_RW BIT P1.5 ;伪指令,定义LCD的RW引脚 LCD_E BIT P1.4 ;伪指令,定义LCD的E引脚 LCD_Status EQU 20H ;定义LCD的忙状态以下为程序中用到的量含义说明:在Keil中应该写成注释LCD_Status:存放LCD忙状态信息,=0,为不忙 R6 存放LCD的命令字,LCD_Write_Command的入口参数 R5 存放要显示的数据,LCD_Write_Dat的入口参数 R4 存放显示位置,LCD_Position的入口参数 R3 存放要显示的数组长度 30H 延时函数的入口参数,通过给30H单元赋值,可以实现不同的延时时间。 ORG 0000H LJMP MAIN;/****
嗨,大家好,昨天刚写好一个汇编程序,之前有bug,不能正确显示,经过一天的调试修改终于改好了,和大家分享一下。
我今天给大家介绍的是LCD1602的显示,该程序是用汇编语言来写的。我们先来看一下实物效果:
LCD1602实物效果图
背面接线
伪指令定义,可以写在ORG 0000H的前面。
LCD_RS BIT P1.3 ; 伪指令,定义LCD的RS引脚
LCD_RW BIT P1.5 ;伪指令,定义LCD的RW引脚
LCD_E BIT P1.4 ;伪指令,定义LCD的E引脚
LCD_Status EQU 20H ;定义LCD的忙状态
以下为程序中用到的量含义说明:在Keil中应该写成注释
LCD_Status:存放LCD忙状态信息,=0,为不忙
R6 存放LCD的命令字,LCD_Write_Command的入口参数
R5 存放要显示的数据,LCD_Write_Dat的入口参数
R4 存放显示位置,LCD_Position的入口参数
R3 存放要显示的数组长度
30H 延时函数的入口参数,通过给30H单元赋值,可以实现不同的延时时间。
ORG 0000H
LJMP MAIN;
/**************************
主程序:MAIN
功能:主函数
************************/
ORG 0030H
MAIN: MOV SP #40H
LCALL LCD_Init;
MOV 30H #5;
LCALL Delay;
LCALL LCD_Display;
MOV 30H #5;
LCALL Delay;
LJMP MAIN;
/*********************************
子程序:Nop4
功 能:6个机器周期延时
*********************************/
Nop6: NOP
NOP
NOP
NOP
NOP
NOP
RET // 6个空操作
/******************************************
子 程 序:LCD_Busy_Check
功 能:LCD忙检测
出口参数:LCD_Status,LCD_Status=0,说明LCD不忙;
*****************************************/
LCD_Busy_Check:
CLR LCD_RS ;LCD_RS=0
SETB LCD_RW ;LCD_RW=1
SETB LCD_E ;LCD_E=1
LCALL Nop6 ;延时4个机器周期
ANL P2 #80H ;LCD_Status=P0&0x80
MOV LCD_Status P2 ;LCD_Status=P0&0x80
CLR LCD_E
RET
/***************************
子 程 序:LCD_Write_Command
功 能:向LCD发布命令
入口参数:R6,在调用该程序前应该对R6进行赋值,即LCD的命令字。
出口参数:无
*******************************/
LCD_Write_Command:
NOP
NEXT1: LCALL LCD_Busy_Check ;
MOV A LCD_Status ;
JNZ NEXT1 ; A不等于0,说明LCD为忙状态,继续检测
CLR LCD_RS ;LCD_RS=0
CLR LCD_RW ;LCD_RW=0
CLR LCD_E ;LCD_E=0
MOV P2 R6 ;将LCD命令字送入P2口
LCALL Nop6
SETB LCD_E;
LCALL Nop6
CLR LCD_E ;
RET
/*********************
子 程 序:LCD_Write_Dat
功 能:向LCD发送数据
入口参数:R5,在调用该程序前应该对R5进行赋值,即向LCD写入的数据。
出口参数:无
*******************/
LCD_Write_Dat:
NOP
NEXT2: LCALL LCD_Busy_Check;
MOV A LCD_Status ;LCD_Status
JNZ NEXT2 ; A不等于0,说明LCD为忙状态,继续检测; A=0 说明LCD不忙了。
SETB LCD_RS ;
CLR LCD_RW ;
CLR LCD_E ;
MOV P2 R5 ;将LCD数据送入P2口
LCALL Nop6
SETB LCD_E ;
LCALL Nop6
CLR LCD_E
RET
/***************************
子 程 序:LCD_Position
功 能:向LCD发布命令
入口参数:R4,在调用该程序前应该对R4进行赋值。
出口参数:R6,将或运算后的数据送入R6,作为LCD_Write_Command的入口参数
**************************/
LCD_Position:
MOV A R4 ;将位置数据送入A
ORL A #80H ;设置LCD的当前显示位置
MOV R6 A ;将位置存入R6;
ACALL LCD_Write_Command;
RET ;
/****************************
子 程 序:LCD_Display
功 能:显示
入口参数:R4,在调用该程序前应该对R4进行赋值。
出口参数:R6,将或运算后的数据送入R6,作为LCD_Write_Command的入口参数
***************************/
LCD_Display:
MOV R4 #00;
LCALL LCD_Position ; 设置第一行的显示位置:00H开始
MOV DPTR #TAB1;
MOV R3 #16
LOOP1: CLR A
MOVC A @A DPTR
MOV R5 A;
LCALL LCD_Write_Dat;
INC DPTR;
DJNZ R3 LOOP1
MOV R4 #41H ; 设置第二行的显示位置:41H开始
LCALL LCD_Position
MOV DPTR #TAB2;
MOV R3 #16
LOOP2:CLR A
MOVC A @A DPTR
MOV R5 A;
LCALL LCD_Write_Dat;
INC DPTR;
DJNZ R3 LOOP2
RET;
/****************************
子 程 序:LCD_Init
功 能:LCD初始化,
入口参数:无
出口参数:无
***************************/
LCD_Init:
MOV R6 #38H;
LCALL LCD_Write_Command;
MOV 30H #10
LCALL DELAY
MOV R6 #0FH;
LCALL LCD_Write_Command;
MOV 30H #10
LCALL DELAY
MOV R6 #06H;
LCALL LCD_Write_Command;
MOV 30H #10
LCALL DELAY
MOV R6 #01H;
LCALL LCD_Write_Command;
MOV 30H #10
LCALL DELAY
RET
/************************
子 程 序:Delay
功 能:延时函数
入口参数:30H
出口参数:无
***************************/
DELAY: ;误差 0us
MOV R2 30H;
DL0: MOV R1 #5FH
DJNZ R1 $
DJNZ R2 DL0
RET
要显示的字符串,用DB进行定义
TAB1: DB "I Love MCU BY"
TAB2: DB "2020.5.27 LY"
END