打印

pcf8563读时间乱

[复制链接]
2064|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
徐剑青|  楼主 | 2007-5-20 21:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  我用汇编编了个时钟程序.可是在读连续时间时有时回出现错误,有时又对了.不知道是什么原因.清高手指教.

我是用伟福模拟的,看内存单元.我实际也用液晶显示过,一样.


;I2C总线说明:
;I2_SDA =1时,即总线空闲
;I2_SDA =0时,即总线忙,即正在使用
; 本程序集在I2_SDA =0时, 使I2_SCL=0,
;此时即可改变I2_SDA 的数据,或接受I2_SDA 数据的改变
;I2_SCL=0时,  数据是可以改变的
;I2_SCL=1时,  数据的改变视为控制信号,如0到1则为停止控制
;如1到0则为启动控制

;I2C总线(PFC8563)驱动子程序集
I2_SCL                  EQU             P2.6
I2_SDA                  EQU             P2.7
I2ADDRW                 EQU             0A2H
I2ADDRR                 EQU             0A3H
I2TIMER                 EQU             02H
I2TIMERN                EQU             07H
               ORG      0000H
               JMP      MAIN
               ORG      0030H
MAIN:
     MOV        SP,#80H
     MOV        R0,#20H
     CALL I2_WRTIME     ;写时间初始值
ED:  MOV        R0,#28H
     CALL I2_RDTIME         ;读时间值
     JMP  ED
;========================================================== 开始I2CU总线子程序
I2_START:            SETB  I2_SDA
                     NOP
                     SETB  I2_SCL
                     NOP                        ;建立起始条件的时间大于4.7us

                     NOP
                     NOP
                     NOP
                     NOP
                     CLR   I2_SDA               ;起始条件
                     NOP
                     NOP
                     NOP
                     NOP
                     NOP
                     CLR   I2_SCL               ;钳隹总线
                     NOP
                     RET
;===================================================结束I2CU总线子程序
I2_STOP:             CLR   I2_SDA
                     NOP
                     SETB  I2_SCL               ;结束总线时间大于4us
                     NOP
                     NOP
                     NOP
                     NOP
                     NOP
                     SETB  I2_SDA               ;结束总线
                     NOP
                     NOP
                     NOP
                     NOP
                     RET
;=============================================发送应答信号子程序:即发送0
I2_SDACK:           CLR   I2_SDA
                    NOP
                    NOP
                    SETB  I2_SCL
                    NOP
                    NOP
                    NOP
                    NOP
                    NOP
                    CLR   I2_SCL
                    SETB I2_SDA
                    NOP
                    NOP
                    RET
;===========================================发送非应答信号子程序, 即发送1
I2_SDNACK:          SETB  I2_SDA
                    NOP
                    NOP
                    SETB  I2_SCL
                    NOP
                    NOP
                    NOP
                    NOP
                    NOP
                    CLR   I2_SCL
                    CLR  I2_SDA
                    NOP
                    NOP
                    RET
;====================================================
;检查应答子程序,即读应答信号:若读出结果 为0
;证明有应答,即总线上有器件响应,否则可能无器件或器件坏

;出口参数:
;FO=O有应答

I2_CHKACK:         SETB  I2_SDA
                   NOP
                   NOP
                   SETB  I2_SCL
                   NOP
                   NOP
                   NOP
                   NOP
                   CLR F0
                   MOV   C,  I2_SDA
                   JNC CEND
                   SETB F0

CEND:              CLR   I2_SCL
                   RET

;=============================================发送字节子程序

;入口参数
;A:   被发送数

;占用资源:
;R2

;说明:每写一字节要调用一次I2_CHKACK取应答位

I2_WRBYTE:        MOV   R2,  #08H
I2_WRBYTELP1:     RLC   A
                  MOV   I2_SDA,  C
                  NOP
                  SETB  I2_SCL
                  NOP
                  NOP
                  NOP
                  NOP
                  NOP
                  CLR   I2_SCL
                  DJNZ  R2,  I2_WRBYTELP1
                  NOP
                  NOP
                  RET

;==================================================读取字节子程序

;出口参数:
;A:    读出的数

;占用资源
;R2

;说明: 每读取一字节要发送一应答/非应答位

I2_RDBYTE:        MOV   R2,  #08H
I2_RDLP:          SETB  I2_SDA
                  NOP
                  SETB  I2_SCL
                  NOP
                  NOP
                  MOV   C,  I2_SDA
                  NOP
                  CLR   I2_SCL
                  RLC   A
                  NOP
                  NOP
                  NOP
                  NOP
                  DJNZ  R2, I2_RDLP
                  RET



;===================================BCD码转二进制子程序

;入口参数:
;A:  BCD码

;出口参数
;A:  二进制数

;占用资源:
;A
;R2
;R3

BCD2BIN:         MOV  R3,  A
                 ANL  A,  #0F0H
                 RR   A
                 MOV  R2,  A
                 RR   A
                 RR   A
                 ADD  A,  R2
                 MOV  R2,  A
                 MOV  A,  R3
                 ANL  A,  #0FH
                 ADD  A,  R2
                 RET


;========================================写8563万年历子程序

;入口参数:
;R0:  参数区首址: 参数区格式(秒分钟小时日星期月年,BCD码表示)

;占用资源:
;A
;R0
;R2
;R3


I2_WRTIME:        CALL  I2_START                ;发送起始条件

                  MOV   A, #I2ADDRW
                  CALL  I2_WRBYTE               ;发送8563地址
                  CALL  I2_CHKACK               ;检查应答
                  JB    F0,I2_WRTIME
                  MOV   A,  #I2TIMER            ;发送8563时间寄存器地址
                  CALL  I2_WRBYTE
                  CALL  I2_CHKACK
                     JB    F0,I2_WRTIME
                  MOV   R3,  #I2TIMERN
I2_WRTIMELP1:     MOV   A,  @R0
                  CALL  I2_WRBYTE               ;向8563写时间
                  CALL  I2_CHKACK
                     JB    F0,I2_WRTIME
                  INC   R0
                  DJNZ  R3,  I2_WRTIMELP1

                  CALL  I2_STOP                 ;发送停止条件
                  RET


;===================================读8563万年历子程序

;入口参数:
;R0:  参数区首址(格式同上)

;出口参数:参数区存放万年历数据(二进制)

;占用资源:
;A
;R0
;R2
;R3

I2_RDTIME:        CALL  I2_START                ;发送起始条件

                  MOV   A,  #I2ADDRW            ;发送8563写地址
                  CALL  I2_WRBYTE
                  CALL  I2_CHKACK
                  JB    F0,I2_RDTIME
                  MOV   A,  #I2TIMER            ;发送8563时间寄存器首址
                  CALL  I2_WRBYTE
                  CALL  I2_CHKACK
                  JB    F0,I2_RDTIME
                  CALL  I2_START                ;发送起始条件
                  MOV   A,  #I2ADDRR            ;发送8563读地址
                  CALL  I2_WRBYTE
                  CALL  I2_CHKACK
                  JB    F0,I2_RDTIME
                  MOV   R3,  #I2TIMERN-1
I2_RDTIMELP1:     CALL  I2_RDBYTE               ;读取8563万年历数据
                  MOV   @R0,  A
                  CALL  I2_SDACK            ;发送应答信号
                  INC   R0
                  DJNZ  R3,  I2_RDTIMELP1
                  CALL  I2_RDBYTE               ;读取8563万年历年数据
                  MOV   @R0,  A
                  CALL  I2_SDNACK               ;发送非应答信号
                  CALL  I2_STOP                 ;发送停止条件
                  RET








相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

4

帖子

0

粉丝