📄 iic_os2.asm
字号:
;'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 + -