打印

谁有PCF8563的程序啊,共享一下

[复制链接]
4383|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
徐剑青|  楼主 | 2007-5-26 18:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
徐剑青|  楼主 | 2007-5-26 18:23 | 只看该作者

程序

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


;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

使用特权

评论回复
板凳
su_tech| | 2007-5-26 21:26 | 只看该作者

遇到相同问题,读快了秒位也有问题

使用特权

评论回复
地板
dengm| | 2007-5-26 21:57 | 只看该作者

等长一点: acc = 0 时,为 error

I2_CHKACK:         SETB  I2_SDA
                   NOP
                   NOP
                   SETB  I2_SCL
                   CLR F0
                   MOV A, #20
I2_CHKACK_L1:                  
                     JNB I2_SDA, I2_CHKACK_L2
                   DJNZ ACC, I2_CHKACK_L1
                   SETB F0
I2_CHKACK_L2:
                   CLR   I2_SCL
                   RET

使用特权

评论回复
5
dengm| | 2007-5-26 22:15 | 只看该作者

给你一段

I2C_WRITE_BYTE:
         ; INPUT: A
         ; OUTPUT: A =0 为 error
         SETB C
I2C_WR_BIT:
           CLR I2C_SCL
           RLC A
           MOV I2C_SDA, C
           JZ I2C_WR_BIT_EX
           SETB I2C_SCL
           CLR C
         SJMP I2C_WR_BIT   
I2C_WR_BIT_EX:
         MOV A, #20
I2C_W_ACK:
            JNB I2C_SDA, I2C_W_ACK_EX
         DJNZ ACC, I2C_W_ACK
I2C_W_ACK_EX:  
         SETB I2C_SCL
         RET
 

使用特权

评论回复
6
徐剑青|  楼主 | 2007-5-27 18:08 | 只看该作者

感谢

  有道理哦.好!我试试去.
  先谢了!

使用特权

评论回复
7
dengm| | 2007-5-31 09:07 | 只看该作者

RE: zt:i2c asm from www.programmersheaven.com




;****************************************************************************





;                     Software Implemented I2C Drivers





; These routines allow an 80C51 based microcontroller to drive the I2C bus 


; as a single master. The main program at the end demonstrates writing and 


; reading several types of devices: 





;    PCF8570 256 byte static RAM.


;    PCF8574 8-bit I/O expander.


;    SAA1064 4 digit LED display driver.








;             Written by G.Goodhue, Philips Components-Signetics





;****************************************************************************








$Title(I2C Routines for 80C51)


$Date(08/14/90)


$MOD51


$DEBUG








;****************************************************************************


;                               Definitions


;****************************************************************************








; Addresses of several I2C devices as connected on the Signetics I2C 


; Evaluation Board.





I2CRAM     EQU     0AEh           ;Slave address for PCF8570 RAM chip.


I2CIO      EQU     4Eh            ;Slave address for PCF8574 I/O expandor.


I2CLED     EQU     76h            ;Slave address for SAA1064 LED driver.








; Data storage locations





BitCnt     DATA    8h             ;Bit counter for I2C routines.


ByteCnt    DATA    9h             ;Byte counter for I2C routines.


SlvAdr     DATA    0Ah            ;Slave address for I2C routines.





XmtDat     DATA    10h            ;I2C transmit buffer, 8 bytes max.


RcvDat     DATA    18h            ;I2C receive buffer, 8 bytes max.


AltRcv     DATA    20h            ;Alternate I2C receive buffer, 8 bytes max.





Flags      DATA    28h            ;Location for bit flags


NoAck      BIT     Flags.0        ;I2C no acknowledge flag.


BusFault   BIT     Flags.1        ;I2C bus fault flag.


I2CBusy    BIT     Flags.2        ;I2C busy flag.








; I2C connections.





SCLPin     BIT     P0.0           ;I2C serial clock line.


SDAPin     BIT     P0.1           ;I2C serial data line.








;****************************************************************************


;                       Reset and Interrupt Vectors


;****************************************************************************








           ORG     0


           AJMP    Reset








;****************************************************************************


;                               Subroutines


;****************************************************************************








           ORG     30h





; BitDly - insures minimum high and low clock times on I2C bus.


; This routine must be tuned for the actual oscilator frequency used, shown 


; here tuned for a 12MHz clock. Note that the CALL instruction that invokes 


; BitDly already uses 2 machine cycles.





BitDly:    NOP                    ;NOPs to delay 5 microseconds (minus 4


                                  ;  machine cycles for CALL and RET).


           RET








; SCLHigh - sends SCL pin high and waits for any clock stretching peripherals.





SCLHigh:   SETB    SCLPin         ;Set SCL from our end.


           JNB     SCLPin,$       ;Wait for pin to actually go high.


           RET








; SendStop - sends an I2C stop, releasing the bus.





SendStop:  CLR     SDAPin         ;Get SDA ready for stop.


           ACALL   SCLHigh        ;Set clock for stop.


           ACALL   BitDly


           SETB    SDAPin         ;Send I2C stop.


           ACALL   BitDly


           CLR     I2CBusy        ;Clear I2C busy status.


           RET                    ;Bus should now be released.








; SendByte - sends one byte of data to an I2C slave device.


; Enter with:


;   ACC = data byte to be sent.





SendByte:  MOV     BitCnt,#8      ;Set bit count.





SBLoop:    RLC     A              ;Send one data bit.


           MOV     SDAPin,C       ;Put data bit on pin.


           ACALL   SCLHigh        ;Send clock.


           ACALL   BitDly


           CLR     SCLPin


           ACALL   BitDly


           DJNZ    BitCnt,SBloop  ;Repeat until all bits sent.





           SETB    SDAPin         ;Release data line for acknowledge.


           ACALL   SCLHigh        ;Send clock for acknowledge.


           ACALL   BitDly


           JNB     SDAPin,SBEX    ;Check for valid acknowledge bit.


           SETB    NoAck          ;Set status for no acknowledge.


SBEX:      CLR     SCLPin         ;Finish acknowledge bit.


           ACALL   BitDly


           RET








; GoMaster - sends an I2C start and slave address.


; Enter with:


;   SlvAdr = slave address.





GoMaster:  SETB    I2CBusy        ;Indicate that I2C frame is in progress.


           CLR     NoAck          ;Clear error status flags.


           CLR     BusFault


           JNB     SCLPin,Fault   ;Check for bus clear.


           JNB     SDAPin,Fault


           CLR     SDAPin         ;Begin I2C start.


           ACALL   BitDly


           CLR     SCLPin


           ACALL   BitDly         ;Complete I2C start.


           MOV     A,SlvAdr       ;Get slave address.


           ACALL   SendByte       ;Send slave address.


           RET





Fault:     SETB    BusFault       ;Set fault status


           RET                    ;  and exit.








; SendData - sends one or more bytes of data to an I2C slave device.


; Enter with:


;   ByteCnt = count of bytes to be sent.


;   SlvAdr  = slave address.


;   @R0     = data to be sent (the first data byte will be the 


;             subaddress, if the I2C device expects one).





SendData:  ACALL   GoMaster       ;Acquire bus and send slave address.


           JB      NoAck,SDEX     ;Check for slave not responding.





SDLoop:    MOV     A,@R0          ;Get data byte from buffer.


           ACALL   SendByte       ;Send next data byte.


           INC     R0             ;Advance buffer pointer.


           JB      NoAck,SDEX     ;Check for slave not responding.


           DJNZ    ByteCnt,SDLoop ;All bytes sent?





SDEX:      ACALL   SendStop       ;Done, send an I2C stop.


           RET








;RcvByte - receives one byte of data from an I2C slave device.


; Returns:


;   ACC = data byte received.





RcvByte:   MOV     BitCnt,#8      ;Set bit count.





RBLoop:    ACALL   SCLHigh        ;Read one data bit.


           ACALL   BitDly


           MOV     C,SDAPin       ;Get data bit from pin.


           RLC     A              ;Rotate bit into result byte.


           CLR     SCLPin


           ACALL   BitDly


           DJNZ    BitCnt,RBLoop  ;Repeat until all bits received.





           PUSH    ACC            ;Save accumulator


           MOV     A,ByteCnt


           CJNE    A,#1,RBAck     ;Check for last byte of frame.


           SETB    SDAPin         ;Send no acknowledge on last byte.


           SJMP    RBAClk





RBAck:     CLR     SDAPin         ;Send acknowledge bit.


RBAClk:    ACALL   SCLHigh        ;Send acknowledge clock.


           POP     ACC            ;Restore accumulator


           ACALL   BitDly


           CLR     SCLPin


           SETB    SDAPin         ;Clear acknowledge bit.


           ACALL   BitDly


           RET








;RcvData - receives sends one or more bytes of data from an I2C slave device.


; Enter with:


;   ByteCnt = count of bytes to be sent.


;   SlvAdr  = slave address.


; Returns:


;   @R0     = data received.





; Note: to receive with a subaddress, use SendData to set the subaddress


;   first (no provision for repeated start).





RcvData:   INC     SlvAdr         ;Set for READ of slave.


           ACALL   GoMaster       ;Acquire bus and send slave address.


           JB      NoAck,RDEX     ;Check for slave not responding.





RDLoop:    ACALL   RcvByte        ;Recieve next data byte.


           MOV     @R0,A          ;Save data byte in buffer.


           INC     R0             ;Advance buffer pointer.


           DJNZ    ByteCnt,RDLoop ;Repeat untill all bytes received.





RDEX:      ACALL   SendStop       ;Done, send an I2C stop.


           RET








;****************************************************************************


;                               Main Program


;****************************************************************************








Reset:     MOV     SP,#2Fh        ;Set stack to start at 30h.





           MOV     XmtDat,#0      ;Initialize transmit data area.


           MOV     XmtDat+1,#37h


           MOV     XmtDat+2,#0AAh


           MOV     XmtDat+3,#055h


           MOV     XmtDat+4,#33h


           MOV     XmtDat+5,#0CCh


           MOV     XmtDat+6,#0FFh


           MOV     XmtDat+7,#0BBh








TestLoop:  MOV     SlvAdr,#I2CIO  ;Write data to PCF8574 I/O expandor.


           MOV     R0,#XmtDat+2   ;Start of data.


           MOV     ByteCnt,#1     ;Send one data byte.


           ACALL   SendData





           MOV     SlvAdr,#I2CIO  ;Read back data from PCF8574 I/O expandor.


           MOV     R0,#AltRcv     ;Start of data.


           MOV     ByteCnt,#1     ;Read one data byte.


           ACALL   RcvData


           INC     XmtDat+2       ;Advance data to next value.





           MOV     SlvAdr,#I2CLED ;Write data to SAA1064 LED driver.


           MOV     R0,#XmtDat     ;Start of data.


           MOV     ByteCnt,#6     ;Send 6 bytes (subaddress, control, data).


           ACALL   SendData





           MOV     SlvAdr,#I2CRAM ;Write data to PCF8570 RAM.


           MOV     R0,#XmtDat     ;Start of data.


           MOV     ByteCnt,#8     ;Send 8 bytes (subaddress + 7 data bytes).


           ACALL   SendData





           MOV     SlvAdr,#I2CRAM ;Write subaddress to PCF8570 RAM.


           MOV     R0,#XmtDat     ;Start of data.


           MOV     ByteCnt,#1     ;Send one byte (subaddress).


           ACALL   SendData


           MOV     SlvAdr,#I2CRAM ;Read back data from PCF8570 RAM.


           MOV     R0,#RcvDat     ;Start of data.


           MOV     ByteCnt,#7     ;Read 7 data bytes.


           ACALL   RcvData





           AJMP    TestLoop       ;Repeat operation for scope watchers.





           END


使用特权

评论回复
8
outstanding| | 2013-8-25 22:13 | 只看该作者

使用特权

评论回复
9
lanchong1980| | 2013-8-26 11:26 | 只看该作者
PCF8563和89C51的资料,看对你有用不 PCF8563.pdf (486.63 KB)



使用特权

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

本版积分规则

2

主题

4

帖子

0

粉丝