查看: 608|回复: 0
打印 上一主题 下一主题

带任务调度的2051+18B20+HT1380+LS247电子钟

[复制链接]
跳转到指定楼层
沙发
发表于 2016-4-27 21:23:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

(原文件名:照片-0005.jpg)


(原文件名:照片-0006.jpg)


(原文件名:照片-0007.jpg)


(原文件名:照片-0008.jpg)

点击此处下载 ourdev_542757.rar(文件大小:36K) (原文件名:电子钟百分之98成功备份.rar)
图中的旧电脑是学习并口编程用的.呵呵,不是我的主力电脑.代码压缩包里有整个工程.这里的是方便大家看的
;修改2010年3月2日13时6分58秒
;2: 增加实时时钟HT1380
;3: 删除掉电检测,删除闹钟,删除2051时钟,
;4: 画的PCB和原来的程序定义不一致,.晕.重新定义
;2051+74ls247电子钟         带电池和省电模式进行比较精确的时间显示   
;
         ; ledbit   bit 02h     ;LED灯闪还是不闪        ,为0就闪,为1任何情况下都不闪
                 
                  ;45h          31h                                36
                  ;44h          30h                                35
                  ;43h                    2fh                                34
                  ;42h                   2eh                                33
              ;41h          2dh
                  ;40h                   2ch                        
         ;MOV 40H,#08 ;个位寄存器初值
        ;MOV 41H,#00 ;十位寄存器初值
        ;MOV 42H,#00 ;百位寄存器初值
        ;MOV 43H,#00 ;千位寄存器初值
        ;MOV 44H,#00 ;万位寄存器初值
        ;MOV 45H,#00 ;十万位寄存器初值
;系统用内存定义
arlmH        equ  39h
taskidbit  equ  36h   ;任务ID标志位
daydata    equ    35h    ;天数
tempLOK   equ   34h          ;转换好的温度BCD数据
tempHOK   equ   33h
saveinit   equ  32h        ;临时变量,用的是动态变量区
savewait   equ  31h
savesp     equ  30h    ;临时变量保护
oswaitflag  bit  2fh.0   ;进入OSWAIT子程序保护区标志
ostaskswflag bit  2fh.1          ;进入任务切换区标志
osidltask    bit  2fh.2                 ;进入最低优先级任务标志
osinittaskflag bit  2fh.3        ; osswflag.7 ; 中断任务保护区
htreadbit        bit  2fh.4           ;读HT1380标志,一秒一读,1为读
;setarlm                bit  2fh.5         ;进入闹钟设置时的标志,1为进入了
drive           bit  2fh.6;18B20存在标志
t2t        bit  2fh.7;是时间模式下还是温度模式下,为1是温度模式只下边的LED亮并且不闪,为0是时间模式2个LED一起闪
ms1to41           bit  2eh.0
ms1to42           bit  2eh.1

taskidnum  equ  2dh   ;任务ID数
osreadybit  equ 2ch   ;任务准备好标志,准备好为1,
osinitbit  equ  2bh   ;任务被中断位表,被中断了为1
oswaitbit  equ  2ah   ;任务被挂起位表,被挂起了为1
s5                equ  29h                ;5秒定时
displaydataH equ  28h         ;数据管显示数据的高位,BCD压缩码
displaydataL equ  27h    ;数据管显示数据的低位,BCD压缩码
timeH       equ  26h     ;时间RAM
timeL       equ  25h     ;时间RAM
timeS       equ  24h            ;秒单元
TEMPER_L    equ  23h     ;温度
TEMPER_H    equ  22h                                                                                                     ;R6温度时间显示计数        ,4秒一换
oswaitram  equ  09h   ;挂起任务的结构首址,8*3=24,09H到21H
                                                                                                                                                     
maxtask    DATA    2             ;最大任务ID,0也是一个任务
H5MS       DATA    0B2H
L5MS       DATA     05h
sdata      bit p1.3 ;HT时序IO
srst     bit p3.5 ;HT数据IO                         ;
sclk     bit p1.2 ;HT1380复位IO
DQ            bit p3.4 ;18B20
leddianh  bit p1.0  ;LED上秒点,高电平点亮
leddianL  bit p1.1  ;LED下秒点  高电平点亮

key       bit p3.7  ;KEY

;********主程序都从OOH开始

ORG 00H
JMP Main       ;引导程序从Main开始执行
org 0bh
ljmp osinitpro
;******下面是主程序执行体
ORG 030H
Main:  MOV SP,#3aH    ;初始化堆栈,系统欠底
       acall initial
            
                  mov taskidnum,#0       ;任务指针指向第0个任务        
                  mov taskidbit,#1               
                  mov osreadybit,#255
                  setb ea
                  setb et0                ;T0中断充许
             setb tr0                        ;T0定时器开始运行
                  
;用户代码写在这里
;//*****************************************//
keyscan:        setb key
                 jb key,ht1380
                 mov r3,#10        ;等待50MS
                 acall oswait
                 setb key
                 jb key,ht1380
               
       mov r0,#timeS ;写入的小时和分数据首址     写入时,分,秒数据
      mov @r0,#58h         ;58秒
      inc r0
       mov @r0,#59h         ;59分
      inc r0
       mov @r0,#6h          ;6点
      acall writehms
               mov r3,#63
                 acall oswait
                         mov r3,#63        ;等待700MS,防止键又被觛发
                acall oswait

                         mov r3,#63        ;等待700MS,防止键又被觛发
                acall oswait

ht1380:                jbc htreadbit,readtime
                 ljmp tasksw
readtime:        acall readhms
                 ljmp tasksw

                   ;千位显示
display:          clr p1.7 ;关闭个位,p3.3
                         mov a,displaydataH
                   anl a,#240        ;BCD压缩码的低四位清零
                  jz dis01                         ;千位为零不显示
                 ; anl 90h,#15           ;把P1端口的高4位清零了,低4不变
                swap a
                   anl 0b0h,#240                 ;p3口低4清0,高4不影响
                 orl 0b0h,a        ;BCD码的高4位是千位
                  
                   setb p1.4 ;打开千位 P3.0
dis01:           mov r3,#1        
           acall oswait  
                     ;百位显示
                  clr p1.4 ;p3.0
                   mov a,displaydataH
                 
                   anl a,#15        ;BCD压缩码的低四位清零
                  anl 0b0h,#240           ;把P1端口的高4位清零了,低4不变
                  orl 0b0h,a        ;合成
                  setb p1.5   3.1
                   mov r3,#1        
                   acall oswait
                  
                   ;十位显示
                  clr  p1.5 ;p3.1        
                   mov a,displaydataL
                   anl a,#240        ;BCD压缩码的低四位清零
                  swap a
                   anl 0b0h,#240           ;把P1端口的高4位清零了,低4不变
                  orl 0b0h,a        ;合成
                  setb p1.6  3.2
                   mov r3,#1        
                   acall oswait
                  
                   ;个位显示
                  clr p1.6  ; p3.2
                   mov a,displaydataL
         
                   anl a,#15        ;BCD压缩码的低四位清零
                  anl 0b0h,#240           ;把P1端口的高4位清零了,低4不变
                  orl 0b0h,a        ;合成
                  setb p1.7  3.3
                   mov r3,#1        
                   acall oswait
                   ajmp display
                  

; 读出转换后的温度值
;//*****************************************//
;  //       mov r3,#64          ;64光事件模式
;   //      acall oswait
GET_TEMPER:
         jnb t2t, GET_TEMPER_0
             CLR drive
         SETB    DQ            ;释放总线
        ACALL    INIT_1820    ; DS18B20初始化
        JNB    drive,GET_TEMPER_0        ; 若DS18B20不存在则返回
        MOV    A,#0CCH        ; 跳过ROM匹配
        ACALL    WRITE_1820
         MOV    A,#44H        ; 发出温度转换命令
        ACALL    WRITE_1820
        
             mov r3,#63                                ;延时63*5MS=315MS
         acall oswait
         mov r3,#63                                ;延时63*5MS=315MS*2=630ms
         acall oswait
                 mov r3,#20                        ;延时24*5MS=120MS  +630ms=750ms, 12位精度时要求的转换时间750MS
         acall oswait
                 CLR drive
         SETB    DQ            ;释放总线
        ACALL    INIT_1820    ; DS18B20初始化
        JNB    drive,GET_TEMPER_0        ; 若DS18B20不存在则返回
               
         ACALL    INIT_1820
         MOV    A,#0CCH        ; 跳过ROM匹配
        ACALL    WRITE_1820
         MOV    A,#0BEH        ; 发出读温度命令
        ACALL    WRITE_1820
         ACALL READ_TEMP        ; 将读出的温度数据保存到35H/36H
         acall TEMPER_COV
GET_TEMPER_0: ljmp tasksw                ;



oswait:   ;系统等待信号,延时子程序,               
                   setb oswaitflag                  ;设立进入OSWAIT子程序保护区标志        
           mov  b,#3                          ;计算OSWAITRAM数据地址换算
                  mov  a,taskidnum        
                   mul  ab
                   add   a,#oswaitram                  ;首址
                                          ;取得本任务OSWAITRAM数据结构地址
                  mov r0,a
           mov a,r3
                   mov @r0,a                                                ;从R3处取得第一字节数据
                  inc r0
                   pop   ACC                                           ;取得本任务断点PC指针,
                   mov   @r0,a
                   inc   r0
                   pop   ACC
                   mov   @r0,a
                   mov   a,taskidbit
                   orl        oswaitbit,a                                        ;设立本任务挂起标志
                  cpl a
                   anl   osreadybit,a                                ;设立本任务不能运行标志位置0
                   jb        oswaitflag,oswaitend        ;自认为是精妙之处,oswaitflag为1说明没有被系统中断,可以检测本任务后的一个任务
                        ;oswaitflag为0说明被系统中断过了。根据占先式OS的要求,就会重新从优先级为0的任务开始检测;
          ajmp  taskjc                  ;
oswaitend:clr   oswaitflag                                 ;清除本保护区标志,
                  
tasksw:   ;用户调用的任务切换程序,特点:接着上一个任务,处理下一个任务
                 setb  ostaskswflag                ;任务切换保护区标志的意义,正在切换任务时,来了中断时间,事件标志,都会更新,在这更新前切换任务是不合适的,
                                                                 ;所以,系统检测如果中断了TASKSW后,就会把SP,oswaitbit,osinitbit都恢复到处理之前的状态,
                ;任务切换程序中检测所有可以运行任务,可以运行的原因
                  ;这是任务切换程序的准备工作
                        clr ea
                         mov savesp,sp                                        ;备份SP,挂起标志,中断标志
                        mov savewait,oswaitbit
                         mov saveinit,osinitbit
                         setb ea
                        
                        
                 ;任务切换程序
nexttask:   mov a,taskidbit
                         rl  a
                         mov taskidbit,a
                         inc taskidnum
                         mov a,taskidnum
                         cjne a,#maxtask+1,ossw1
                         clr ostaskswflag
                         setb osidltask
                         mov psw,#0
osidl:      orl pcon,#1
                         jmp osidl
ossw1:            mov a,taskidbit
                         anl a,osreadybit                       ;本任务可以运行吗
                        jz nexttask                                    ;不能运行转到下一个,
                         anl a,oswaitbit                                ;可以运行,是否被挂起的,
                         jz  ossw2                                     ;没被挂起就跳到下面的检测
                        ;挂起任务的处理
                    cpl a
                     anl oswaitbit,a                            ;挂起的任务可以运行了,清除其挂起标志,
                   mov  b,#3                          ;计算OSWAITRAM数据地址换算
                  mov  a,taskidnum        
                   mul  ab
                   mov  r0,#oswaitram                  ;首址
                  add   a, r0                         ;取得本任务OSWAITRAM数据结构地址
                  add  a,#2                                                ;不处理第一字节数据,跳过第二字节为了配合欠跳转,
             mov r0,a
                   mov   a,@r0
                   push   ACC                                           ;恢复本任务断点PC指针,
                   dec   r0
                   mov   a,@r0
                   push   ACC
                   jmp   osswend                                        ;跳到断点处
ossw2:   ;中断任务的处理
                  mov a,taskidbit               
                   anl a,osinitbit        
                   jz   ossw3                                     ;也没有中断就跳到OSSW3
                   cpl a
                   anl osinitbit,a                            ;中断的任务可以运行了,清除其中断标志,
                   POP        03h
                   POP        02h
                   POP        01h
                   POP        00h
                   POP        DPL
                   POP        DPH
                   POP        B
                   POP        PSW
                   POP        ACC        
                   jmp   osswend         
ossw3:   ;没有挂起,也没有中断的任务的处理
                 mov dptr,#taskpcmap                  ;各个任务的首PC地址
                 mov  a,taskidnum
                  rl a                                                         C值是双字节,所以要*2
                  mov r3,a
                  movc a,@a+dptr
                  push ACC
                  mov a,r3
                  inc a
                  movc a,@a+dptr
                  push ACC
osswend: clr ostaskswflag                            ;切换结束,清除其开关
                 ret
                                                                           
osinitpro:; 系统中断处理程序 中断程序中检测所有没有准备好的任务,不能运行的原因
                        clr tr0
                         mov th0,#H5MS
                         mov tl0,#L5MS
                         setb tr0
                             
                         jb osidltask,taskjc                          ;这是最低优先级任务的标识
                        jb ostaskswflag,flag1            ;ostaskswflag是TASKSW数据保护区
                        jb oswaitflag,flag0                    ;oswaitflag是WAIT数据保护区需要保护处理就跳到FLAG0,并清零                  
                 PUSH        ACC        ;受OS保护的寄存器就这些.
                 PUSH        PSW
                 PUSH        B
                 PUSH        DPH
                 PUSH        DPL
                 PUSH        00h
                 PUSH        01h
                 PUSH        02h
                 PUSH        03h
;任务被中断了,
                mov a,taskidbit
                 orl osinitbit,a        ;把被中断任务的中断标志置1
                 ;cpl a
                 ;anl osreadybit,a      ;把被中断的任务的准备好标志置0,
                setb osinittaskflag                     ; 中断任务保护区
taskjc:            ;系统用的任务切换,特点:从0任务开始处理,只处理延时和事件的标志
                        mov  a,#1
                         mov taskidbit,a
                         mov r3,a
                         mov r2,#0        ;中断后总是初始化任务指针指向第0个任务
                        mov taskidnum,r2
nextjc:        cjne r2,#maxtask+1,jc2         ;最后一个任务检测完了就结束检测               
jcend:         jbc osinittaskflag,jcend2        ;中断了的任务,已经保存了他的SP等信息,直接到JCEND2,由任务切换程序按该任务的优先级来执行
                jbc osidltask,     jcend666                          ;这是最低优先级任务的标识
                jbc ostaskswflag,  jcend999                ;ostaskswflag是TASKSW数据保护区
                jbc oswaitflag,    jcend2                    ;oswaitflag是WAIT数据保护区需要保护处理就跳到FLAG0,并清零        
                          
jcend999:        
                          POP DPH
                   POP DPL
jcend666:;         // clr ostaskswflag
                          dec sp
                      dec sp
jcend2:                                  ;  出口为任务切换程序PC地址
;        //          anl 2fh,#192      ;2fH是位寻址各种标志寄存器,高2位被用户程序占用,不被清0,低6位被清0
                   acall timer                         ;时间,LED秒点,时间温度切换显示
                 mov a,#low ossw1                         ;这里要直接跳到ossw1,需要注意这里
                 push acc
                  mov a,#high ossw1
                  push acc
                  
                        
jcend333:         reti                                 

jc2:                anl        a,osreadybit                ;中断中就检测OSREADYBIT这个标志
                        jz  noready
jc1:     mov a,r3
          rl a
                         mov r3,a
                         inc r2
                         jmp nextjc
flag0:                ret                                  ;处理的办法,直接返回原数据保护区,不干涉,再由数据区跳到中断区退出
flag1:      mov sp,savesp                                ;恢复被TASKSW子程序更改的SP,挂起标志,中断标志后,重新进行切换
                        mov oswaitbit,savewait
                         mov osinitbit,saveinit
                         PUSH DPL
                     PUSH DPH
                         jmp taskjc
noready:     ;检测不能运行任务的原因
                        mov a,r3
                         anl a,oswaitbit              ;暂只有挂起检测
                        jz  jc1
taskgq:        ;挂起任务的检测工作
                  mov  b,#3                          ;计算OSWAITRAM数据地址换算
                  mov  a,r2        
                   mul  ab
                   mov  r0,#oswaitram                  ;首址
                  add   a, r0                         ;取得本任务OSWAITRAM数据结构地址
                  mov r0,a
                   mov a,@r0
                   ;
                   jb  acc.7,msstart                ;oswaitram.7是数据成以4的延时标志,能延时63*5*4=1260MS;如果这2个标志全没有就是普通延时
                  jb acc.6,jc807                        ;oswaitram.6是有事件标志                 
                   jmp jc801                        
msstart:  cpl ms1to41
                   jnb ms1to41,ms14
                    jmp jc1
ms14:          cpl ms1to42
                   jnb ms1to42,jc1

jc801:          dec @r0         
                   mov a,#63                  ;屏B高2位
                  anl a,@r0
                   jnz jc1
jc888:                mov a,r3
                         orl osreadybit,a              ;任务延时时间到,置位可以运行的标志
                        jmp jc1
jc807: ;;1111111111111111111光事件
                  mov a,r2
                   rl a                   ;*2,用的是RL,/2用的是RR,  
                   mov dptr,#sjpc
                   jmp @a+dptr
sjpc:           ajmp task0           ;提供给各个任务的事件处理程序
;原本这里计划要处理事件包括,任务间的通信,一些特殊的任务等,很麻烦,结果一拖再拖后
;没有心情弄了.
                    ajmp task1
                    ajmp task2
                    ajmp task3
                    ajmp task4
                    ajmp task5
                    ajmp task6
                    ajmp task7

task0:

task1:    jb t2t,jc889        ;第二个任务的简单的事件,是否是温度模式
                  jmp jc1
jc889:          mov a,@r0
                   anl a,#191                   ;本任务事件处理完,去除本任务的事件标志
                  mov @r0,a                                
                   jmp jc888                           ;再去去除没准备好的标志
task2:
task3:
task4:
task5:
task6:
task7:
                                                      


initial:  
                    mov r7,#200    ;1S时间        
                    clr a
                    mov s5,a
                    mov tmod,a          ;定时器0工作于模式0,13位定时状态
                   mov th0,#H5MS                ;13位定时器的定时数据计算:取低5位的值做为TL0的数据,高8位的值做为TH0的数据,否则就不会对。
                   mov tl0,#L5MS                        ;定时5MS的初值
                   acall rest1380
                         ret         



;**************************************************************
;DS18B20子程序集
;**************************************************************
;//*****************************************//
; 将从DS18B20中读出的温度数据进行转换
/*18b20中取出的温度TEMPL,和TEMPH. TEMPL中的低四位代表小数位.
                                         正温度的算法: TEMPL中的高四位和TEMPH中的低三位.一起组成正温度时的温度值        
                                                                   TEMPH中的高五位代表正负符号标志.5个0时为正温度,5个1时为负温度
                                        负温度的算法: 负温度的算法基本和正的相同.不同之处在于TEMPL中的高四位和TEMPH中的低三位
                                                                  这个7BIT的数要进行取反加一操作.
                                                                  
//*****************************************/
TEMPER_COV:         /* mov tempLOK,        TEMPER_L
                           MOV tempHOK,  TEMPER_H
                           RET                          */
;精确到99.9的尾数显示 ,模仿人工有小数点的成法
   mov a,TEMPER_L
    mov b,#6
    clr c
    mul ab
    mov r3,a      ; 十位相成的积
   mov b,#10
    div ab                        ;
    clr c
    add a,r3
    mov r3,0f0h
    clr c
    cjne r3,#6,qq11  ;五蛇六入
qq22:  inc a
         jmp qq33
qq11: jc qq33
           jmp qq22        
qq33:mov b,#10
         clr c          ;好象成除法,DA,都与CY有关联
        div ab
         swap  a                 ;十位显示小数部分.个位显示C
         xrl a,0f0h    ;合成

        mov tempLOK,a        ;小数部分
        mov a,TEMPER_L
         anl a,#240
         swap a
         mov r2,a                ;
         mov a,TEMPER_H
         anl a,#7
         swap a
         xrl 02h,a                ;用异或进行数据合成,并把合成后的8位初步温度数据存入R2中
   
     MOV A,TEMPER_H
         anl a,#248   ;看高5位是0还是1
         jz  zentemp
         ;负温
         mov a,r2
          cpl a
          inc a
          anl a,#127
tempout:mov b,#10
                 clr c
                 div ab
                 swap a
                 xrl a,0f0h
             mov tempHOK,a                ;温度的整数部分
           ret
zentemp:mov a,r2   ;正温度时更好转换   
                 jmp tempout
         


;//*****************************************//                                                                           
; DS18B20初始化程序
;//*****************************************//
; 这是DS18B20复位初始化子程序
INIT_1820:
      SETB DQ
      NOP
      CLR DQ
;主机发出延时537微秒的复位低脉冲
     MOV R0,#134
TSR1JNZ R0,$
      SETB DQ;然后拉高数据线
     NOP
      NOP
      MOV R0,#77
TSR2:JNB DQ,TSR3;等待DS18B20回应
     DJNZ R0,TSR2
      AJMP TSR4 ; 延时
TSR3:        djnz r0,tsr3
         SETB drive ; 置标志位,表示DS1820存在
                AJMP TSR5

                 
TSR4:CLR drive ; 清标志位,表示DS1820不存在
     AJMP TSR7
TSR5:MOV R0,#7
TSR6JNZ R0,TSR6 ; 时序要求延时一段时间
TSR7:SETB DQ
     RET

;//*****************************************//
; 写DS18B20的程序
;//*****************************************//
;写DS18B20的子程序(有具体的时序要求)
WRITE_1820:
         MOV R2,#8;一共8位数据
        CLR C
WR1:
         CLR DQ
         MOV R3,#3
         DJNZ R3,$
         RRC A
         MOV DQ,C
         MOV R3,#11
         DJNZ R3,$
         SETB DQ
         NOP
         DJNZ R2,WR1
         SETB DQ
         nop
         RET

;//*****************************************//
; 读DS18B20的程序,从DS18B20中读出一个字节的数据
;//*****************************************//
; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据
READ_TEMP:
         MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
        MOV R1,#TEMPER_L ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
         
RE00:MOV R2,#8;数据一共有8位
   
RE01:CLR C
         SETB DQ
         NOP
         CLR DQ
         NOP
         NOP
         SETB DQ
         MOV R3,#2
RE10: DJNZ R3,RE10
         nop
         MOV C,DQ
         MOV R3,#2
RE20: DJNZ R3,RE20
         RRC A
         DJNZ R2,RE01
         MOV @R1,A
         DEC R1
         DJNZ R4,RE00
         RET
;//*****************************************//
;
;**************************************************************
timer:        
                                                             ;最高优先级任务,直接在系统中断中作为子程序调用,
                 DJNZ r7,tt1                          ;时间模式
                mov r7,#200
                 mov a,S5
                 cjne a,#5,tts
                 mov S5,#0
                 cpl t2t
                 setb htreadbit         ;一秒一读
                jmp tt22
tts:        inc S5               
         
                 ;LED秒点控制
tt22:           
                    jb t2t,wendu1  
                    setb leddianH                ;时间模式下2个灯一起闪
                   setb leddianL
                    jmp        timeout

tt1:   
                      cjne r7,#100,tt6
;LED秒点半秒控制  
                    
                           jb t2t,wendu1  
                    clr leddianH
                    clr leddianL                ;时间模式下2个灯一起闪           
                    jmp        timeout

wendu1:                    clr leddianH
                         setb leddianL       ;温度模式下下LED只亮不闪
                        mov displaydataH,tempHOK
                         mov displaydataL,tempLOK
tt6:                ret                ;不是整秒或半秒不动LED秒点


timeout:         mov displaydataL,timeL
                  mov displaydataH,timeH                    
                    ret

writehms:           ;写入小时,分秒的子程序
                mov B,#0beh ;BEH为多字节写入的命令
                mov R2,#3  ;只写入小时和分数据和秒
            mov r0,#timeS ;写入的小时和分数据首址
                acall tx   ;调用写入
                ret
readhms: mov B,#0bfh ;0bfh为多字节读出命令               
          mov R2,#3    ;只读出小时,分,秒数据
                 mov r1,#timeS ;读出的时,分,秒数据首址
                 acall rx ;          ;调用读出
          ret
rx:                                      ;        rx接收
         acall htrest_com    ;htrest_com子程序为1830的初始化和命令字节(在B中)的发送
rx_byte1:clr a                  ;准备接收数据
                 clr c
                  mov R3,#8 ;接收位数为8
rx_byte2:nop
                  mov c,sdata  ;数据总线数据传送给C
                  rrc a        ;移入A
                  setb sclk          ;时钟总线置高
                 nop
                  clr sclk           ;时钟下跳,接收有效
                 nop
                  djnz R3,rx_byte2
                  mov @r1,a                ;接收到的数据放入内存缓冲区
                 inc r1                 ;内存地址加一
                 djnz R2,rx_byte1 ;字节未接收完继续
                 nop
                  clr srst                ;逻辑操作完毕,关闭
                 ret
tx:                              ; tx发送
                acall htrest_com
tx_byte1:mov a,@r0        ;传送数据
                 mov R3,#8
tx_byte2:rrc a
                  mov sdata,c
                  nop
                  setb sclk
                  nop
                  clr sclk                ;清时钟总线
                 djnz R3,tx_byte2
                  inc r0
                  djnz R2,tx_byte1 ;多字节传送
                 
                  clr srst
                  ret                                 
;入口参数:B
htrest_com: clr srst ;复位端为0,所有数据传送终止
                clr c
                 nop
                 clr sclk ;清时钟总线
                nop
                 setb srst ;复位端为1,逻辑控制有效
                mov a,B ;准备发送命令字节
                mov R3,#8 ;传送位为8
rxtx_byte0:rrc a                     ;将最低位传送给c
                 mov sdata,c         ;位传送到数据总线
                nop
                 setb sclk                ;时钟上升沿,发送的数据有效
                nop
                 clr sclk                ;清时钟总线
                djnz R3,rxtx_byte0 ;8位未完继续               
                 ret

rest1380:mov r0,#timeS
          mov @r0,#0    ;数据
          mov B,#8eh  ;8eh命令:写写保护,写0就充许数据写入时分秒单元
          mov R2,#1 ;只写入一个数据                    
          acall tx

           mov r0,#timeS
           mov @r0,#0    ;数据
          mov B,#80h  ;允许工作的命令
          mov R2,#1 ;只写入一个数据                    
          acall tx
          ret        
;任务欠表,决定最终任务的执行顺序                  
taskpcmap: db low keyscan, high keyscan,low GET_TEMPER, high GET_TEMPER,low display, high display
;taskpcmap:  dw  keyscan,GET_TEMPER,display
end
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表