汇编程序设计是什么 (汇编程序设计需要截图吗)

嗨,大家好,昨天刚写好一个汇编程序,之前有bug,不能正确显示,经过一天的调试修改终于改好了,和大家分享一下。

我今天给大家介绍的是LCD1602的显示,该程序是用汇编语言来写的。我们先来看一下实物效果:

lcd1602预编译指令,汇编程序设计

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