这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【换取手持数字示波器】+AT89C2051串口接收数据显示到LCD1602上

共2条 1/1 1 跳转至

【换取手持数字示波器】+AT89C2051串口接收数据显示到LCD1602上

专家
2024-05-11 00:03:50   被打赏 50 分(兑奖)     打赏

本帖依旧是使用AT89C2051、汇编语言实现的一个小程序。应用时,与计算机相连,从串口收到可显示的字符时,显示到LCD1602上。LCD1602基本上也算是被淘汰的LCD了,但作为初学者,学习相关的通讯处理,个人觉得依旧有存在的意义。这个汇编程序,对于学习、理解51单片机在中断上的处理方式上,希望能对51单片机初学者有所帮助。

电路图:

图片1.pngP1.0和 P1.1作为IO使用的时候,必须要加上拉电阻。串口没有做特殊处理,连接计算机的串口时,需要使用TTL转换电路,这一点要特别注意。串口的通讯波特率为2400,n,8,1模式。

程序如下:


;显示缓冲区1---第一行数据,总共16字节 08H-17H
LineBuf1          equ 08H
;显示缓冲区1---第二行数据,总共16字节 18H-27H
LineBuf2          equ 18H
;寄存器选择
RS                equ P3.4
;R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。
;当RS和RW共同为低电平时可以写入指令或者显示地址,
;当RS为低电平RW为高电平时可以读忙信号,
;当RS为高电平RW为低电平时可以写入数据;
RW                equ P3.5
;E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令;
EN                equ P3.7
;;串口接收完整数据标志单元
;DatOK             equ 28H
;串口数据接收缓冲区,收到03时,缓冲区单元重新指向30H,并建立标志,启动显示
ComDatBuf         equ 2AH
;标号==============指令================================地址===机器码=======
                   ORG   0000H
                   LJMP  Startup
                    ORG     0023H
                    LJMP    ComInt
        
Startup:           ;初始化所有单元为0
                   MOV   R0,#7FH
                   CLR   A
initmem:           MOV   @R0,A
                   DJNZ  R0,initmem
                   ;设置堆栈地址
                   MOV   SP,#40H
                   
                   ;初始化LCD1602
                   LCALL InitLcd
                   
                   ;初始化串口:2400,N,8,1
                   Lcall InitCom
                   
Main:               NOP
                    ;建立串口缓冲区接收地址
                    MOV     R0,     #ComDatBuf
                    
                    MOV   R7,#0AH
                    MOV   R6,#00H
                    LCALL _DELAY
;清除显示
                   ;LCALL ClearDisp
;显示第一行字符串                   
                   CLR   A
                   MOV   R7,A
                   LCALL LCD_POS
DispLine1:         MOV   A,R6
                   MOV   DPTR,#LineStr1
                   MOVC  A,@A+DPTR
                   MOV   R7,A
                   JZ    Line2Start
                   LCALL LCD_WDAT
                   INC   R6
                   LJMP  DispLine1
;显示第二行字符串
Line2Start:        MOV   R7,#41H
                   LCALL LCD_POS
                   CLR   A
                   MOV   R6,A
DispLine2:         MOV   A,R6
                   MOV   DPTR,#LineStr2
                   MOVC  A,@A+DPTR
                   MOV   R7,A
                   JZ    LoopEnd
                   LCALL LCD_WDAT
                   INC   R6
                   LJMP  DispLine2
LoopEnd:           LJMP  LoopEnd
;==========================================================================
InitLcd:           MOV   R7,#38H
                   LCALL LCD_WCMD
                   MOV   R7,#01H
                   MOV   R6,#00H
                   LCALL _DELAY
                   ;MOV   R7,#0CH
                   MOV   R7,#0FH
                   LCALL LCD_WCMD
                   MOV   R7,#01H
                   LCALL _DELAY
                   MOV   R7,#06H
                   LCALL LCD_WCMD
                   MOV   R7,#01H
                   LCALL _DELAY
                   LCALL LCD_WCMD
                   LJMP  _DELAY
;==========================================================================
LCD_WCMD:          LCALL LCD_Busy
                   JC    LCD_WCMD
                   CLR   RS
                   CLR   RW
                   CLR   EN
                   NOP
                   NOP
                   MOV   P1,R7
                   NOP
                   NOP
                   NOP
                   NOP
                   SETB  EN
                   NOP
                   NOP
                   NOP
                   NOP
                   CLR   EN
                   RET
;==========================================================================
LCD_WDAT:          LCALL LCD_Busy
                   JC    LCD_WDAT
                   SETB  RS
                   CLR   RW
                   CLR   EN
                   NOP
                   NOP
                   MOV   P1,R7
                   NOP
                   NOP
                   NOP
                   NOP
                   SETB  EN
                   NOP
                   NOP
                   NOP
                   NOP
                   CLR   EN
                   RET
;==========================================================================
;延时
_DELAY:            CLR   A
                   MOV   R5,A
Delay1:            MOV   A,R5
                   CLR   C
                   SUBB  A,R7
                   MOV   A,R6
                   XRL   A,#80H
                   MOV   R3,A
                   MOV   A,#80H
                   SUBB  A,R3
                   JNC   DelayEnd
                   CLR   A
                   MOV   R4,A
Delay2:            INC   R4
                   CJNE  R4,#0FDH,Delay2
                   INC   R5
                   SJMP  Delay1
DelayEnd:          RET
;==========================================================================
;检查LCD是否忙中
LCD_Busy:          CLR   RS
                   SETB  RW
                   SETB  EN
                   NOP
                   NOP
                   NOP
                   NOP
                   MOV   A,P1
                   RLC   A
                   CLR   EN
                   RET
;==========================================================================
;设置LCD显示位置
LCD_POS:           MOV   A,R7
                   ORL   A,#80H
                   MOV   R7,A
                   LJMP  LCD_WCMD
;清除所有显示                   
ClearDisp:         NOP
                   CLR   A
                   MOV   R7,A
                   LCALL LCD_POS
DispSpc1:          MOV   A,R6
                   MOV   DPTR,#LineSpace
                   MOVC  A,@A+DPTR
                   MOV   R7,A
                   JZ    LineSpc2Start
                   LCALL LCD_WDAT
                   INC   R6
                   LJMP  DispSpc1
                   
LineSpc2Start:     MOV   R7,#41H
                   LCALL LCD_POS
                   CLR   A
                   MOV   R6,A
DispSpc2:          MOV   A,R6
                   MOV   DPTR,#LineSpace
                   MOVC  A,@A+DPTR
                   MOV   R7,A
                   JZ    ClearEnd
                   LCALL LCD_WDAT
                   INC   R6
                   LJMP  DispSpc2 
ClearEnd:          RET
;初始化串口工作为2400,N,8,1模式,为了和HC-06匹配波特率
InitCom:            NOP
                    ;清除显示
                    LCALL ClearDisp
                    
                    MOV     TMOD, #20H          ;设置T1的工作模式:2、自动装载,8位计数器
                    MOV     TH1, #0FAH          ;6M晶振, 2400波特率
                    MOV     TL1, #0FAH
                    SETB    TR1                 ;允许T1开始工作       
            
                    MOVSCON, #50H;设定串行口工作模式=1,8位UART,软件控制允许串口接收数据。REN=1,允许接收;REN=0:禁止接收
                    ;MOV     PCON, #00H          ;波特率不加倍.6M晶振场合,2400波特率/4800波特率
            
            SETBES;允许串口中断
            SETBEA;开中断
            
            RET
            
;串口中断处理程序,接收来自HC-06的数据,并保存到缓冲区,
;收到结束标志时,建立允许显示标志DatOK,并准备转送。     
;未收到结束标志,但已经超过10个字符了,重新初始化接收缓冲区标志
;******************************串口中断处理程序,接收字符直到收到0x03或者超过了16个字符时
ComInt:         CLR     ES                      ;禁止中断
        PUSH    ACC                     ;保存现场
                PUSH    PSW
                PUSHB
        
        JNB     RI, ComEnd              ;收到数据?
        CLRRI
                ;取得串口数据
                MOV     A,      SBUF
                ;保存到缓冲区
                MOV     @R0,    A
                
                ;是否收到结束标志03H?
                XRL     A,      #03H
                JNZReadNext0
                
                ;显示串口数据到液晶上
                LCALl   DispComDat
                
                ;重新指向串口缓冲区首地址
                MOV     R0,     #ComDatBuf
                
                LJMP    ComEnd
                
ReadNext0:      NOP                             ;没有收到结束标志,但已经超过了16个字符?
                MOV     A,      #ComDatBuf
                ADD     A,      #16
                XRL     A,      R0
                JNZ     ReadNext
                
                ;显示串口数据到液晶上
                LCALl   DispComDat
                
                ;重新指向串口缓冲区首地址
                MOV     R0,     #ComDatBuf
                
                LJMP    ComEnd
                
ReadNext:       INC     R0;指向下一个缓冲区
                
ComEnd:         POPB
        POP     PSW
                POP     ACC
ComEnd1:        SETB    ES                  ;开放串口中断,允许下次接受
        RETI
        
;显示串口接收到的数据(结束标志03H,不能被显示)
DispComDat:     NOP
                MOV     R2,     #0              ;计数显示字符数目
                MOV     R1,     #ComDatBuf
                
                ;显示在第一行上                   
                CLR   A
                MOV   R7,   A
                LCALL LCD_POS
                
                ;循环接收缓冲区数据
DispComDat1:    MOV     A,    @R1
                MOV     B,    A
                ;是否为结束标志,是则不显示并退出
                XRL     A,    #03H
                JZ      DispComDatEnd
                
                ;不是结束标志,正常数据,发给液晶显示
                MOV     R7,     B
                LCALL   LCD_WDAT
                INC     R2
                
                ;是否已经显示了16个字符?
                MOV     A,      #16
                XRL     A,      R2
                JZ      DispComDatEnd
                ;没有。指向下一个数据,继续显示
                INC     R1
                LJMP  DispComDat1
                ;恢复缓冲区首地址
DispComDatEnd:  MOV     R0,     #ComDatBuf
                RET        
                         
;==========================================================================
                   ;数据定义区
;==========================================================================
LineSpace:   DB  '                   '
             DB 00H
;LineStr1: DB  20H, 20H, 57H, 61H, 6EH, 67H, 48H, 65H, 6AH, 75H, 6EH, 20H, 20H, 00H;
LineStr1: DB  '2016-12-12 12:00:00'
             DB  00H
LineStr2: DB  20H, 31H, 38H, 36H, 32H, 34H, 32H, 30H, 31H, 38H, 35H, 32H, 20H, 00H;
END

程序中都有注释,很容易理解。





关键词: AT89C2051     LCD1602    

助工
2024-05-18 00:15:57     打赏
2楼

神人啊,还在用汇编


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]