⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iic_os2.asm

📁 i2c to os/2
💻 ASM
📖 第 1 页 / 共 5 页
字号:
DO_30:
        CJNE    A,#status_OK_,DO_35
        CLR     IIC_failure
        CLR     i_am_a_slave
DO_X:
        MOV     A,IIC_status
        MOV     IIC_final_status,A
        RET
        ;
        ;if 'iic_timer' overflows, have an IIC bus timeout error.
        ;
DO_ERR:
        CALL    MORE_00_SUB                               ;clear all registers
        ANL     IIC_status,#status_upper_mask_          ;preserve upper nibble
        ORL     IIC_status,#status_timeout_               ;indicate inactivity
        CALL    DO_ERRX
        ;
        ;do error recovery here - i.e. lost arbitration, bus error.
        ;Alternately, let the calling routine interrogate 'IIC_final_status'
        ;so that the main routines decide what to do for various errors.  For
        ;development and debug purposes, this example routine ignores the
        ;errors.
        ;
DO_35:
        SETB    IIC_failure                     ;indicate a failed IIC session
        SJMP    DO_X
DO_ERRX:                                  ;ensure the interrupt bit is cleared
        RETI
        ;
        ;==========
        ;"IIC_time"
        ;Subroutine to increment IIC timeout timer.  ACC returns 0 if timeout
        ;occurs.  Should make this an actual timer in your system so that
        ;the amount of time for a timeout is deterministic.  Note that the
        ;"IIC_VECTOR" routine resets this timer as well.
        ;
IIC_time:
        INC     iic_timer
        MOV     A,iic_timer
        JNZ     time_X
        INC     iic_timer + 1
        MOV     A,iic_timer + 1
time_X:
        RET
;
;============================================================================
;Subroutine "FETCH_COMMAND"
;DESCRIPTION:
;============
;This subroutine fetches a byte from the address 'IIC_Command_File_adrs' in
;code memory space.  If "FETCH_COMMAND_0" is called, then the address pointer
;'IIC_Command_File_adrs' is not incremented at exit, otherwise the address
;pointer is incremented.
;INPUT:
;======
;'IIC_Command_File_adrs' holds the address of the byte to be retreived.
;OUTPUT:
;=======
;ACCumulator holds the retreived byte.
;'IIC_Command_File_adrs' is incremented (not if "FETCH_COMMAND_0" is called).
;
FETCH_COMMAND_0:
        CLR     C                  ;carry indicates whether pointer inc or not
        SJMP    FC_10

FETCH_COMMAND:
        SETB    C

FC_10:
        MOV     DPL,IIC_Command_File_adrs           ;no, must be XDATA or CODE
        MOV     DPH,IIC_Command_File_adrs+1
FC_Code:
        CLR     A
        MOVC    A,@A+DPTR
FC_exit:
        JNC     FCX_10                    ;don't increment pointer if no carry
        INC     DPTR                          ;if carry set, increment pointer
FCX_10:
        MOV     IIC_Command_File_adrs,DPL                     ;restore pointer
        MOV     IIC_Command_File_adrs+1,DPH
        RET
;
;============================================================================
;Subroutine "FETCH_DATA"
;DESCRIPTION:
;============
;This subroutine is used by all the IIC_OS2 states to get the next data byte
;from the address 'IO_address' in the memory space indicated in
;'Data?adrs?space'.  This routine also saves the fetched data in the byte
;'last_data' so error recovery can be easiy done.  Before this routine exits,
;the pointer 'IO_buffer_adrs' is incremented.  For the 'immediate_' directive,
;simply get the next data byte from the command file stream.
;Fetched data returned in ACCumulator.
;INPUT:
;======
;'IO_address' has address where data is to be fetched from.  If the target
;             space is DATA, then the LSByte of 'IO_address' is the full
;             address and the MSByte is ignored.
;'Data?adrs?space' holds the information for which address space is to be
;             targetted for fetching the data.
;OUTPUT:
;=======
;ACCumulator is loaded with the fetched byte.
;'last_data' gets the fetched byte as well.
;'IO_address' is incremented (unless in immediate option in which case the
;                             'IO_address' is meaningless).
;
FETCH_DATA:
        JNB     immediate_data,FD_10
        CALL    FETCH_COMMAND              ;if immediate option, get data from
        JMP     FD_x2                                     ;command file stream
FD_10:
        JB      IO_Data,FD_Data                        ;is data in DATA space?
        MOV     DPL,IO_buffer_adrs       ;no, then must be XDATA or CODE space
        MOV     DPH,IO_buffer_adrs+1
        JB      IO_Code,FD_Code                          ;is it in CODE space?

FD_Xdata:
        MOVX    A,@DPTR                         ;no, it must be in XDATA space

FD_exit:
        INC     DPTR                                             ;bump pointer
        MOV     IO_buffer_adrs,DPL                            ;restore pointer
        MOV     IO_buffer_adrs + 1,DPH
FD_x2:
        MOV     last_data,A                                        ;store data
        RET
        ;
        ;enter here if data is in CODE space
        ;
FD_Code:
        CLR     A
        MOVC    A,@A+DPTR
        SJMP    FD_exit
        ;
        ;enter here if data is in DATA space
        ;
FD_Data:
        MOV     R0,IO_buffer_adrs
        MOV     A,@R0
        MOV     last_data,A
        INC     R0
        MOV     IO_buffer_adrs,R0
        RET
;
;============================================================================
;Subroutine "STORE_DATA"
;DESCRIPTION:
;============
;This subroutine stores incoming data in the address 'IO_address' in the
;data space indicated in 'Data?adrs?space'.  Only XDATA and DATA spaces
;are valid since we cannot write into the CODE space.
;INPUT:
;======
;ACCumulator has data to be stored.  This data is not corrupted.
;'IO_address' holds address for where data is to be stored
;'Data?adrs?space' (bit addressable) describes which data space is to
;             be targetted.
;OUTPUT:
;=======
;ACCumulator contents not corrupted by subroutine
;ACCumulator contents are stored in address as described above.
;'last_data' holds a copy of the data.
;'IO_address' is incremented.
;
STORE_DATA:
        JB      IO_Data,SD_Data                          ;is target area DATA?

SD_Xdata:
        MOV     DPL,IO_buffer_adrs             ;no, then must be XDATA so load
        MOV     DPH,IO_buffer_adrs+1                        ;address into DPTR
        MOVX    @DPTR,A                                        ;store the data
        MOV     last_data,A                                       ;and copy it
        INC     DPTR                                 ;bump the address pointer
        MOV     IO_buffer_adrs,DPL                             ;and restore it
        MOV     IO_buffer_adrs+1,DPH
        RET
        ;
        ;enter here if the target space is DATA
        ;
SD_Data:
        MOV     R0,IO_buffer_adrs                     ;get the address into R0
        MOV     @R0,A                                          ;store the data
        MOV     last_data,A                                       ;and copy it
        INC     R0                                   ;bump the address pointer
        MOV     IO_buffer_adrs,R0                              ;and restore it
        RET
$eject
;
;===========================================================================
;IIC interrupt vector
;Everytime a significant event occurs on the IIC bus (a start, stop, error,
;etc.), this interrupt routine is entered.  This routine reads the IIC
;hardware SFR called 'S1STA' to determine what state the IIC hardware is in.
;Each state has it's own processing routine as shown below.
;The multi-master rotuines shown are very simple in this module - multi-
;master functions are very dependent on the system being serviced.  This
;module simply relinquishes control of the bus if another master wins
;arbitration;  it will receive or send bytes if it is addressed as a
;slave.
;============================================================================
;
IIC_VECTOR:
        PUSH    PSW               ;save all registers used in interrupt vector
        PUSH    ACC
        PUSH    DPL
        PUSH    DPH
        PUSH    AR0
;
;'S1STA', the SFR indicating IIC hardware status for the '552 takes on a
;limited range of values, namely 00H to 0C8H in steps of 08H.  The following
;manipulation changes the 'S1STA' value to a number from 0 to 50 (decimal) in
;steps of 2 so a jump can be done from an 'AJMP' table (AJMP instruction is
;2 bytes long).  In other words, divide 'S1STA' by 4!
;
;The only special case for S1STA is the 'No relevant state' = state 0F8H.  In
;this state, there is no relevant information and the IIC spec. says to
;ignore the state completely.  So I did.
;
        MOV     A,S1STA            ;get SFR which holds hardware status of bus
        CJNE    A,#0F8H,IICV_10                 ;check for 'No relevant state'
        SJMP    IIC_EXIT
IICV_10:
        RR      A
        RR      A
        MOV     DPTR,#S1STA_00
        JMP     @A+DPTR
;
;all sections exit here.
;The timeout timer 'iic_timer' is restarted everytime around, it is assumed
;that if an interrupt occurs, that more than likely, everything is OK.
;
IIC_EXIT:
        MOV     iic_timer,#LOW(max_wait_)                ;reload timeout timer
        MOV     iic_timer + 1,#HIGH(max_wait_)

        POP     AR0
        POP     DPH
        POP     DPL
        POP     ACC
        POP     PSW
        RETI
;
;----------------------------------------------------------------------------
;Jump table for interrupt routine entry above.
;----------------------------------------------------------------------------
;
S1STA_00:
        AJMP     MORE_00                                       ;Bus Error mode

        AJMP     MORE_08                     ;Master Receiver/Transmitter Mode
        AJMP     MORE_10                     ;Master Receiver/Transmitter Mode
        AJMP     MORE_18                              ;Master Transmitter Mode
        AJMP     MORE_20                              ;Master Transmitter Mode
        AJMP     MORE_28                              ;Master Transmitter Mode
        AJMP     MORE_30                              ;Master Transmitter Mode
        AJMP     MORE_38                     ;Master Receiver/Transmitter Mode

        AJMP     MORE_40                                 ;Master Receiver Mode
        AJMP     MORE_48                                 ;Master Receiver Mode
        AJMP     MORE_50                                 ;Master Receiver Mode
        AJMP     MORE_58                                 ;Master Receiver Mode

        AJMP     MORE_60                                  ;Slave Receiver Mode
        AJMP     MORE_68                                  ;Slave Receiver Mode
        AJMP     MORE_70                                  ;Slave Receiver Mode
        AJMP     MORE_78                                  ;Sla

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -