# 1
求 1+2+3+…+99 的 BCD 和,存入 RAM 高 128B 区域
ORG 0000H
LJMP START
ORG 0100H
START:
MOV R2, #01H ; 初始化计数器R2为1
MOV R3, #99H ; 循环99次
MOV A, #00H ; 初始化累加器A为0
MOV B, #00H ; 初始化寄存器B为0,用于进位
LOOP:
ADD A, R2 ; 将R2中的值加到累加器A中
INC R2 ; 计数器R2加1
DJNZ R3, LOOP ; 减1非0转移进行循环
; 现在A中包含1到99的和
MOV B, A ; 将累加结果存入B
MOV A, #00H ; 清空累加器A
; 转换为BCD码
MOV A, B ; 将累加结果存入A
DA A ; BCD码调整
MOV R4, A ; 将调整后的BCD码存入R4
; 存储结果到RAM高128B区域
MOV R0, #80H ; 设置RAM地址
MOV A, R4
MOV @R0, A ; 存储结果
SJMP $ ; 无限循环,终止程序
END
# 2
使用外部中断 0 和外部中断 1,在动态数码管上显示中断 0 次数,中断 1 用作次数清 0。数码管采用 74HC595 驱动。中断次数显示形式自定(3 位十进制或 2 位 16 进制)
ORG 0000H
LJMP Main
ORG 0003H ; 外部中断0向量地址
LJMP INT0_ISR
ORG 0033H ; 外部中断1向量地址
LJMP INT1_ISR
ORG 0100H
Main: SETB EX0 ; 外部中断0允许
SETB IT0 ; 外部中断0下降沿触发
SETB EX1 ; 外部中断1允许
SETB IT1 ; 外部中断1下降沿触发
Loop: DispScan;
SJMP Loop
INT0_ISR:
INC CNT ; CNT加1
RETI ; 返回主程序
INT1_ISR:
MOV CNT, #0 ; CNT清零
RETI ; 返回主程序
DispScan: MOV A, CNT
MOV B, #10
DIV AB
MOV R5, A ;R5存百位
MOV A, #10
XCH A, B
DIV AB
MOV R6, A ; R6存十位
MOV R7, B ; R7存个位
MOV P1,#0FEH ;选中最右边数码管
MOV DPTR, #T_Disp ; 7段码表头
MOV A, R7 ; 待显示的个位数
MOVC A, @A+DPTR
MOV P0, A
MOV P1,#0FDH ;选中最右边第2数码管
MOV A, R6 ; 待显示的十位数
MOVC A, @A+DPTR
MOV P0, A
MOV P1,#0FBH ;选中最右边第3数码管
MOV A, R5 ; 待显示的百位数
MOVC A, @A+DPTR
MOV P0, A
T_Disp: DB 3FH,06H,5BH,4FH,66H,6DH, 7DH,07H
DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H; 0-F的7段码
# 3
定时器 0/1 做 16 位自动重装,使 P1.7 输出周期为 1 秒或 2 秒的矩形波,占空比自定。
ORG 0000H
LJMP MAIN
; 定义单片机寄存器
P1 EQU 90H
TMOD EQU 89H
TH0 EQU 8CH
TL0 EQU 8AH
TCON EQU 88H
; 定义常量
TIMER0_MODE EQU 00000001B ; 定时器0模式1(16位定时器)
TIMER0_START EQU 00000001B ; 启动定时器0
TIMER0_STOP EQU 00000000B ; 停止定时器0
; 初始化定时器0
INIT_TIMER0:
MOV TMOD, TIMER0_MODE ; 设置定时器0为模式1
MOV TH0, #0FCH ; 高8位初值
MOV TL0, #18H ; 低8位初值
SETB TR0 ; 启动定时器0
RET
; 定时器0中断服务程序
TIMER0_ISR:
CLR TR0 ; 停止定时器0
CPL P1.7 ; 翻转P1.7引脚状态
MOV TH0, #0FCH ; 重新加载高8位初值
MOV TL0, #18H ; 重新加载低8位初值
SETB TR0 ; 重新启动定时器0
RETI
; 主程序
MAIN:
MOV P1, #00H ; 初始化P1口
CALL INIT_TIMER0 ; 初始化定时器0
SETB EA ; 开启全局中断
SETB ET0 ; 开启定时器0中断
SJMP $ ; 无限循环
END