protues中LM032的仿真

虽然是两百来行的程序,但是今天我调试了一天才弄出来什么地方错了,呵呵。

原来是在读P0口的时候没有向P0口写#0ffh。弄的我忙了半天,最后在CSDN上找了个C的proteus仿真程序和keil的C程序。坚定了我的电路图是没有问题的,最后我一步一步的联合keil和proteus将错误找出来了,挺高兴的,呵呵。

想回报一下上传C源程序和proteus仿真程序的朋友,不过,今天没能传上去,只有在这发个图和汇编的程序了。等到可以上传资源了,我上传一下,弄点积分,好在学习点东西啊!

呵呵,祝大家好运!

 

   RS   BIT P2.5    ;寄存器选择信号
   RorW BIT P2.6 ;读、写选择信号
   E    BIT P2.7 ;使能控制
   ORG  0000H
   LJMP MAIN
   ORG  0030H
MAIN:
   MOV  SP,#60H     ;设堆栈指针
   LCALL INIT       ;调LCM初始化程序
   LCALL FIRST      ;调设定显示地址为第1行,第1个位置子程序
   MOV   DPTR,#TAB1 ;设置第1行字符的首地址
   LCALL DISPLAY    ;调用显示字符子程序
   LCALL SECOND     ;调设定显示地址为第2行,第1个位置子程序
   MOV   DPTR,#TAB2 ;设置第2行字符的首地址
   LCALL DISPLAY    ;调用显示字符子程序
   SJMP  $          ;主程序结束

;LCM初始化程序(本程序采用了热启动的指令段)
;热启动操作步骤:1,写入指令代码,30H或38H。2,延时时间>4.1ms。
;                3,写入指令代码,30H或38H。4,延时时间>100us。
;                5,写入指令代码,30H或38H。
INIT:
   LCALL  DELAY1    ;调延时5ms的子程序
   LCALL  DELAY1    ;延时,等待电源稳定
   MOV    A,#38H  ;可以写30H或38H,我感觉,这是写工作方式的字节吧,
                     ;工作方式:0 0 1 DL N F * *,
      ;DL=1,采用8位数据总线,N=1,显示双行字符行,F=0,采用5*&点阵字符体
   MOV    P2,#00011111B    ;E,RS,RorW为0
   NOP
   SETB   E          ;E为高,使能
   MOV    P0,A       ;写入指令代码

   CLR    E
      
   LCALL  DELAY1     ;延时5ms

   MOV    A,#38H
   MOV    P2,#00011111B
   NOP
   SETB   E
   MOV    P0,A
   CLR    E

   LCALL  DELAY2     ;延时120us子程序
  
   MOV    A,#38H
   MOV    P2,#00011111B
   NOP
   SETB   E
   MOV    P0,A
   CLR    E
   LCALL  DELAY2      ;延时120us子程序
;热启动程序到此结束
;下面是初始化程序
   MOV    A,#38H      ;工作方式设置为2行显示,8为数据总线,5*7点阵字符体
   ACALL  WRC         ;判断BF和写命令
   MOV    A,#01H      ;清除显示
   ACALL  WRC
   MOV    A,#06H      ;设置输入方式为AC加1,光标右移,画面不动
   ACALL  WRC
   MOV    A,#0EH      ;设置显示状态为开显示,显示光标,不闪烁
   ACALL  WRC
   RET
;初始化程序到此结束

;判读BF和写指令
WRC:
   ACALL  BUSY        ;调判读BF子程序
   MOV    P2,#00011111B  ;E,RorW,RS为0,准备写
   NOP
   SETB   E    ;使能
   MOV    P0,A        ;写指令代码  
   CLR    E          ;E为低
   RET
;判断忙程序,不忙则返回
BUSY:
   PUSH  ACC
W: MOV   P2,#01011111B     ;RS=0,RorW=1,E=0,准备读数据
   NOP
   mov    P0,#0FFh      ;将P0口设置为输入口
   SETB   E
//  mov    P0,0FFH
   NOP
   NOP
   MOV    A,P0             ;读BF和AC值
   JB     ACC.7,W          ;BF不为0,等待
   CLR    E
   POP    ACC
   RET

;写显示数据子程序
WRTD:
    ACALL   BUSY
 MOV     P2,#00111111B     ;RS=1,RorW=0,E=0,准备写数据
 SETB    E
 MOV     P0,A
 CLR     E
 LCALL   DELAY2
 RET

;显示字符程序
DISPLAY:
   MOV     R1,#00
  NEXT:
     MOV   A,R1
  MOVC  A,@A+DPTR        ;将DPTR所指的字符码逐一送到LCD显示
  CJNE  A,#21H,DSL       ;到结束符“!”时返回,否则继续显示
  RET
   DSL:
     LCALL WRTD             ;调显示子程序
  INC   R1
  SJMP  NEXT

FIRST:
  MOV   A,#10000000B       ;DDRAM的地址设为80H,即要显示的字符从第1行第1个位置开始
  CALL  WRC    
  RET

SECOND:
  MOV  A,#11000000B        ;DDRAM的地址设为C0H,即要显示的字符从第2行第1个位置开始
  CALL WRC
  RET
DELAY1:
  MOV  R7,#05H        ;毫秒数
 DL1:
      MOV R6,#0FAH   ;12MHz,1ms延时预设值
 DL2:
      NOP
   NOP
   DJNZ  R1,DL2
   DJNZ  R7,DL1
RET

DELAY2:
   MOV  R7,#0CH       ;10us的倍数
  DL3:
    NOP
 NOP
 NOP
 NOP
 NOP
 NOP
 NOP
 NOP
  DJNZ  R7,DL3
RET
 

TAB1:
  DB  '  WELCOME TO'   ;LCD第1行显示的字符
  DB  '!'                       ;结束码为“!”
TAB2:
  DB  '  OUR UNIVERSITY'        ;LCD第2行显示的字符
  DB  '!'                       ;结束码为“!”
  END         

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章