×
单片机 > 单片机程序设计 > 详情

基于51单片机秒表的程序设计

发布时间:2020-06-08 发布时间:
|

1.设计目的:

(1)利用单片机定时器中断和定时器计数方式实现秒、分定时。

(2)通过LED显示程序的调整,熟悉8155与8051,8155与LED的接口技术,熟悉LED动态显示的控制过程。

(3)通过键盘程序的调整,熟悉8155与矩阵式键盘的接口技术,熟悉键盘扫描原理。

(4)通过阅读和调试简易秒表整体程序,学会如何编制含LED动态显示、键盘扫描和定时器中断等多种功能的综合程序,初步体会大型程序的编制和调试技巧。

2.  设计步骤与要求

(1)要求:以8位LED右边2位显示秒,左边6位显示0,实现秒表计时显示。以4×4矩阵键盘的KE0、KE1、KE2等3键分别实现启动、停止、清零等功能。

(2)方法:用单片机定时器T0中断方式,实现1秒定时;利用单片机定时器1方式3计数,实现60秒计数。用动态显示方式实现秒表计时显示,用键盘扫描方式取得KE0、KE1、KE2的键值,用键盘处理程序实现秒表的启动、停止、清零等功能。

(3)软件设计:软件整体设计思路是以键盘扫描和键盘处理作为主程序,LED动态显示作为子程序。二者间的联系是:主程序查询有无按键,无按键时,调用二次LED动态显示子程序(约延时8ms)后再回到按键查询状态,不断循环;有按键时,LED动态显示子程序作为按键防抖延时被连续调用二次(约延时16ms),待按键处理程序执行完后,再回到按键查询状态,同时兼顾了按键扫描取值的准确性和LED动态显示的稳定性。秒定时采用定时器T0中断方式进行,60秒计数由定时器1采用方式3完成,中断及计数的开启与关闭受控于按键处理程序。由上述设计思路可设计出软件流程图如图1.1所示。

(5)程序编制:编程时置KE0键为“启动”,置KE1键为“停止”,置KE2键为“清零”,因按键较少,在处理按键值时未采用散转指令“JMP”,而是采用条件转移指令“CJNE”,每条指令后紧跟着一条无条件跳转指令“AJMP”,转至相应的按键处理程序,如不是上述3个按键值则跳回按键查询状态。8位LED显示的数据由显示缓冲区30H~37H单元中的数据决定,顺序是从左至右,动态显示时,每位显示持续时间为1ms,1ms延时由软件实现,8位显示约耗时8ms。主程序、按键查询子程序采用第0组工作寄存器,显示子程序采用第1组工作寄存器。1秒定时采用定时器T0方式1中断,每50ms中断一次,用21H做50 ms计数单元,每20次为一个循环,计满20次,60秒计数单元(20H)计数1次。60秒计数采用定时器T1方式2计数,计数脉冲采用软件置位、复位P3.5口的方法实现,用20H单元做60秒计数单元,如定时器T1溢出,则20H单元被清零,20H单元的数据采用十进制计数,该数据被拆成个位和十位两个数据后分别送至显示缓冲区的30H、31H单元。

 

按照上述思路可编制源程序如下:

                  ORG                 0000H

        AJMP       MAIN

        ORG        000BH

        AJMP       CONT [page]

;主程序

;――――――――――初始化程序―――――――――――

MAIN:        MOV       TMOD,#61H           ;置T0方式1定时,T1方式2计数

                       MOV       TH0,#3CH                    ;T0置初值

                       MOV       TL0,#0B0H

                       MOV       TH1,#0C4H                  ;T1置初值

                       MOV       TL1,#0C4H               

                       MOV       DPTR,#4400H           ;8155控制口地址送DPTR

                       MOV       A,#43H                       ;设置8155工作方式字

                       MOVX       @DPTR,A               ;设置PA、PB口输出,PC口输入

                       MOV       20H,#00H                    ;60秒计数单元置初值

                       MOV       21H,#14H                   ;50ms计数单元置初值

                       MOV       SP,#3FH                     ;堆栈指针置初值

                       MOV       R2,#08H     &n, bsp;               ;LED待显示位数送R2

                       MOV       R0,#30H                      ;显示缓冲区首址送R0

STAR:        MOV       @R0,#00H                  ;显示缓冲区清零

          INC        R0

                       DJNZ       R2,STAR

                       CLR        A                                    ;累加器清零

;―――――――――――键盘查询程序――――――――――

  KEY:           ACALL     KS          ;调按键查询子程序判是否有键按下                              

    JNZ       K1                                    ;有键按下转移

                       ACALL       DISP                           ;无键按下,调显示子程序延时

                       AJMP       KEY                              ;继续查询按键

;―――――――――――键盘扫描程序――――――――――

K1:            ACALL     DISP                            ;键盘去抖延时

          ACALL   DISP

                       ACALL   KS                                ;再次判别是否有键按下

                       JNZ        K2                                 ;有键按下转移

    AJMP       KEY                         ;无按键,误读,继续查询按键

 K2:              MOV       R3,#0FEH                  ;首列扫描字送R3

                      MOV       R4,#00H                     ;首列号送R4

K3:            MOV       DPTR,#4401H          ;PA口地址送DPTR,开始列扫描

                       MOV       A,R3                        

                       MOVX       @DPTR,A                ;列扫描字送PA口

                       INC        DPTR                            ;指向PC口

          INC        DPTR

                       MOVX       A,@DPTR               ;读取行扫描值

                       JB           ACC.0,L1                     ;第0行无键按下,转查第1行

                       MOV       A,#00H                      ;第0行有键按下,行首键号送A

                       AJMP       LK                                ;转求键号

L1:            JB           ACC.1,L2                     ;第1行无键按下,转查第2行

                       MOV       A,#08H                      ;第1行有键按下,行首键号送A

                       AJMP       LK                                ;转求键号

 L2:             JB           ACC.2,L3                     ;第2行无键按下,转查第3行

                       MOV       A,#10H                      ;第2行有键按下,行首键号送A

                       AJMP       LK                                ;转求键号

L3:               JB           ACC.3,NEXT             ;第3行无键按下,转查下一列

                       MOV       A,#18H                       ;第3行有键按下,行首键号送A

          AJMP       LK

LK:            ADD       A,R4                         ;形成键码送A

                       PUSH       ACC                            ;键码入栈保护

 K4:            ACALL   DISP

                       ACALL       KS                           ;等待键释放

                       JNZ        K4                                ;未释放,等待

                       POP        ACC                             ;键释放,弹栈送A

                       AJMP       PR                               ;转键盘处理程序

NEXT:        INC        R4                                 ;修改列号

                       MOV       A,R3

                       JNB        ACC.3,KEY               ;4列扫描完返回按键查询状态

                       RL          A                                   ;未扫描完,改为下列扫描字

                       MOV       R3,A               &, nbsp;         ;扫描字暂存R3

                       AJMP       K3                               ;转列扫描程序

;―――――――――――键盘处理程序―――――――――――――――

PR:           CJNE       A,#00H,PR01         ;不是KE0键码,转KE1键

                      AJMP       KE0                             ;转KE0键处理程序

PR01:        CJNE       A,#01H,PR02         ;不是KE1键码,转KE2键

                      AJMP       KE1                             ;转KE1键处理程序

PR02:         CJNE       A,#02H,PR03        ;不是KE2键码,返回按键查询

                       AJMP       KE2                             ;转KE2键处理程序

PR03:         AJMP       KEY

KE0:           SETB       TR0                             ;启动定时器T0

                       SETB       TR1                             ;启动定时器T1

                       SETB       ET0                             ;允许定时器T0中断

                       SETB       EA                               ;开中断

                       AJMP       KEY                       ;返回键盘查询状态 [page]

KE1:           CLR        EA                               ;关中断

                       CLR        ET0                             ;禁止定时器T0中断

                       CLR        TR1                             ;关定时器T1

                       CLR        TR0                             ;关定时器T0

          AJMP       KEY

KE2:           CLR        EA                                 ;关中断

                       AJMP       MAIN                          ;返回主程序进行初始化

;――――――――――按键查询子程序――――――――――――――

 KS:            MOV       DPTR,#4401H           ;置8155PA口地址

                        MOV       A,#00H                     

                       MOVX       @DPTR,A                ;全扫描字#00H送PA口

                       INC        DPTR                            ;指向PC口

          INC        DPTR

                       MOVX       A,@DPTR            ;读入PC口状态

                       CPL        A                                    ;变正逻辑,高电平表示有键按下

                       ANL       A,#0FH                  ;屏蔽高4位

                       RET                                             ;返回,A≠0表示有键按下

;―――――――――LED动态显示子程序―――――――――――――

DISP:          PUSH       ACC                            ;A入栈保护

                       SETB       RS0                              ;保护第0组工作寄存器,启用第1组工作寄存器                      

                      MOV    R2,#08H         ;LED待显示位数送R2

                       MOV       R1,#00H                    ;设定显示时间

                       MOV       R3,#7FH                    ;选中最右端LED

                       MOV       R0,#30H                    ;显示缓冲区首址送R0

                       MOV       A,@R0                      ;秒显示个位送A

DISP1:        MOV       DPTR,#TAB            ;指向字形表首址

                       MOVC       A,@A+DPTR        ;查表取得字形码

                       MOV       DPTR,#4402H          ;指向8155PB口(段码口)

                       MOVX       @DPTR,A             ;字形码送PB口

                       MOV       A,R3                         ;取位选字

                       MOV       DPTR,#4401H          ;指向8155PA口(位选口)

                       MOVX       @DPTR,A             ;位码送PA口

                       DJNZ       R1,$                          ;延时0.5ms

                       DJNZ       R1,$                          ;延时0.5ms

                       RR          A                                   ;位选字移位

                       MOV       R3,A                         ;移位后的位选字送R3

                       INC        R0                                 ;指向下一位缓冲区地址

                       MOV       A,@R0                      ;缓冲区数据送A

    DJNZ       R2,DISP1                   ;未扫描完,继续循环

                       CLR        RS0                               ;恢复第0组工作寄存器

                       POP        ACC                              ;A弹栈,恢复现场

          RET

TAB:          DB          3FH,06H,5BH,4FH,66H              ;共阴极LED字形表

                       DB          6DH,7DH,07H,7FH,6FH

;――――――――――定时器中断服务程序―――――――――――――

CONT:       PUSH    ACC                               ;保护现场

                       MOV     TH0,#3CH               ;定时器T1重置初值

                       MOV     TL0,#0B0H                        

                       MOV     A,20H                      ;秒计数器送A

          AJMP    CONT1                       

REN:           AJMP    REN1

CONT1:      DJNZ       21H,REN                     ;1秒定时未到,中断返回

                       MOV       21H,#14H                     ;重置50ms计数初值

                       CLR        P3.5                                ;软件产生定时器T1计数脉冲

          NOP

          NOP

          SETB       P3.5

                       INC        A                                    ;1秒计数值加1

                       DA         A                                    ;换算为10进制计数

                       JBC        TF1,CONT2                ;60秒到,转清零

 CONT3:     MOV       20H,A                        ;计数值送60秒计数单元20H

                       ANL       A,#0FH                  ;屏蔽高4位

                       MOV       30H,A                        ;秒表个位待显示数据送显示缓冲区

                       MOV       A,20H

                       SWAP     A                                   ;60秒计数单元高、低4位数据互换

                       ANL       A,#0FH                  ;屏蔽高4位

                       MOV       31H,A                        ;秒表十位待显示数据送显示缓冲区

          AJMP       REN1

 CONT2:     MOV       A,#00H                     

          AJMP       CONT3

REN1:         POP        ACC                            ;恢复现场

                       RET                                           ;中断返回

          END                           

3. 总结与分析

    (1)实验采用七段码LED设计(数码管),显示直观;采用定时器中断,计时更准确;功能齐全,可随时启动、停止、清零,后者智能化程度更高。

(2)设计、调试大型程序时,需先根据要求划分模块,优化结构;再根据各模块特点确定何为主程序,何为子程序,何为中断服务程序,相互间如何调用;再根据各模块性质和功能将各模块细化,设计出程序流程图;最后才根据各模块流程图编制具体程序。调试时应先调主程序,实现最基本最主要的功能,在此基础上再将各模块功能往主程序上堆砌,直至各模块联调、统调,实现全部功能。本例子将整个程序划分为键盘程序,动态显示程序,秒计时程序三大模块,根据各自的特点确定键盘程序为主程序,动态显示程序为子程序,秒计时程序为定时器中断服务程序。主程序又细分为初始化程序,键盘查询程序,键盘扫描程序,键盘处理程序四大部分。三大模块之间的关系是:键盘程序在无键按下时,不断调用动态显示子程序;在有键按下时,先调用动态显示子程序消抖,再进入键盘处理程序,控制中断服务程序的运行;处理完毕后,再不断调用动态显示子程序。经上述处理后,三大模块运行协调一致,既保持了动态显示的稳定性,又保持了键盘的可靠性,还保持了秒计时的准确性,较好地实现了全部功能。

(3)本例子只用到8位LED显示中的两位,只用到4×4键盘16个按键中的3个,因此,其功能还有较大的扩展空间。只要将上述程序稍加改动即可实现秒、分、时、日显示,并可作全方位修改的实时时钟。如增加LED显示位数或将显示改为LCD显示模块,可实现年、月、周、日、时、分、秒显示。

关键字:51单片机  秒表  定时器

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ARM 汇编的必知必会