快捷搜索:  汽车  科技

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与单片机是怎么通信的(汇编程序设计LCD1602静态显示)(1)

LCD1602实物效果图

lcd1602与单片机是怎么通信的(汇编程序设计LCD1602静态显示)(2)

背面接线

伪指令定义,可以写在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

猜您喜欢: