📄 main.asm
字号:
;*************************************************************************
; main.asm
; 16×16 LED点阵的扫描显示:滚动显示文字
;*************************************************************************
;*************************************************************************
;设置屏幕滚动速度(单位:×10ms)
;*************************************************************************
SCROLL_SPEED EQU 15
;*************************************************************************
;定义I/O端口
;*************************************************************************
STR BIT P1.3 ;74HC595存储寄存器时钟(Storage register clock)
SI BIT P1.4 ;74HC595串行输入信号(Serial Input)
SCK BIT P1.5 ;74HC595移位寄存器时钟(Shift register clock)
;*************************************************************************
;定义全局变量
;*************************************************************************
DispBuf IDATA 0x30 ;定义显示缓冲区(在T1定时中断里扫描)
T1INTSVC_n DATA 0x30+32 ;函数T1INTSVC()中的静态变量
;*************************************************************************
;复位入口
;*************************************************************************
ORG 0x0000
LJMP Premain
;*************************************************************************
;T1中断入口
;*************************************************************************
ORG 0x001B
LJMP T1INTSVC
;*************************************************************************
;文件包含
;*************************************************************************
$INCLUDE(Branch.INC) ;分支判断
$INCLUDE(Zimo.inc) ;包含字模点阵头文件
;*************************************************************************
;程序段:Premain
;功能:进入函数main()之前的初始化
;*************************************************************************
Premain:
MOV SP, #(0x2F+33)
MOV T1INTSVC_n, #0
LJMP main
;*************************************************************************
;函数:void SysInit()
;功能:系统初始化
;*************************************************************************
SysInit:
CLR A
MOV R1, A
MOV R0, #DispBuf
SysInit_for:
MOV @R0, A
INC R0
INC R1
CJNE R1, #32, SysInit_for
SETB STR
CLR SI
CLR SCK
ANL TMOD, #0xF0
ORL TMOD, #0x01
ANL TMOD, #0x0F
ORL TMOD, #0x10
MOV TH1, #0xFC
MOV TL1, #0x66
SETB TR1
SETB ET1
SETB EA
RET
;*************************************************************************
;函数:Delay()
;功能:延时10ms~2.56s
;参数:
; t>0时,延时(t*10)ms
; t=0时,延时2.56s
;*************************************************************************
; void Delay(unsigned char t)
; t = R7
Delay:
MOV TH0, #0xDC
MOV TL0, #0x66
SETB TR0
JNB TF0, $
CLR TR0
CLR TF0
DJNZ R7, Delay
RET
;*************************************************************************
;函数:isupper()
;功能:判断字符c是否为大写字母
;*************************************************************************
; bit isupper(unsigned char c)
; c = R7
; 返回值 = CY
isupper:
;{
; if ( (c >= 'A') && (c <= 'Z') )
BLO R7, #'A', isupper_endif
BHI R7, #'Z', isupper_endif
; {
; return 1;
SETB C
RET
; }
isupper_endif:
; return 0;
CLR C
;}
RET
;*************************************************************************
;函数:islower()
;功能:判断字符c是否为小写字母
;*************************************************************************
; bit islower(unsigned char c)
; c = R7
; 返回值 = CY
islower:
;{
; if ( (c >= 'a') && (c <= 'z') )
BLO R7, #'a', islower_endif
BHI R7, #'z', islower_endif
; {
; return 1;
SETB C
RET
; }
islower_endif:
; return 0;
CLR C
;}
RET
;*************************************************************************
;函数:void PutChar(unsigned char c)
;功能:滚动显示一个字母或汉字
;参数:
; c:字母或汉字的编码,当c>=0x80时视为汉字
;*************************************************************************
; void PutChar(unsigned char c)
; c = R7
PutChar:
;{
; unsigned int a; //地址变量
; unsigned char i,j; //循环变量
; unsigned char t; //临时变量
; unsigned char code *Tab; //指针,用于查表
; 分配:a = (R2,R3)
; 分配:i = R4
; 分配:j = R5
; 分配:t = R6
; 分配:*Tab = (0x18,0x19)
PUSH 0x02
PUSH 0x03
PUSH 0x04
PUSH 0x05
PUSH 0x06
PUSH 0x18
PUSH 0x19
; t = 8;
MOV R6, #8
; if ( c >= 0x80 ) //如果c是汉字
BLO R7, #0x80, PutChar_elseif1
; {
; t = 16;
MOV R6, #16
; a = 32 * ( c - 0x80 );
MOV A, R7
CLR C
SUBB A, #0x80
MOV B, #32
MUL AB
MOV R2, B
MOV R3, A
; Tab = HanziTab;
MOV 0x18, #HIGH(HanziTab)
MOV 0x19, #LOW(HanziTab)
; }
SJMP PutChar_endif
; else if ( isupper(c) ) //如果c是大写字母
PutChar_elseif1:
LCALL isupper
JNC PutChar_elseif2
; {
; a = 16 * ( c - 'A' );
MOV A, R7
CLR C
SUBB A, #'A'
MOV B, #16
MUL AB
MOV R2, B
MOV R3, A
; Tab = UpperTab;
MOV 0x18, #HIGH(UpperTab)
MOV 0x19, #LOW(UpperTab)
; }
SJMP PutChar_endif
; else if ( islower(c) ) //如果c是小写字母
PutChar_elseif2:
LCALL islower
JNC PutChar_else
; {
; a = 16 * ( c - 'a' );
MOV A, R7
CLR C
SUBB A, #'a'
MOV B, #16
MUL AB
MOV R2, B
MOV R3, A
; Tab = LowerTab;
MOV 0x18, #HIGH(LowerTab)
MOV 0x19, #LOW(LowerTab)
; }
SJMP PutChar_endif
; else //如果是其它字符
PutChar_else:
; {
; return;
SJMP PutChar_end
; }
PutChar_endif:
; for ( j=0; j<t; j++ )
MOV R5, #0
PutChar_for1:
; {
; for ( i=0; i<15; i++ )
MOV R4, #0
PutChar_for2:
; {
; DispBuf[i] = DispBuf[i+1];
MOV A, #DispBuf
ADD A, R4
MOV R0, A
INC A
MOV R1, A
MOV A, @R1
MOV @R0, A
; DispBuf[16+i] = DispBuf[17+i];
MOV A, R0
ADD A, #16
MOV R0, A
INC A
MOV R1, A
MOV A, @R1
MOV @R0, A
; }
INC R4
CJNE R4, #15, PutChar_for2
; DispBuf[i] = Tab[a+j];
MOV A, #DispBuf
ADD A, R4
MOV R0, A
MOV A, 0x19
ADD A, R3
MOV DPL, A
MOV A, 0x18
ADDC A, R2
MOV DPH, A
MOV A, R5
MOVC A, @A+DPTR
MOV @R0, A
; DispBuf[16+i] = Tab[a+j+t];
MOV A, R0
ADD A, #16
MOV R0, A
MOV A, R5
ADD A, R6
MOVC A, @A+DPTR
MOV @R0, A
; Delay(SCROLL_SPEED);
PUSH 0x07
MOV R7, #SCROLL_SPEED
LCALL Delay
POP 0x07
; }
INC R5
BLO R5, R6, PutChar_for1
PutChar_end:
POP 0x19
POP 0x18
POP 0x06
POP 0x05
POP 0x04
POP 0x03
POP 0x02
RET
;*************************************************************************
;函数:PutStr()
;功能:滚动显示一个文字串
;参数:
; *str:以'\0'结尾的文字串
; *str可以同时包含字母和汉字,其中汉字必须是小汉字库内的汉字
;*************************************************************************
; void PutStr(unsigned char code *str)
; *str = (R6,R7)
PutStr:
PUSH 0x02
PUSH 0x03
MOV A, R6
MOV R2, A
MOV A, R7
MOV R3, A
; unsigned char c;
; for (;;)
PutStr_for:
; {
; c = *str++;
MOV DPH, R2
MOV DPL, R3
CLR A
MOVC A, @A+DPTR
INC DPTR
MOV R2, DPH
MOV R3, DPL
; if ( c == '\0' ) break;
JZ PutStr_endfor
; PutChar(c);
MOV R7, A
LCALL PutChar
; }
SJMP PutStr_for
PutStr_endfor:
POP 0x03
POP 0x02
RET
;*************************************************************************
;函数:void T1INTSVC() interrupt 3 using 2
;功能:T1中断服务函数
;*************************************************************************
T1INTSVC:
;保护寄存器
PUSH ACC
PUSH PSW
PUSH DPH
PUSH DPL
;切换到第2组工作寄存器
SETB RS1
CLR RS0
;定义变量
; static unsigned char n = 0; //局部静态变量,用于查表
; unsigned char i,j; //循环变量
; unsigned char d; //临时变量
; unsigned char data buf[4]; //临时数组,用于向74HC595发送数据
; 分配:i = R2
; 分配:j = R3
; 分配:d = ACC
;分配数组buf[]
MOV A, SP
INC A
MOV R4, A
ADD A, #3
MOV SP, A
;处理定时器T1
; TR1 = 0;
; TH1 = 0xFC;
; TL1 = 0x66;
; TR1 = 1;
CLR TR1
MOV TH1, #0xFC
MOV TL1, #0x66
SETB TR1
;查表,取得要发送的数据
; buf[0] = Tab[n];
MOV A, R4
MOV R0, A
MOV A, T1INTSVC_n
MOV DPTR, #T1INTSVC_Tab
MOVC A, @A+DPTR
MOV @R0, A
INC R0
; buf[1] = Tab[16+n];
MOV A, T1INTSVC_n
ADD A, #16
MOVC A, @A+DPTR
MOV @R0,A
INC R0
; buf[2] = DispBuf[16+n];
MOV A, #DispBuf
ADD A, #16
ADD A, T1INTSVC_n
MOV R1, A
MOV A, @R1
MOV @R0, A
INC R0
; buf[3] = DispBuf[n];
MOV A, #DispBuf
ADD A, T1INTSVC_n
MOV R1, A
MOV A, @R1
MOV @R0, A
; n++;
; n &= 0x0F;
INC T1INTSVC_n
ANL T1INTSVC_n, #0x0F
;向74HC595发送数据
; STR = 0;
CLR STR
; for ( i=0; i<4; i++ )
MOV R2, #0
MOV A, R4
MOV R0, A
T1INTSVC_for:
; {
; d = buf[i];
MOV A, @R0
INC R0
; j = 8;
MOV R3, #8
; do
T1INTSVC_do:
; {
; SI = (bit)(d & 0x01);
MOV C, ACC.0
MOV SI, C
; SCK = 1;
; d >>= 1;
; SCK = 0;
SETB SCK
RR A
ANL A, #0x7F
CLR SCK
; } while ( --j != 0 );
DJNZ R3, T1INTSVC_do
; }
INC R2
CJNE R2, #4, T1INTSVC_for
; STR = 1;
SETB STR
;释放数组buf[]
MOV A, SP
CLR C
SUBB A, #4
MOV SP, A
;恢复寄存器
POP DPL
POP DPH
POP PSW
POP ACC
;中断返回
RETI
T1INTSVC_Tab:
;定义扫描数据表
DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE
DB 0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
;*************************************************************************
;函数:void main()
;功能:主函数
;*************************************************************************
main:
LCALL SysInit
main_Loop:
MOV R6, #HIGH(main_s)
MOV R7, #LOW(main_s)
LCALL PutStr
SJMP main_Loop
main_s:
;定义文字串
DB 0x81 ;欢
DB 0x82 ;迎
DB 0x83 ;使
DB 0x84 ;用
DB 'S','m','a','r','t','S','O','P','C'
DB 0x85 ;教
DB 0x86 ;学
DB 0x87 ;实
DB 0x88 ;验
DB 0x89 ;开
DB 0x8A ;发
DB 0x8B ;平
DB 0x8C ;台
DB 0x80 ; (全角空白)
DB 0x00
;*************************************************************************
;程序结束
;*************************************************************************
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -