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

📄 iic_os2.asm

📁 i2c to os/2
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;'SLVbytes_... EQUates must change.
;
;IIC_OS2 does not need these 16 DATA bytes if the system is single-master.
;IF your system is single-master, then use the 'Slave_in' and 'Slave_out'
;buffers for your own general purpose buffers or registers.
;
;---------------
;IIC_data_buffer
;
;This buffer is a general purpose buffer for the "IIC_OS2" system.  It is
;the source or destination target when the address space directive in byte
;2 of the command file is 'ioBuffer_'.
;
;----------
;'aux_adrs'
;
;Loaded by the calling routine with the address of the slave to be
;communicated with.  This function allows the user to have a generic command
;block with the slave address specified by 'aux_adrs'.  The command file has
;'use_aux_adrs_' in place of the slave address.  The routine that loads
;'aux_adrs' must ensure the read/write bit is set correctly (by ORing the
;'aux_adrs' with 'iic_write_mask_' or 'iic_read_mask_').
;
;----------------------------------------------------------------------------
;
DSEG    AT      IIC_OS2_DATA

IIC_status:             DS      1
IIC_final_status:       DS      1
IO_buffer_adrs:         DS      2
IIC_Command_File_adrs:  DS      2
indirect_adrs:          DS      2
indirect_count:         DS      1
iic_timer:              DS      2
Attempt_count:          DS      1
Multiple_count:         DS      1
last_data:              DS      1
aux_adrs:               DS      1

Slave_in:               DS      SLVbytes_in_
Slave_out:              DS      SLVbytes_out_
IIC_data_buffer:        DS      IIC_buffer_size_
;
;Use 'DATA_start' to define where your system DATA bytes will be located.
;
DATA_start      EQU     IIC_data_buffer + IIC_buffer_size_
;
;'Data?adrs?space' is loaded by the calling routine, and maipulated by the
;"IIC_OS2" routine.  It indicates which memory space the command file is to
;be read from.  It also ultimately gets the address space for the input and
;output data, as well as the indication for the special functions 'indirect_',
;'immediate_', and 'call_'.  Generally speaking, the calling routine
;loads 'Data?adrs?space' with the code for which memory space holds the
;command file to be executed - then, the command file information ammends this
;byte as each block of the command file is executed.
;
DSEG    AT      IIC_OS2_BITADRS_DATA

Data?adrs?space:     DS      1

BSEG    AT      Data?adrs?space.0

IO_Data:                DBIT    1
IO_Code:                DBIT    1
IO_Buffer:              DBIT    1
immediate_data:         DBIT    1
call_function:          DBIT    1
indirect_xxx:           DBIT    1
dummy1:                 DBIT    1   ;fill out the byte since 'Data?adrs?space'
dummy2:                 DBIT    1                   ;is often byte manipulated
;
;this next bit is set whenever the microcontroller is addressed as a slave
;receiver or a slave transmitter.  "DO_IIC" needs this bit to hold off
;pending calls from the main routines to the IIC bus.
;
i_am_a_slave:           DBIT    1
;
;if any iic session failure occurs, set the failure bit
;
IIC_failure:            DBIT    1
;
;Use 'BITS_start' to define where your system bit definitions will be located.
;
BITS_start      EQU     IIC_failure + 1
;
;mask bytes for the various 'Data?adrs?space' bits.  These codes are used
;in the command file.  See examples above.
;
ioD_            EQU     00000001B           ;input/output data from DATA space
ioC_            EQU     00000010B                 ;output data from CODE space
ioBuffer_       EQU     00000100B    ;input/output data from 'IIC_data_buffer'
ioX_            EQU     00000000B          ;input/output data from XDATA space
immediate_      EQU     00001000B                ;next byte is data to be sent
call_           EQU     00010000B                ;call subroutine after in/out
indirect_       EQU     00100000B          ;get info from 'indirect_ registers
;
;masks to isolate the groups of bits in the 'Data?adrs?space' register.
;
iospaces_       EQU     00000111B              ;mask to isolate I/O space bits
commands_       EQU     00111000B     ;mask to isolate control and status bits
dummy1_bit_mask EQU     01000000B     ;mask to isolate 'dummy1' bit (not used)
dummy2_bit_mask EQU     10000000B     ;mask to isolate 'dummy2' bit (not used)
;
;The following status bytes are used to indicate the present state as well
;as the ultimate state of the IIC operations.  These values are loaded into
;'IIC_status' by the various states as well as "DO_IIC".
;
status_OK_              EQU     0         ;end of session and/or bus available
status_arb_lost_        EQU     1                            ;arbitration lost
status_attempt_data_    EQU     2;'max_data_attempts_' failed to get/send data
status_attempt_adrs_    EQU     3   ;'max_adrs_attempts_' failed to find slave
status_timeout_         EQU     4         ;"DO_IIC" detected timeout problem
status_buss_err_        EQU     5           ;a bus error or illegal start/stop
status_bad_read_space_  EQU     6       ;command file target for read was CODE
status_DO_IIC_          EQU     0FH    ;all running fine (bus busy) indication

status_master_             EQU     00H            ;master receiver/transmitter
status_slave_              EQU     10H       ;addressed as slave (own address)
status_arb_lost_slave_r_   EQU     20H   ;arbitration lost, addressed as slave
status_arb_lost_slave_w_   EQU     30H   ;arbitration lost, addressed as slave
status_general_slave_      EQU     40H      ;addressed as slave (general call)
status_arb_lost_general_   EQU     50H         ;arbitration lost, general call

status_type1_mask_      EQU     0FH              ;mask to isolate lower nibble
status_upper_mask_      EQU    0F0H    ;mask to isolate upper nibble of status
;
;IIC control characters.
;These characters are used in the IIC command file and various routines.
;'iic_end_' must be the last character in any command file sequence.
;'iic_write_mask_' and 'iic_read_mask_' are used in conjunction with the slave
;                    address to indicate whether data is a comin' or a goin'.
;'max_data_attempts_' should be equated to a value indicating how many times
;                    this system should re-try to get data from/to a slave
;                    before it gives up and says an error has occured.
;'max_adrs_attempts_' should be equated to a value indicating how many times
;                    this system should re-try to address a slave
;                    before it gives up and says an error has occured.
;'max_wait_' is used in a crude loop counting timer in "DO_IIC".  This number
;           should be equated to give roughly the timeout time required by
;           your system (i.e. IIC inactivity timeout).  The count will depend
;           on the clock speed as well as the average loop time in "DO_IIC".
;           The loop time will be affected by the IIC interrupt processing as
;           well as any other interrupt service routines in your system.
;'use_aux_adrs_' is used in place of the slave address (the first byte in the
;               command file block) so that the system will get the slave
;               address from the 'aux_adrs' register.  The routine that loads
;               'aux_adrs' must ensure the read/write bit is set correctly
;              (by ORing the 'aux_adrs' with 'iic_write_mask_' or 'iic_read_mask_').
;               This option excludes the slave address 0FEH from being used
;               directly, but if it is required, the user must use the 'use_
;               aux_adrs' option and load 0FEH into 'aux_adrs'.
;
iic_end_                EQU             0FFH          ;end of IIC command file
use_aux_adrs_           EQU             0FEH  ;use 'aux_adrs' as slave address
iic_write_mask_         EQU             00H
iic_read_mask_          EQU             01H
max_data_attempts_      EQU             3      ;maximum tries to get/send data
max_adrs_attempts_      EQU             3      ;maximum tries to address slave
max_wait_               EQU             1        ;reload value for 'iic_timer'
                                                                  ;(counts up)
;
;'S1STA' relaod values.  Virtually the same as old '552 app. note.
;
ENS1_NOTSTA_STO_NOTSI_NOTAA_CR0              EQU        0D1H
ENS1_NOTSTA_STO_NOTSI_AA_CR0                 EQU        0D5H
ENS1_NOTSTA_NOTSTO_NOTSI_AA_CR0              EQU        0C5H
ENS1_NOTSTA_NOTSTO_NOTSI_NOTAA_CR0           EQU        0C1H
ENS1_STA_NOTSTO_NOTSI_AA_CR0                 EQU        0E5H

;
;IIC hardware interrupt vector definition.

CSEG    AT      002BH
        JMP     IIC_VECTOR                   ;IIC_OS2 interrupt service routine
;
CSEG
;
;============================================================================
;"DO_IIC"
;==========
;The calling routine has loaded the DPTR register with the
;address of the command file to be executed.
;This routine simply waits for the IIC process to be completed.  Completion
;of the IIC session is indicated by 'IIC_status'= 'status_OK_', or one of the
;many error codes. "IIC_VECTOR" will take care of updating the status byte.
;
;It is possible that another master has addressed this master as a slave. If
;"DO_IIC" is called under these circumstances, it will exit with
;'IIC_failure' set and also check for a timeout for the addressed slave
;session. If a timeout is detected , all IIC_OS2 registers and bits are set to
;their default value.  In either case the 'IIC_failure' bit is set.
;
;In the addressed slave mode, the calling master determines bus timing and
;clock values etc.  If something happens to that master, and it cannot
;complete it's session, then this slave is left hanging!  For this reason, we
;we have a built-in timeout check feature for addressed slave mode (if and
;when this slave calls "DO_IIC" to do it's own work).
;
;'IIC_final_status' is a copy of the 'IIC_status' register.  It is used
;because the 'IIC_status' can be set as 'status_arb_lost_slave_'  which
;indicates an arbitration lost, addressed as slave condition - when this
;occurs, the very next interrupt into "IIC_VECTOR" may change 'IIC_status',
;thus the calling routine will cannot determine what happened (thus it can
;check the 'IIC_final_status').
;
;INPUT:
;======
;'IIC_status' is checked to ensure an addressed slave state is not in progress
;DPTR loaded with address of the command file to execute.
;OUTPUT:
;=======
;'IIC_status' is updated to reflect completion of IIC session or error.
;'IIC_final_status' holds a copy of 'IIC_status'.
;'IIC_failure' is updated (0 = all OK, 1 = some kind of error).
;============================================================================
;
DO_IIC:
        JNB     i_am_a_slave,DO_10
        ;
        ;if a slave receive or transmit session is in effect (as initiated by
        ;another master), this processor will only know that through the
        ;"IIC_VECTOR" routine - there is no timeout check etc.  Because of
        ;this situation, "DO_IIC" will check for a slave session in
        ;progress and exit as a failure if all is OK with that session (so
        ;that the calling routine will keep trying to get hold of the bus).
        ;If the slave session has timed out or there is an error, clear
        ;everything and exit as an error as well.
        ;
DO_05:
        CALL    IIC_time                        ;addressed slave timeout check
        JNZ     DO_35                               ;if not, exit as a failure
DO_06:
        CLR     i_am_a_slave                ;if timeout, reset system and exit
        SJMP    DO_ERR                                           ;as a failure
        ;
        ;ready to try - this micro is not presently addressed as a slave, and
        ;all else seems to be OK.
        ;
DO_10:
        MOV     IIC_Command_File_adrs,DPL
        MOV     IIC_Command_File_adrs + 1,DPH
        MOV     IIC_status,#status_DO_IIC_                  ;indicate IIC busy
        SETB    STA               ;do an IIC interrupt (start start condition)
DO_15:
        MOV     iic_timer,#LOW(max_wait_)                 ;start timeout timer
        MOV     iic_timer + 1,#HIGH(max_wait_)
DO_20:
        CALL    IIC_time
        JZ      DO_ERR
        ;
        ;as long as 'iic_timer' is OK, loop here and check the 'IIC_status'.
        ;'IIC_status' will remain as 'status_DO_IIC_' as long as the IIC
        ;session is still on.  This byte will be loaded with 'status_OK_' if
        ;the session ends normally, or it will be loaded with some other
        ;status byte if an error or arbitration process occurs.
        ;
        ;If this micro has been addressed as a slave, or has lost arbitration
        ;and become a slave, then 'IIC_status' indicates the situation, and
        ;this subroutine is terminated.  The routine that calls this one must
        ;check the 'IIC_status' to determine if another master has won the bus
        ;so that it can wait for 'IIC_status' to become 'status_OK_', at which
        ;point, it could try again.
        ;
DO_25:
        MOV     A,IIC_status                      ;when = status_OK_, all done
        CJNE    A,#status_DO_IIC_,DO_30
        SJMP    DO_20

⌨️ 快捷键说明

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