AT89C51单片机实验

img


AT89C51单片机实验,使用汇编语言编写,keil内编写,5.25前完成

答案参考ChatGPT Plus版,整理汇总。希望能帮助你解决问题
实验一BCD码加法实验

下面是一个简单的示例程序,用于实现BCD码的加法运算:

ORG 0000H ; 程序起始地址

MAIN: ; 主程序
    MOV R0, #0 ; 清零寄存器R0
    MOV R1, #0 ; 清零寄存器R1

    ; 假设要相加的两个BCD数分别存储在内存地址0x1000和0x1001
    ; 可根据实际情况修改存储地址

    MOV DPTR, #1000H ; 将内存地址0x1000存入DPTR寄存器
    MOVX A, @DPTR ; 将0x1000地址处的数据读取到累加器A中
    ADD A, R0 ; 将A与R0相加
    MOV R0, A ; 将结果存入R0

    INC DPTR ; DPTR加1,指向下一个内存地址
    MOVX A, @DPTR ; 将0x1001地址处的数据读取到累加器A中
    ADD A, R1 ; 将A与R1相加
    MOV R1, A ; 将结果存入R1

    ACALL BCD_ADD ; 调用BCD加法子程序

    ; 将加法结果存储到内存地址0x2000处
    MOV DPTR, #2000H ; 将内存地址0x2000存入DPTR寄存器
    MOV A, R0 ; 将R0的值存入累加器A中
    MOVX @DPTR, A ; 将累加器A的值写入0x2000地址处

    INC DPTR ; DPTR加1,指向下一个内存地址
    MOV A, R1 ; 将R1的值存入累加器A中
    MOVX @DPTR, A ; 将累加器A的值写入0x2001地址处

    SJMP MAIN ; 无限循环

BCD_ADD: ; BCD加法子程序
    PUSH ACC ; 保存累加器A的值
    PUSH PSW ; 保存程序状态字寄存器的值

    MOV A, R0 ; 将R0的值存入累加器A中
    ADD A, R1 ; 将A与R1相加
    DAA ; 进行十进制调整
    MOV R0, A ; 将结果存入R0

    POP PSW ; 恢复程序状态字寄存器的值
    POP ACC ; 恢复累加器A的值
    RET ; 返回主程序

END ; 程序结束标记
                                                                                       ——四个实验操作——

为了BCD加法实验:


; BCD addition program
; Adds two 16-bit BCD numbers and stores the result in memory location 30H-31H

ORG 0000H
    SJMP START

ORG 0030H
    DB 00H        ; store result LSB here
    DB 00H        ; store result MSB here

ORG 0040H
START:
    MOV A, #0AH   ; set accumulator to 10
    MOV R1, #00H  ; clear R1 register

LOOP:
    MOV R0, #00H  ; clear R0 register

    MOV A, #0AH   ; set accumulator to 10
    ADD A, @SOURCE1 ; add first source digit
    ADD A, @SOURCE2 ; add second source digit

    JC CARRY      ; jump to CARRY if result is greater than 99

    MOV R0, A     ; store result in R0

    SJMP SKIP

CARRY:
    SUBB A, #0AH  ; adjust result by subtracting 10
    MOV R0, A     ; store adjusted result in R0

SKIP:
    INC SOURCE1   ; increment source 1 pointer
    INC SOURCE2   ; increment source 2 pointer

    MOV A, R1     ; add carry from previous digit (if any)
    ADD A, R0     ;ADD A, @RESULT  ; add previous result digit
    MOV @RESULT, A ; store result digit

    JC CARRY2     ; jump to CARRY2 if result is greater than 99

    SJMP NEXT

CARRY2:
    SUBB A, #0AH  ; adjust result by subtracting 10
    MOV @RESULT, A ; store adjusted result digit
    SETB C        ; set carry flag

NEXT:
    INC RESULT   ; increment result pointer
    DJNZ COUNT, LOOP ; loop through all digits

    MOV A, R1   ; check for carry out of last digit
    JZ DONE     ; if no carry, we're done

    MOV A, @RESULT ; if carry, adjust last result digit
    ADD A, #10
    MOV @RESULT, A

DONE:
    SJMP $       ; program end

COUNT:
    DB 04H      ; loop counter

SOURCE1:
    DB 06H, 07H, 08H, 09H ; first source number

SOURCE2:
    DB 02H, 01H, 00H, 09H ; second source number

RESULT:
    DB 00H, 00H ; result number

来源数字循环计数器是LED闪烁实验:


; LED blinking program
; Blinks 4 LEDs connected to P1.7, P1.6, P4.7, and P4.6 at a rate of 0.5 seconds per transition

ORG 0000H
    SJMP START

ORG 0040H
START:
    MOV P1M0, #00H ; configure P1.7 and P1.6 as outputs
    MOV P4M1, #00H ; configure P4.7 and P4.6 as outputs

    MOV A, #0F0H   ; set initial LED pattern
    MOV P1, A      ; output to P1
    MOV P4, A      ; output to P4

    MOV R0, #0AH   ; set loop counter to 10
LOOP:
    CALL DELAY     ; delay for 0.5 seconds
    CPL P1.7       ; toggle P1.7
    CPL P1.6       ; toggle P1.6
    CPL P4.7       ; toggle P4.7
    CPL P4.6       ; toggle P4.6
    DJNZ R0, LOOP  ; loop 10 times

    SJMP $         ; program end

DELAY:
    MOV R1, #0FFH  ; set delay counter to 255
    MOV R2, #For the external interrupt experiment:

外部中断程序:


;回应
; 切换

组织机构
SJMP 开始

组织机构
数据库 00H ; 店铺

组织机构
开始:
MOV P4M1
MOV P3M1,#

MOV A, #00H    ; clear LED state
MOV @LEDSTATE, A ; store in memory

MOV TMOD, #01H ; configure timer 0 as 16-bit timer with mode 1
MOV TH0, #-50000/256 ; set timer 0 to overflow every 1 second
MOV TL0, #-50000%256
SETB ET0       ; enable timer 0 interrupt
SETB EA        ; enable interrupts globally

MOV A, #00H    ; clear LED state
MOV P4.6, A    ; initialize LED state
等待:
MOV A,@LEDSTATE
CJ

SJMP $         ; program end

; 定时器程序
;使用定时器 0 中断每 1 秒切换一次 P4.6

; Timer program
; Toggles P4.6 every 1 second using timer 0 interrupt

ORG 0000H
    SJMP START

ORG 0040H
START:
    MOV P4M1, #00H ; configure P4.6 as output

    MOV TMOD, #01H ; configure timer 0 as 16-bit timer with mode 1
    MOV TH0, #-50000/256 ; set timer 0 to overflow every 1 second
    MOV TL0, #-50000%256
    SETB ET0       ; enable timer 0 interrupt
    SETB EA        ; enable interrupts globally

    MOV A, #00H    ; clear LED state
    MOV P4.6, A    ; initialize LED state

WAIT:
    SJMP WAIT      ; loop indefinitely

TIMER0_ISR:
    CPL P4.6       ; toggle LED state
    RETI           ; return from interrupt