报告论文:单片机电子时钟报告

一.设计目的:

1、进一步掌握8255电路的编程方法。

2、进一步掌握定时器的使用和编程方法。

二.设计内容:

利用MPLAB微机实验系统上提供的8255,键盘电路,数码显示电路,设计一个电子时钟,要求按24小时制显示,能够修改初始时间值。

三.设备及连线:

本实验使用MPLAB微机试验系统

 

 查看更多精彩图片

 

四.程序说明:

本程序采用模块化编程,能够实现输入时间数据检测,当输入错误格式及时间数据时,自动清空时间为初始0值。能够自由启动,停止和重设时间初值。秒针进位由定时器控制。定时器工作方式设为1

电子时钟格式及功能如下:

XX XX XX  由左向右以此显示:时,分,秒

1C键:清除,显示时间00 00 00

2B键:启动电子时钟

3F键:停止电子时钟,并可设置时间

当输入时间数据错误,立即清零,显示00 00 00

例如,当输入 27 34 23 ―― 小时数据错误!

             13 78 43 ―― 分钟数据错误!

             03 23 a4 ―― 秒数据错误!

五.程序框图:

   查看更多精彩图片

 

六.程序代码:

comport equ 9003h                   8255命令字地址9003h

aport equ 9000h                      8255 PA口输出显示字符段码地址

bport equ 9001h                      8255 PB口输出显示字符位码地址

cport equ 9002h                      8255 PC口输入读取键盘数据

databuf equ 50h                      ;设置存放时间数据首地址

mov r6,#5

mov r5,#8                          ;定时器循环次数

mov tmod,#10h                      ;设置定时器1 方式1

mov th1,#3ch                        ;设置定时器初值高位

mov tl1,#0b0h                       ;设置定时器初值低位

start:

      mov sp,#30h                  ;设置SP值为30h

      mov dptr,#comport            

      mov a,#10001000b

      movx @dptr,a                 ;初始化8255

      mov r0,#databuf

      mov r1,#6                   

      clr a

initloop:                           ;清空时间数据为0(循环6次)

      mov @r0,a

      inc r0

      djnz r1,initloop

hf:   mov r4,#50h                  ;备份存放时间数据首地址

                                  ;初始化完毕

mainloop:                          ;主程序运行

      call scankey                  ;调用键盘扫描子程序

jc ccc                       ;判断进位标志是否为1(即有无按键输入)

      sjmp qwe                    ;不为1(有按键输入),跳转键值输入程序段

ccc:   ljmp time                    ;为1(无按键输入),跳转到定时程序

qwe:  push acc                     ;数据压栈,保存按键值

      mov a,r4                     ;取出当前时间数据存放位置

      mov r0,a                    

      pop acc                      ;数据出栈,按键值保存在a

      cjne a,#0ch,nor                ;判断按键是否为c键,否则跳转继续判断

      ajmp start                    ;按键值是C键(清零功能),跳转程序开始处

nor:  cjne a,#0bh,nor2                ;判断按键是否为b键,否则跳转继续判断

      setb tr1                      ;按键值是b键(启动时钟功能),启动定时器

      mov r0,#databuf               ;取出第一个时间数据

      mov a,@r0                   ;赋值给a

      jmp nor3                     ;跳转到赋值时间数据程序段

nor2: cjne a,#0fh,nor3                ;判断按键是否为F键,否则跳转到赋值时间程序段

      clr tr1                       ;按键值是F键(设置时间功能),停止定时器

      jmp dspbuf                   ;跳转到时间显示子程序

          

nor3:      

      mov @r0,a                  ;给当前数据存放地址内赋时间数据

      call vali                     ;调用数据合法性判断子程序

      inc r4                       r4值+1,即当前存放数据地址后移一位

      mov a,r4                   

      subb a,#56h               ;判断r4是否为55h,即数据存放地址是否为最后一位

      jz hf                 ;是转初始化r4程序段,即改变当前数据存放地址为第一位

time:                            ;定时器子程序

       jbc tf1,agai                tf1是否溢出,是转

       jmp dspbuf                ;否转显示子程序

agai:  djnz r5,time                 ;判断定时器是否循环8次(1秒时间)

       mov r5,#8                 ;是恢复定时器初始值为8

       jmp count                 ;跳转至秒针进位程序

dspbuf:                          ;调用显示子程序

      call dspled

      jmp mainloop               ;回转到主程序开始处

 

scankey:                         ;扫描键盘子程序

      mov dptr,#cport            

      clr a

      movx @dptr,a

      movx a,@dptr

      orl a,#0fh

      inc a

      jnz skloop

      call dspled

      ljmp exit

skloop:                          ;查键闭合否

      call dspled

      mov dptr,#cport

      clr a

      movx @dptr,a

      movx a,@dptr

      orl a,#0fh

      inc a

      jz exit

      mov r0,#0

      mov r1,#4

      mov r2,#0feh

skloop1:                          ;软消除按键抖动

      mov a,r2

      movx @dptr,a

      rl a

      mov r2,a

      movx a,@dptr

      orl a,#0fh

      cjne a,#0ffh,keyval

      mov a,#4

      add a,r0

      mov r0,a

      djnz r1,skloop1

      sjmp exit

keyval:

      swap a

      mov r1,#4

skloop2:                               

      rrc a                            

      jnc readval                        ;有键按下,跳转读键值程序段

      inc r0

skloop3:djnz r1,skloop2

exit:   setb c                           ;无键按下,退出

      sjmp quit

readval:                                ;读键值

      mov dptr,#tab

      mov a,r0

      movc a,@a+dptr                   ;查表获取相应按键值

      push acc                          ;键值压栈

wait:  call dspled                       

      mov dptr,#cport

      clr a

      movx @dptr,a

      movx a,@dptr

      orl a,#0fh

      inc a

      jnz wait

      clr c                            ;清空进位标志,初始化8255输入端

      pop acc                          ;键值出栈

quit:   ret

tab:  db 0,1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh

 

count:                                ;秒针进位子程序

mov th1,#3ch                

      mov tl1,#0b0h

      mov r0,#databuf+5                ;取个位秒数值

      mov a,@r0

      cjne a,#09h,mc                   ;判断个位秒值是否为9,否转

      clr a                            ;是,个位秒值清零

      mov @r0,a

      jmp jwm                       ;转判断十位秒值

mc:   inc a                          ;个秒值+1

      mov @r0,a

      jmp dspbuf                     ;显示数值

jwm:  mov r0,#databuf+4              

      mov a,@r0

      cjne a,#05h,mmc                 ;判断十秒位是否为5,否则转

      clr a                          

      mov @r0,a                      ;是,十秒位清零

      jmp jwf                         ;转判断个位分值

mmc:  inc a

      mov @r0,a                      ;否,十秒位数值+1

      jmp dspbuf                      ;显示数值

jwf:  mov r0,#databuf+3                 ;判断个位分值

      mov a,@r0

      cjne a,#09h,fc                     ;判断个位分值是否为9,否则转

      clr a                           

      mov @r0,a                       ;是,个位分值清零

      jmp jwsf                         ;转判断十位分值

fc:    inc a                           

      mov @r0,a                       ;否,个位分值+1

      jmp dspbuf                       ;显示数值

jwsf: mov r0,#databuf+2                  ;判断十位分值

      mov a,@r0

      cjne a,#05h,fcc                   ;判断十位分值是否为5,否则转

      clr a                        

      mov @r0,a                      ;是,十位分值清零

      jmp jws                         ;转判断个位小时

fcc:  inc a                             

      mov @r0,a                       ;否,十位分值+1

      jmp dspbuf                       ;显示数值

jws:                                  ;判断个位小时数值

mov r0,#databuf                  

      mov a,@r0                      ;先取十位小时数值

      cjne a,#02h,sss                   ;判断十位小时数值是否为2,否则转

      mov r0,#databuf+1                ;是,取个位小时数值

      mov a,@r0                     

      cjne a,#03h,xxs                   ;判断个位小时数值是否为3,否则转

      clr a

      mov @r0,a                       ;是,个位小时数值清零

      jmp jwxs                         ;判断十位小时数值

xxs:   inc a

      mov @r0,a                       ;否,个位小时数值+1

      jmp dspbuf                       ;显示数值

sss:  mov r0,#databuf+1               ;取个位小时数值

      mov a,@r0

      cjne a,#09h,xss                 ;判断个位小时数值是否为9,否则转

      clr a

      mov @r0,a                    ;是,个位小时清零

      jmp jwxxs                     ;转十位小时+1

xss:   inc a

      mov @r0,a                  ;否,各位小时数值+1

      jmp dspbuf                  ;显示数值

jwxxs:mov r0,#databuf            ;十位小时直接+1

      mov a,@r0

      inc a

      mov @r0,a              

      jmp dspbuf              ;显示数值           

jwxs: mov r0,#databuf             ;十位小时直接清零

      mov a,@r0

      clr a

      mov @r0,a

      jmp dspbuf                ;显示数值

dspled:                                  ;时间显示子程序

      mov r0,#databuf                   ;赋r0为存放第一个显示数值的地址

      mov r1,#6                        ;赋r1为显示次数

      mov r7,#20h                   ;赋显示位码给r720h6位数码管左边第一位)

dsploop:

      mov a,@r0                    ;取第一个显示数据(即十位小时数值)

      mov dptr,#ledcode         

      movc a,@a+dptr                ;查表得显示数据得相应段码

      mov dptr,#aport

      movx @dptr,a                  ;赋段码值给8255 PA端口

      mov a,r7

      mov dptr,#bport

      movx @dptr,a                   ;赋位码值给8255PB端口

      mov b,#1

      call delay                       ;调用显示延迟子程序

      inc r0                          ;指向存放当前显示数值得地址后一位

      djnz r1,shift                     ;依次循环显示存放的时间数据(共6次)

      ret

shift:  mov a,r7                       

       rr a                           ;右移当前段码值,即当前显示数码管右移一位

       mov r7,a

       sjmp dsploop                   ;继续显示数值

delay:  mov r2,#3

       mov r3,#0

dloop: djnz r3,dloop

       djnz r2,dloop

       djnz b,dloop

      ret

ledcode:

      db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,77h,7ch,39h,5eh,79h,71h

    

vali:                                    ;判断数据合法性子程序

mov r0,#databuf

       mov a,@r0                       ;取十位小时数值

       cjne a,#0,aa                       ;判断十位小时数值是否为0,否转继续判断

       jmp aga2                         ;是,转十位分数值合法性判断

aa:    cjne a,#1,bb                        ;十位小时数值是否为1,否转继续判断

       jmp aga2                         ;是,转十位分数值合法性判断

bb:    cjne a,#2,wrong                    ;十位小时数值是否为2,否转出错程序段

       jmp aga                          ;是,转个位小时数值合法性判断

wrong: mov r4,#4fh                       ;出错程序段

       mov r0,#databuf

       mov r1,#6

       clr a

initloop3:                               ;初始化显示数值全部为0

      mov @r0,a

      inc r0

      djnz r1,initloop3

ok:     ret                            

aga:    mov r0,#databuf+1                ;取个位小时数值

        mov a,@r0

        cjne a,#0,cc                     ;个位小时数值是否为0,否转继续判断

        jmp ag                         ;是,转十位分数值判断

cc:     cjne a,#1,dd                      ;个位小时数值是否为1

        jmp ag

dd:     cjne a,#2,ee                      ;个位小时数值是否为2

        jmp ag

ee:     cjne a,#3,wrong                 ;个位小时数值是否为3,否转出错

        jmp ag                        ;是,转十位分数值判断

ag:     mov r0,#databuf+2               ;先取十位分数值进行合法性判断

twice:   mov a,@r0

        cjne a,r6,taga                    ;依次判断十位分数值是否为54321

pd:     cjne r0,#54h,addd               ;当前判断位是否为十位秒?无继续进行判断

        jmp ok

addd:    inc r0

        inc r0                        ;地址后移,取十位秒数值进行合法性判断

        mov r6,#5

        jmp twice

taga:    djnz r6,twice

        cjne a,r6,wrong              ;数值是否为0,否则出错

        jmp pd

     

[hide]需要回复才[/hide]

转载于:https://www.cnblogs.com/Gemgin/archive/2013/06/13/3136612.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值