赞助论坛
  • 11596阅读
  • 0回复

8x8点阵LED字符显示器的设计 [复制链接]

楼层直达
liyan  
发帖
60
精华
0
金币
105
威望
1
贡献
4
好评
0
注册
2009-09-09
楼主    liyan 发表于: 2009-09-14 08:40:24 
[post] ;功能说明 8x8点阵LED字符显示器的设计
;中断入口程序
ORG     0000H       ;程序执行开始地址
LJMP   START       ;跳至START执行
ORG     0003H       ;外中断0中断入口地址
RETI             ;中断返回(不开中断)
ORG     000BH       ;定时器T0中断入口地址
RETI             ;中断返回(不开中断)
ORG     0013H       ;外中断1中断入口地址
RETI             ;中断返回(不开中断)
ORG     001BH       ;定时器T1中断入口地址
RETI             ;中断返回(不开中断)
ORG     0023H       ;串行口中断入口地址
RETI             ;中断返回(不开中断)
ORG     002BH       ;定时器T2中断入口地址
RETI             ;中断返回(不开中断)
;初始化程序
CLEARMEN: MOV A,#0FFH ;四端口置1
      MOV P1,A   ;
      MOV P2,A   ;
      MOV P3,A   ;
      MOV P0,A
      MOV DPTR,#TAB;取"电子设计"字符表首址值
      CLR A     ;
      MOV 21H,A   ;21H~24H内存内存单元清0
      MOV 22H,A   ;
      MOV 23H,A   ;
      MOV 24H,A   ;
      MOV R3,A   ;R3寄存器清0
      MOV R1,#50H ;设安符表移入内存单元首址
      MOV R2,#20H ;设查表次数(32次)
CLLOOP:   MOVC A,@A+DPTR;查表将"电子设计"字符数据移入内存单元
      MOV @R1,A   ;
      MOV A,R3   ;
      INC A     ;
      MOV R3,A   ;
      INC R1     ;
      DJNZ R2,CLLOOP;查表32次,不到转CLLOOP再查
      RET       ;子程序返回
;主程序
START:   MOV 20H,#00H ;20H内存单元清0
      SETB 00H     ;20H.0位置1
START1:   LCALL CLEARMEN;调用上电初始化子程序
      JB 00H,FUN0 ;20H.0位为1,执行FUN0
      JB 01H,FUN1 ;20H.1位为1,执行FUN1
      JB 02H,FUN2 ;20H.2位为1,执行FUN2
      AJMP START1   ;跳回START1循环
;键扫描子程序
KEYWORK: MOV P1,#0FFH ;置输入状态
      JNB P1.0,KEY1;P1.0为0(键按下)转KEY1
      JNB P1.1,KEY2;P1.1为0(键按下)转KEY2
      JNB P1.2,KEY3;P1.2为0(键按下)转KEY3
KEYRET:   RET       ;无键按下,子程序返回
;按键1功能处理
KEY1:   LCALL DL10MS ;延时10MS消抖动
      JB P1.0,KEYRET ;是干扰转KEYRET结束
      SETB 00H   ;置逐字显示方式标志(20H.0=1)
      CLR   01H   ;
      CLR   00H   ;
      CLR   02H   ;
      RET       ;子程序返回
;按键2功能处理
KEY2:   LCALL DL10MS ;
      JB P1.1,KEYRET ;
      SETB 01H   ;置上移字显示方式标志(20H.1=1)
      CLR   00H   ;
      CLR   02H   ;
      RET       ;子程序返回
;按键3功能处理
KEY3:   LCALL DL10MS ;
      JB P1.2,KEYRET ;
      SETB 02H   ;置左移显示方式标志(20H.2=1)
      CLR   01H   ;
      CLR   01H   ;
      CLR   00H   ;
      RET       ;子程序返回
;逐字显示功能程序
FUN0:   MOV   30H,#80H   ;1帧显示时间控制(约1S)
      MOV   31H,#08H   ;换帧跳转步距为8
      LJMP DISP1     ;转显示子程序DISP1
;上移显示功能程序
FUN1:   MOV   30H,#0AH   ;1帧显示时间控制(约80MS)
      MOV   31H,#01H   ;换帧跳转步距为1
      LJMP DISP1     ;转显示子程序DISP1
;左移显示功能程序
FUN2:   LJMP DISP2     ;
;显示控制程序
DISP1:   MOV   B,#50H   ;显示数据首址
      MOV   R4,30H   ;放入1帧显示时间控制数据
      MOV   R5,31H   ;放入跳转步距控制数据
LOOP:   LCALL DISPLAY   ;调用显示子程序一次
      DJNZ R4,LOOP   ;1帧显示时间未到再转LOOP循环
      MOV   R4,30H   ;1帧显示时间到,重装初值
      MOV   A,B     ;
      CJNE A,#68H,CONT;不是末地址转CONT
      AJMP START1   ;是未地址,一次显示结束跳回START1
CONT:   ADD   A,R5     ;次帧扫描首址调整
      MOV   B,A     ;
      AJMP LOOP     ;转LOOP进行次帧扫描
;显示子程序,字符数据从P0口输出.扫描控制字从P2口输出.显示1帧约需8MS
DISPLAY: MOV   A,#0FFH   ;
      MOV   P0,A     ;关显示数据
      MOV   P2,A     ;关扫描
      MOV   R6,#0FFH   ;赋扫描字
      MOV   R0,B     ;赋显示数据首地址
      MOV   R7,#08H   ;一次扫描8行
DISLOOP: MOV   A,@R0     ;取显示数据
      MOV   P0,A     ;放入P0口
      MOV   P2,R6     ;扫描输出(显示某一行)
      LCALL DL1MS     ;亮1MS
      INC   R0       ;指向下一行数据地址
      MOV   A,R6     ;扫描字移入A
      RL   A       ;循环左移一位
      MOV   R6,A     ;放回R6
      DJNZ R7,DISLOOP ;8行扫描未完转DISLOOP继续
      RET         ;8行扫描结束
;左移显示控制程序
DISP2:   MOV   R5,#32   ;左移32次
DISP22:   LCALL DISPP     ;调用左移显示控制子程序
      LCALL MOVH     ;调用高位移出处理子程序MOVH
      LCALL MOVH1     ;调用高位移出处理子程序MOVH1
      DJNZ R5,DISP22 ;左移显示32次控制
      LJMP START1   ;跳回主程序
;左移显示控制子程序
DISPP:   MOV   B,#50H   ;第一显示字符首址
      MOV   R4,#25H   ;1帧显示时间控制
DISPP1:   LCALL DISPLAY   ;调用显示子程序一次
      DJNZ R4,DISPP1 ;1帧显示时音不到转DISPP再循环
      RET
;高位移出处理子程序,将"电子设计:四个字符数据的最高位移出至21H~24H单元内
MOVH:   MOV   R1,#21H   ;最高位移出存放单元首址
      MOV   R0,#50H   ;"电子设计"字符数据首址
      MOV   R2,#08H   ;每"字"移8次
MOV1:   MOV   A,@R0     ;取"电子设计"字符数据首址
      CLR   C       ;清进位C
      RLC   A       ;带进位循环左移
      MOV   @R0,A     ;放回原单元
      MOV   A,@R1     ;存放单元数据入A
      RRC   A       ;带进位循环右移
      MOV   @R1,A     ;放回存放单元
      INC   R0     ;字符数据地址加1
      DJNZ R2,MOV1   ;移8次未完转MOV1再移
      MOV   R2,#08H   ;8次移完赋初值
      INC   R1       ;存放单元地址是否小于25H
      MOV   A,R1     ;判断地址是否小于25H
      SUBB A,#25H   ;
      JZ   OUT     ;等于25H退出
      AJMP MOV1     ;小于25H转MOV1继续
OUT:     RET         ;子程序结束
;高位移出处理子程序
MOVH1:   MOV   A,21H     ;21H与22H,23H,24H单元数据循环交换
      XCH   A,24H     ;21H与24H全交换
      XCH   A,23H     ;23H与24H全交换
      XCH   A,22H     ;23H与22H全交换
      MOV   21H,A     ;22H与21H全交换
      MOV   R1,#21H   ;以下是重新组成显示安符数据表程序
      MOV   R0,#50H   ;将21H~24H的各位分别移入50H~6FH的低位
      MOV   R2,#08H   ;移位次数
MOV2:   MOV   A,@R0     ;取字符数据
      RR   A       ;右移
      MOV   @R0,A     ;放回原单元
      MOV   A,@R1     ;取原移出最高位存放单元数
      CLR   C       ;清C
      RRC   A       ;带进位循环右移
      MOV   @R1,A     ;放回原单元
      MOV   A,@R0     ;取字符数据
      RLC   A       ;带进位循环左移
      MOV   @R0,A     ;放回字符数据
      INC   R0       ;字符数据地址加1
      DJNZ R2,MOV2   ;8次未完转MOV2再继续
      MOV   R2,#08H   ;8次未完赋初值
      INC   R1       ;原移出最高位存放单元地址加1
      MOV   A,R1     ;判断地址是否小于25H
      MOV   A,#25H   ;
      JZ   OUT     ;等于25H转OUT退出
      AJMP MOV2     ;小于25H转MOV2继续
;1MS延时子程序,采用调用扫键子程序延时,可快速读出按钮的状态
DL1MS :   MOV   R3,#64H   ;100X(10+2)US
LOOPK:   LCALL KEYWORK
      DJNZ R3,LOOPK
      RET
;0.5MS延时子程序
DL512:   MOV   R2,#0FFH
LOOP1:   DJNZ R2,LOOP1
      RET
;10MS延时子程序
DL10MS:   MOV   R3,#14H
LOOP2:   LCALL DL512
      DJNZ R3,LOOP2
      RET
;"电子设计"显示用ROM数据表
TAB:     DB 0EFH,83H,0ABH,83H,0ABH,83H,0EEH,0E0H ;电
      DB 0FFH,0C7H,0EFH,83H,0EFH,0EFH,0CFH,0EFH;子
      DB 0B1H,0B5H,04H,0BFH,0B1H,0B5H,9BH,0A4H ;设
      DB 0BBH,0BBH,1BH,0A0H,0BBH,0BBH,9BH,0BBH ;计
      DB 00H,00H,00H,00H
      END[/post]