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

📄 smb.asm

📁 用c8051f系列单片机的SMBus功能实现串行通信。
💻 ASM
📖 第 1 页 / 共 2 页
字号:
   setb  STA                          ; Initiate Transfer

   jb    SM_BUSY, $                   ; Wait for receive to finish
   pop   ACC                          ; Restore accumulator

   ret

;---------------------------------------------------------------------------------------
; SMBus_Init
; SMbus initialization routine
;

; - Configures and enables the SMBus.
; - Sets SMBus clock rate.
; - Enables SMBus interrupt.
; - Clears SM_Busy flag for first transfer.


SMBus_Init:

   mov   SMB0CN, #04h                 ; Configure SMBus to send ACKs on acknowledge cycle
   mov   SMB0CR, #0B0h                ; SMBus clock rate = 100KHz, per SMB0CR equation:
                                      ; SMB0CR = -(SYSCLK)/(2*Fscl)

   orl   SMB0CN, #40h                 ; Enable SMBus

   orl   EIE1, #02h                   ; Enable SMBus interrupts
   clr   SM_BUSY

   ret
   
;--------------------------------------------------------------------------------------
; INTERRUPT VECTORS
;--------------------------------------------------------------------------------------

;--------------------------------------------------------------------------------------
; SMBus ISR
;
; Implemented as a state table lookup, with the SMBus status register as the index.
; SMBus status codes are multiples of 8; thus the status code can be used to index
; program segments that are spaced by 8 bytes. Each 'org' command indicates
; a new state, offset from the beginning of the table by its status code value.
; 
; Note that only 8 bytes are available to process each state.  In the cases where
; more than 8 bytes are necessary, the code jumps to a program location outside
; of the state table. This is only necessary in the state 'SMB_MTDBACK'.

SMBus_ISR:

   push   PSW                         ;
   push   ACC                         ;
   push   DPH                         ; Resource preservation
   push   DPL                         ;
   push   ACC                         ;

   mov   A, SMB0STA                   ; Load accumulator with current SMBus state.
                                      ; State corresponds to the address offset
                                      ; for each state execution

   anl   A, #7Fh                      ; Mask out upper bit, since any states that
                                      ; set this bit are not defined in this code.

   mov   DPTR, #SMB_STATE_TABLE       ; Point DPTR to the beginning of the state table
   jmp   @A+DPTR                      ; Jump to the current state

; SMBus State Table------------------------------------------------------------------------

SMB_STATE_TABLE:                  
   
   ; SMB_BUS_ERROR
   ; All Modes: Bus Error
   ; Reset hardware by setting STOP bit
   org    SMB_STATE_TABLE + SMB_BUS_ERROR
   
      setb  STO
      jmp   SMB_ISR_END               ; Jump to exit ISR

   ; SMB_START
   ; Master Transmitter/Receiver: START transmitted.
   ; The R/W bit will always be a zero (W) in this state because
   ; for both write and read, the memory address must first be written.
   org SMB_STATE_TABLE + SMB_START

      mov   SMB0DAT, WRI_ADD          ; Load slave address + W
      clr   STA                       ; Manually clear START bit
      jmp   SMB_ISR_END               ; Jump to exit ISR

   ; SMB_RP_START
   ; Master Transmitter/Receiver: Repeated START transmitted.
   ; This state should only occur during a read, after the memory 
   ; address has been sent and acknowledged.
   org    SMB_STATE_TABLE + SMB_RP_START

      mov   SMB0DAT, READ_ADD         ; Load slave address + R
      clr   STA                       ; Manually clear START bit
      jmp   SMB_ISR_END

   ; SMB_MTADDACK
   ; Master Transmitter: Slave address + WRITE transmitted.
   ; ACK received
   org   SMB_STATE_TABLE + SMB_MTADDACK

      mov   SMB0DAT, MEM_ADD          ; Load memory address   
      setb  BYTE_SENT                 ; BYTE_SENT=1: In the next ISR call,
                                      ; the memory address will have just been
                                      ; sent.                        
      jmp   SMB_ISR_END

   ; SMB_MTADDNACK
   ; Master Transmitter: Slave address + WRITE transmitted. 
   ; NACK received. The slave is not responding. Try again with
   ; acknowledge polling. Send STOP + START.
   org SMB_STATE_TABLE + SMB_MTADDNACK

      setb  STO                              
      setb  STA
      jmp   SMB_ISR_END

   ; SMB_MTDBACK
   ; Master Transmitter: Data byte transmitted. ACK received.
   ; This state is used in both read and write operations.
   ; Check BYTE_SENT; if 1, memory address has just been sent. Else,
   ; data has been sent.
   org    SMB_STATE_TABLE + SMB_MTDBACK
   
      jbc   BYTE_SENT, ADDRESS_SENT    ; If BYTE_SENT=1, clear bit and
                                       ; jump to ADDRESS_SENT to process
                                       ; outside of state table.
                                          
                                    
      jmp   DATA_SENT                  ; If BYTE_SENT=0, data has just been sent, 
                                       ; transfer is finished.
                                       ; jump to end transfer
   
   ; SMB_MTDBNACK
   ; Master Transmitter: Data byte transmitted.  NACK received.
   ; Slave not responding.  Send STOP followed by START to try again.
   org SMB_STATE_TABLE + SMB_MTDBNACK

      setb  STO
      setb  STA
      jmp   SMB_ISR_END

   ; SMB_MTARBLOST
   ; Master Transmitter: Arbitration Lost.
   ; Should not occur.  If so, restart transfer.
   org SMB_STATE_TABLE + SMB_MTARBLOST

      setb  STO
      setb  STA
      jmp   SMB_ISR_END

   ; SMB_MRADDACK
   ; Master Receiver: Slave address + READ transmitted. ACK received.
   ; Set to transmit NACK after next transfer since it will be the
   ; last (only) byte.
   org SMB_STATE_TABLE + SMB_MRADDACK

      clr   AA                       ; NACK sent on acknowledge cycle
      jmp   SMB_ISR_END

   ; SMB_MRADDNACK
   ; Master Receiver: Slave address + READ transmitted. NACK received.
   ; Slave not responding. Send repeated START to try again.
   org SMB_STATE_TABLE + SMB_MRADDNACK
      
      clr   STO
      setb  STA
      jmp   SMB_ISR_END

   ; SMB_MRDBACK
   ; Master Receiver: Data byte received. ACK transmitted.
   ; Should not occur because AA is cleared in previous state.
   ; Send STOP if state does occur.
   org SMB_STATE_TABLE + SMB_MRDBACK

      setb  STO
      jmp   SMB_ISR_END

   ; SMB_MRDBNACK
   ; Master Receiver: Data byte received. NACK transmitted.
   ; Read operation completed. Read data register and send STOP
   org SMB_STATE_TABLE + SMB_MRDBNACK
   
      mov   RECEIVE_BYTE, SMB0DAT
      setb  STO
      setb  AA                       ; Set AA for next transfer
      clr   SM_BUSY   
      jmp   SMB_ISR_END

; End of State Table--------------------------------------------------------------

;---------------------------------------------------------------------------------
; Program segment to handle SMBus states that require more than 8 bytes of program
; space.

; Address byte has just been sent.  Check RW.  If R (1), jump to RW_READ.
; If W, load data to transmit into SMB0DAT.
ADDRESS_SENT:

   jb    RW, RW_READ
   mov   SMB0DAT, TRANSMIT_BYTE      ; Load data
   jmp   SMB_ISR_END                 ; Jump to exit ISR

; Operation is a READ, and the address byte has just been sent.  Send
; repeated START to initiate memory read.
RW_READ:
   
   clr   STO
   setb  STA                         ; Send repeated START
   jmp   SMB_ISR_END                 ; Jump to exit ISR

; Operation is a WRITE, and the data byte has just been sent.  Transfer
; is finished.  Send STOP, free the bus, and exit the ISR.
DATA_SENT:

   setb  STO                         ; Send STOP and exit ISR.
   clr   SM_BUSY                     ; Free SMBus
   jmp   SMB_ISR_END                 ; Jump to exit ISR   
;---------------------------------------------------------------------------------

; SMBus ISR exit. 
; Restore registers, clear SI bit, and return from interrupt.   
SMB_ISR_END:

   clr   SI
   pop   ACC
   pop   DPL
   pop   DPH
   pop   ACC
   pop   PSW

   reti

END




   
         
      

⌨️ 快捷键说明

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