大三第二学期单片机课程设计-上机篇

设计前练习:


0.asm
                ORG    000H
                LJMP MAIN
                ORG    1000H
MAIN:        MOV 53H, #00H    ;初始化各数据
                MOV 52H, #00H
                MOV 51H, #00H
                MOV 50H, #00H
                MOV R5, #53H
KEYSUB:    MOV A, #03H        ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
                MOV DPTR, #7F00H    ;向8155写入命令字
                MOVX @DPTR, A
BEGIN:    ACALL DIS    ;调用显示函数
                ACALL CLEAR    
                ACALL CCSCAN    ;调用扫描函数
                JNZ INK1    ;若有键按下,则听到INK1, 否则重新扫描
                AJMP BEGIN
INK1:        ACALL DIS
                ACALL DL1MS    ;延时去抖
                ACALL DL1MS ;延时去抖
                ACALL CLEAR
                ACALL CCSCAN    ;再次扫描, 确保去抖后, 还能检测到有键按下
                JNZ    INK2
                AJMP BEGIN
INK2:        MOV R2, #0FEH    ;先扫描最左边列的按键
                MOV R4, #00H   
COLUM:    MOV DPTR, #7F01H  ;拉低某一列
                MOV A, R2
                MOVX @DPTR, A
                INC DPTR
                INC DPTR    
                MOVX A, @DPTR ;读取PC口, 即扫描行
                JB A.
0 , LONE ;若第一行没有有键按下, 则跳到LONE
                MOV A, #00H        ;第一行有键按下, A为0
                AJMP KCODE
LONE:        JB A.
1 NEXT         ;判断是否第二行有键按下
                MOV A, #04H        ;第二行有键按下, A为4
KCODE:    ADD A, R4
                ACALL PUTBUF ;将键码存入存储区, 先从53H到50H
                PUSH A
KON:        ACALL DIS    ;按键释放检测
                ACALL CLEAR
                ACALL CCSCAN
                JNZ KON    ;若一直有键被按下, 则一直等待键被释放
                POP A
NEXT :        INC R4    ;扫描列左移
                MOV A, R2
                JNB A.
3  KERR ;全部列已扫描完, 则重新开始
                RL A    ;列左移一位
                MOV R2, A
                AJMP COLUM    扫描行
KERR:        AJMP BEGIN
CCSCAN:    MOV DPTR, #7F01H ;扫描检测是否有键被按下函数, 若有键被按下, A不为0, 没有则A为0
                MOV A, #00H
                MOVX @DPTR, A
                INC DPTR
                INC DPTR
                MOVX A, @DPTR
                CPL A ;取反后, 没有键按下时, 低2位都为0, 有键按下时, 低2位都为1
                ANL A, #03H ;使A是否为0取决于低2位的值
                RET
CLEAR:    MOV DPTR, #7F02H ;消除余辉
                MOV A, #00H
                MOVX @DPTR, A
                RET
DIS:            PUSH A        ;显示函数, 将当前50H~53H单元中的数据显示在数码管上
                PUSH 00H  ;前三条指令用于现场保护
                PUSH 03H
                MOV A, #03H ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
                MOV DPTR, #7F00H
                MOVX @DPTR, A
                MOV R0, #50H
                MOV R3, #0F7H ; 先从最左边这位数码管开始显示
                MOV A, R3
AGAIN:    MOV DPTR, #7F01H   ;选中一个数码管
                MOVX @DPTR, A
                MOV A, @R0
                MOV DPTR, #TABLE
                MOVC A, @A
+ DPTR
                MOV DPTR, #7F02H  ;送入7段码
                MOVX @DPTR, A
                ACALL DL1MS
                INC R0    
                MOV A, R3
                JNB A.
0 , OUT ;已显示完4单元数据, 退出显示函数
                RR A 
                MOV R3, A
                AJMP AGAIN ;显示下一个单元
OUT:        POP 03H
                POP 00H
                POP A
                RET
TABLE:  DB 03FH, 06H, 05BH, 04FH, 066H, 06DH, 07DH, 07H
DL1MS:    MOV R7, #01H    ;延时函数, 延时1ms
DL0:        MOV R6, #0FFH
DL1:        DJNZ R6, DL1
                DJNZ R7, DL0
                RET
PUTBUF:PUSH 00H        ;将键码存入存储器单元的函数
                PUSH A
                MOV A, R5
                MOV R0, A
                POP A
                MOV @R0, A
                DEC R5
                CJNE R5, #04FH, GOBACK
                MOV R5, #53H
GOBACK: POP 00H
                RET
                
END
        

设计题目: 倒计时秒表
设计所使用的电路图(注意与上面的电路图的微小区别, 差别就体现在代码中)

1. 在显示器显示任意4位十六进制数.
ContractedBlock.gif ExpandedBlockStart.gif 1.asm
                ORG    000H
                LJMP MAIN
                ORG    1000H
;与之前的不同, 设计中的电路图, 8155PA口作为数码管的数据输入, PB高4位为字选控制端
MAIN:        MOV 53H, #0AH    ;初始化各数据, 从左到右显示ABC9
                MOV 52H, #0BH
                MOV 51H, #0CH
                MOV 50H, #09H
BEGIN:    ACALL DIS
                AJMP BEGIN
CLEAR:    MOV DPTR, #7F01H ;消除余辉
                MOV A, #00H
                MOVX @DPTR, A
                RET
DIS:            PUSH A        ;显示函数, 将当前50H~53H单元中的数据显示在数码管上
                PUSH 00H  ;前三条指令用于现场保护
                PUSH 03H
                MOV A, #03H ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
                MOV DPTR, #7F00H
                MOVX @DPTR, A
                MOV R0, #50H
                MOV R3, #0EFH ; 先从最右边这位数码管开始显示
                MOV A, R3
AGAIN:    MOV DPTR, #7F02H   ;选中一个数码管
                MOVX @DPTR, A
                MOV A, @R0
                MOV DPTR, #TABLE
                MOVC A, @A
+DPTR
                MOV DPTR, #7F01H  ;送入7段码
                MOVX @DPTR, A
                ACALL DL1MS
                ACALL CLEAR        ;消去余辉
                INC R0    
                MOV A, R3
                JNB A.
7, OUT ;已显示完4单元数据, 退出显示函数
                RL A 
                MOV R3, A
                AJMP AGAIN ;显示下一个单元
OUT:        POP 03H
                POP 00H
                POP A
                RET
TABLE:  DB 03FH, 06H, 05BH, 04FH, 066H, 06DH, 07DH, 07H, 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H
DL1MS:    MOV R7, #01H    ;延时函数, 延时1ms
DL0:        MOV R6, #0FFH
DL1:        DJNZ R6, DL1
                DJNZ R7, DL0
                RET
                
END
        

2.
ContractedBlock.gif ExpandedBlockStart.gif 2.asm
                ORG    000H
                LJMP MAIN
                ORG    1000H
MAIN:        MOV 53H, #00H    ;初始化各数据
                MOV 52H, #00H
                MOV 51H, #00H
                MOV 50H, #00H
                MOV R5, #53H
KEYSUB:    MOV A, #03H        ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
                MOV DPTR, #7F00H    ;向8155写入命令字
                MOVX @DPTR, A
BEGIN:    ACALL DIS    ;调用显示函数
                ACALL CLEAR    
                ACALL CCSCAN    ;调用扫描函数
                JNZ INK1    ;若有键按下,则听到INK1, 否则重新扫描
                AJMP BEGIN
INK1:        ACALL DIS
                ACALL DL1MS    ;延时去抖
                ACALL DL1MS ;延时去抖
                ACALL CLEAR
                ACALL CCSCAN    ;再次扫描, 确保去抖后, 还能检测到有键按下
                JNZ    INK2
                AJMP BEGIN
INK2:        MOV R2, #07FH    ;先扫描最左边列的按键
                MOV R4, #00H   
COLUM:    MOV DPTR, #7F02H  ;拉低某一列
                MOV A, R2
                MOVX @DPTR, A
                INC DPTR
                INC DPTR    
                MOVX A, @DPTR ;读取PC口, 即扫描行
                JB A.
2, LONE ;若第一行没有有键按下, 则跳到LONE
                MOV A, #00H        ;第一行有键按下, A为0
                AJMP KCODE
LONE:        JB A.
1NEXT        ;判断是否第二行有键按下
                MOV A, #04H        ;第二行有键按下, A为4
KCODE:    ADD A, R4
                ACALL PUTBUF ;将键码存入存储区, 先从53H到50H
                PUSH A
KON:        ACALL DIS    ;按键释放检测
                ACALL CLEAR
                ACALL CCSCAN
                JNZ KON    ;若一直有键被按下, 则一直等待键被释放
                POP A
NEXT:        INC R4    ;扫描列右移
                MOV A, R2
                JNB A.
4 KERR ;全部列已扫描完, 则重新开始
                RR A    ;列右移一位
                MOV R2, A
                AJMP COLUM    扫描行
KERR:        AJMP BEGIN
CCSCAN:    MOV DPTR, #7F02H ;扫描检测是否有键被按下函数, 若有键被按下, A不为0, 没有则A为0
                MOV A, #00H
                MOVX @DPTR, A
                INC DPTR
                INC DPTR
                MOVX A, @DPTR
                CPL A ;取反后, 没有键按下时, 
1,2位都为0, 有键按下时, 1,2位都为1
                ANL A, #06H ;使A是否为0取决于1,2位的值
                RET
CLEAR:    MOV DPTR, #7F01H ;消除余辉
                MOV A, #00H
                MOVX @DPTR, A
                RET
DIS:            PUSH A        ;显示函数, 将当前50H~53H单元中的数据显示在数码管上
                PUSH 00H  ;前三条指令用于现场保护
                PUSH 03H
                MOV A, #03H ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
                MOV DPTR, #7F00H
                MOVX @DPTR, A
                MOV R0, #53H
                MOV R3, #07FH ; 先从最左边这位数码管开始显示
                MOV A, R3
AGAIN:    MOV DPTR, #7F02H   ;选中一个数码管
                MOVX @DPTR, A
                MOV A, @R0
                MOV DPTR, #TABLE
                MOVC A, @A
+DPTR
                MOV DPTR, #7F01H  ;送入7段码
                MOVX @DPTR, A
                ACALL DL1MS
                DEC R0    
                MOV A, R3
                JNB A.
4, OUT ;已显示完4单元数据, 退出显示函数
                RR A 
                MOV R3, A
                AJMP AGAIN ;显示下一个单元
OUT:        POP 03H
                POP 00H
                POP A
                RET
TABLE:  DB 77H, 07H, 39H, 6FH
                DB 7CH, 7FH, 5EH, 06H
DL1MS:    MOV R7, #01H    ;延时函数, 延时1ms
DL0:        MOV R6, #0FFH
DL1:        DJNZ R6, DL1
                DJNZ R7, DL0
                RET
PUTBUF:PUSH 00H        ;将键码存入存储器单元的函数
                PUSH A
                MOV A, R5
                MOV R0, A
                POP A
                MOV @R0, A
                INC R5
                CJNE R5, #054H, GOBACK
                MOV R5, #50H
GOBACK:    MOV R0, 50H    ;低位的数
                    MOV R1, #51H  ;高一位的数
XCH1:            MOV A, R0
                    XCH A, @R1         ;
50~53H, 向左移一字节, 53H移到50H
                    MOV R0, A
                    INC R1
                    CJNE R1, #54H, XCH1
                    MOV 50H, R0
                    POP 00H
                    RET
                    
END
        

对应代码下载:
0.asm
1.asm


60分钟倒计时秒表

功能:

1.       带有启动键Start, 暂停键Pause, 停止键Stop, 复位键Reset;

2.       4位数码管显示分(两位)(两位);

3.       按启动键启动从60分开始倒计时, 按暂停键暂停,显示保持原来计时时间, 再次按启动键继续计时, 按停止键停止计时, 复位键复位, 到零停止计时.

4.       按停止键后, 可按中间的4个键, 分别对应分的十位(2), 个位(4), 和秒的十位(5), 个位(9), 按动一下, 相应的位增1, 并保证时间的正确值, 再按一次停止键, 保存设置值, 按其它键则放弃设置时间值, 恢复原来的时间.

 

电路图:


计时器工作模式:

编码(54H单元)

当前工作模式

00H

Reset

01H

Start

02H

Pause

03H

Stop


主程序流程:

ContractedBlock.gif ExpandedBlockStart.gif 主程序代码段
主程序代码段:
ORG 0000H
            LJMP MAIN
            ORG 000BH
            LJMP TIMER0
            ORG 1000H
MAIN:        ACALL INIT    
;初始化定时器
            SETB EA        ;开总中断
            SETB ET0        ;开定时器0中断
            MOV A, #03H    ;设置8155的工作模式, PA, PB输出, PC输入.
            MOV DPTR, #7F00H            
            MOVX @DPTR
, A
BEGIN:        ACALL DIS
            ACALL CLEAR
            ACALL CCSCAN
            JNZ INK1
            AJMP BEGIN
INK1:        ACALL DIS
            ACALL CLEAR
            ACALL CCSCAN
            JNZ INK2
            AJMP BEGIN
INK2:        MOV R2
, #7FH        ;从最左边列开始扫描
            MOV R4, #00H
COLUM:        MOV DPTR
, #7F02H
            MOV A
, R2
            MOVX @DPTR
, A
            INC DPTR
            MOVX A
, @DPTR
            JB ACC
.2, LONE
            MOV A
, #00H
            AJMP KCODE
LONE:        JB ACC
.1, NEXT
            MOV A
, #04H
KCODE:        ADD A
, R4
            ACALL PUTBUF
KON:        ACALL DIS
            ACALL CLEAR
            ACALL CCSCAN
            JNZ KON
NEXT:        INC R4
            MOV A
, R2
            JNB ACC
.4, KERR
            RR A
            MOV R2
, A
            AJMP COLUM
KERR:        AJMP BEGIN
CCSCAN:        MOV DPTR
, #7F02H
            MOV A
, #00H
            MOVX @DPTR
, A
            INC DPTR
            MOVX A
, @DPTR
            CPL A
            ANL A
, #03H
            RET
CLEAR:        MOV DPTR
, #7F01H
            MOV A
, #00H
            MOVX @DPTR
, A
            RET
INIT:            MOV 53H
, #06H    ;分十位
            MOV 52H, #00H   ;分个位        
            MOV 51H, #00H    ;秒十位
            MOV 50H, #00H    ;秒个位
            MOV 54H, #00H    ;存放当前工作模式, 00:Reset, 01 Start, 02 Pause, 03 Stop
            MOV 55H, #0AH    ;定时计数用, 定时器每次中断0.1s, 计数10次, 定时1s
            CLR TR0
            MOV TMOD
, 01H    ;定时器工作在方式1, 16位定时器
            MOV TH0, #3CH
            MOV TL0
, #0B0H
            RET




ContractedBlock.gif ExpandedBlockStart.gif 显示子函数
DIS:            PUSH ACC
            PUSH 00H
            PUSH 03H
            MOV A
, #03H
            MOV DPTR
, #7F00H
            MOVX @DPTR
, A
            MOV R0
, #50H
            MOV R3
, #0EFH
            MOV A
, 54H
            CJNE A
, #03H, DIS0
            MOV R0
, #60H
DIS0:        MOV A
, R3
AGAIN:        MOV DPTR
, #7F02H
            MOVX @DPTR
, A
            MOV A
, @R0
            MOV DTPR
, DATAS
            MOVC A
, @A+DPTR
            MOV DPTR
, #7F01H
            MOVX @DPTR
, A
            ACALL DL1MS
            INC R0
            MOV A
, R3
            JNB ACC
.0, OUT
            RL A            
            MOV R3
, A
            AJMP AGAIN
OUT:            POP 03H
            POP 00H
            POP ACC
            RET
DATAS:    DB 03FH
, 06H, 05BH, 04FH, 066H, 06DH, 07DH
DB 07H
, 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H
DL1MS:        MOV R7
, #01H
DL0:            MOV R6
, #0FFH
DL1:            DJNZ R6
, DL1
            DJNZ R7
, DL0
            RET




ContractedBlock.gif ExpandedBlockStart.gif 按键功能
PUTBUF:            MOV R1, A
                JNZ CHKSTART
                ACALL RESETFUNC
                SJMP GOBACK
CHKSTART:        CJNE R1
, #03H, CHKPAUSE
                ACALL STARTFUNC
                SJMP GOBACK
CHKPAUSE:        CJNE R1
, #04H, CHKSTOP
                ACALL PAUSEFUNC
                SJMP GOBACK
CHKSTOP:        CJNE R1
, #07H, CHKOTHER
                ACALL STOPFUNC
                SJMP GOBACK
CHKOTHER:        ACALL OTHERFUNC
GOBACK:            RET



ContractedBlock.gif ExpandedBlockStart.gif 重置代码段
RESETFUNC:        MOV R0, 54H
                CJNE R0
, #00H, RESET0
                RET
                CJNE R0
, #01H, RESET0
                RET
RESET0:             ACALL INIT
                MOV 54H
, #00H
RET




ContractedBlock.gif ExpandedBlockStart.gif 开始功能代码段
STARTFUNC:        MOV R0, 54H
                CJNE R0
, #01H, START0
                RET
START0:            MOV 54H
, #00H
                SETB TR0
RET



ContractedBlock.gif ExpandedBlockStart.gif 暂停功能代码段
PAUSEFUNC:        MOV R0, 54H
                CJNE R0
, #01H, PAUSE0
                CLR TR0
                MOV 54H
, #02H
                SJMP PAUSE1
PAUSE0:            CJNE R0
, #02H, PAUSE1
                SETB TR0
                MOV 54H
, #01H
PAUSE1:            RET



ContractedBlock.gif ExpandedBlockStart.gif 停止功能代码段
STOPFUNC:        MOV R0, 54H
                CJNE R0
, #03H, STOP0
                MOV 54H
, #02H
                MOV R0
, #50H
                MOV R1
, #60H
STOP1:            MOV A
, @R1
                MOV @R0
, A
                INC R0
                INC R1
                CJNE R0
, #54H, STOP1
                RET
STOP0:            CLR TR0
                MOV 54H
, #03H
                MOV R0
, #60H
                MOV R1
, #50H
STOP2:            MOV A
, @R1
                MOV @R0
, A
                INC R0
                INC R1
                CJNE R1
, #54H, STOP2
                RET



ContractedBlock.gif ExpandedBlockStart.gif 其他功能代码段
OTHERFUNC:        MOV R0, 54H
                CJNE R0
, #03H, OTHER0
                CJNE R1
, #01H, OTHER1
                MOV R0
, #63H
                INC @R0
                CJNE @R0
, #06H, OTHER0
                MOV @R0
, #00H
                SJMP OTHER0
OTHER1:            CJNE R1
, #02H, OTHER2
                MOV R0
, #62H
                INC @R0
                CJNE @R0
, #0AH, OTHER0
                MOV @R0
, #00H
                SJMP OTHER0
OTHER2:            CJNE R1
, #05H, OTHER3
                MOV R0
, #61H
                INC @R0
                CJNE @R0
, #06H, OTHER0
                MOV @R0
, #00H
                SJMP OTHER0
OTHER3:            CJNE R1
, #06H, OTHER0
                MOV R0
, #60H
                INC @R0
                CJNE @R0
, #0AH, OTHER0
                MOV @R0
, #00H
                SJMP OTHER0
OTHER0:            RET



ContractedBlock.gif ExpandedBlockStart.gif 中断定时代码段
;使用定时器0, 工作模式1, 定时0.1s, 晶振频率为6MHz
;
定时器初值 X = 65536 – 50000 = 15536 = 3CB0H

TIMER0:        MOV TH0
, #3CH
            MOV TL0
, #0B0H
            DJNZ 55H
, EXIT0        ;判断是否已定时中断10, 即1秒
            MOV 55H, #0AH
            MOV R0
, #50H
GOON0:        DEC @R0
            CJNE @R0
, #0FFH, EXIT0
            MOV @R0
, #09H
            INC R0
            DEC @R0
            CJNE @R0
, #0FFH, EXIT0
MOV @R0
, #05H
            INC R0
            DEC @R0
CJNE @R0
, #0FFH, EXIT0
MOV @R0
, #09H
            INC R0
            DEC @R0
            CJNE @R0
, #0FFH, EXIT0        ; 倒计时结束, 停止计时, 显示全”0”
            ACALL INIT
            MOV 53H
, #00H
            MOV 54H
, #03H
EXIT0:        RET


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值