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

📄 i2c.asm

📁 一个用汇编写的I2C通信程序
💻 ASM
字号:
;I2C  读写程序
;BYTE WRITR AND  RANDOM READ (字节写,任意读)
;用来写一个指定的数据到一个指定的地址,或用来读一个指定的地址的数据。
;晶振4MHZ,HT46R47


       
#include ht46r47.inc

 	  
data  .section  'data'               
  
  WORD_ADDRESS         EQU         [071H]          ;写入或读出数据的存储器地址
  WRITE_IN             EQU         [072H]          ;写入存储中的数据暂存器
  READ_OUT             EQU         [073H]          ;读出存储器中的数据暂存器
  DATA_8               EQU         [074H]          ;移位用临时变量
  COUNT1               EQU         [075H]          ;定时用临时变量
  COUNT2               EQU         [076H]          ;定时用临时变量

TIME_6US    MACRO             ;宏延迟6US,
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
ENDM
   
;-----------------------------------------------
code  .section  at 0  'code'

  SCL                   EQU         PA.0             ;存储器CLK
  SCL_C                 EQU         PAC.0
  SDA                   EQU         PB.3             ;存储器DATA
  SDA_C                 EQU         PBC.3           
       
        org	   00h
        nop
        nop
        nop
        jmp    star 	
	    
        org    04h                 ;外部中断
        RETI
    
        org    08h                
        reti                       ;定时/计数中断

        ORG    0CH
        RETI                       ;AD中断
 
star:            
        clr    intc                ;清除中断控制寄存器       
        clr    tmrc                ;清除定时/计数控制寄存器
        clr    tmr                 ;清除定时/计数器        
        CLR    STATUS
        clr    pac                 ;将PA口设为输出,防止输入悬空
        clr    pbc                 ;将PB口设为输出,防止输入悬空
        clr    pdc                 ;将PD口设为输出,防止输入悬空
        clr    pa                  ;将PA口设为L,
        clr    pb                  ;将PB口设为L
        CLR    PD

MAIN:       
        MOV    A,02EH
        MOV    WRITE_IN,A          ;要写入的数据
        MOV    A,001H
        MOV    WORD_ADDRESS,A      ;要将数据存入的地址位置,或要从那地址读数据
        CALL   WRITE_ROM
        CALL   READ_ROM
        nop
        MOV    A,READ_OUT          ;检验写数据是否正确
        NOP
        JMP MAIN
         


;--------------------------------------------------------------------------
WRITE_ROM:
;写ROM;    
;MOV    A,001H
;MOV    WRITE_IN,A        ;要写入的数据    
;MOV    A,001H            
;MOV    WORD_ADDRESS,A    ;要把数据写在ROM的什么位置  
;START......ACK......写地址......ACK......写数据......ACK......STOP (5MS--24LC02B)写数据时间
;START......ACK......写地址......ACK......写数据1......ACK......写数据2......STOP (5MS--24LC02B)写数据时间            

            CLR    SDA_C         ;设SDA为输出
            CLR    SCL_C         ;设SCL为输出

            SET   SDA
            SET   SCL            
            TIME_6US
            CLR   SDA            ;START
            TIME_6US
        
            CLR    SCL
            SET    SDA            ;1
            TIME_6US
            SET    SCL        
            TIME_6US    
            
            CLR    SCL
            CLR    SDA            ;0
            TIME_6US              
            SET    SCL
            TIME_6US
     
            CLR    SCL   
            SET    SDA            ;1
            TIME_6US
            SET    SCL
            TIME_6US
            
            CLR    SCL
            CLR    SDA            ;0
            TIME_6US             
            SET    SCL
            TIME_6US
           
            CLR    SCL
            CLR    SDA            ;A2=0
            TIME_6US              ;为零时可不用
            SET    SCL
            TIME_6US

            CLR    SCL
            CLR    SDA            ;A1=0
            TIME_6US              ;为零时可不用
            SET    SCL
            TIME_6US
          
            CLR    SCL
            CLR    SDA            ;A0=0
            TIME_6US              ;为零时可不用
            SET    SCL
            TIME_6US
   
            CLR    SCL
            CLR    SDA            ;0 写模式
            TIME_6US              ;可不用
            SET    SCL
            TIME_6US
            
            CLR    SCL             
            SET    SDA_C           ;设IC地址ACK       ;设SDA为输入模式     ;之前地址对会自动为零,若不对会马上为高,后面程序执行不下去               
            SET    SCL            
                            
 IC_ADDRESS_ACK:                   ;等待应答信号,确认IC地址是否正确   ;判断地址对不对,对-过关,不对-死机
            SZ     SDA                 
            JMP    IC_ADDRESS_ACK
            CLR    SCL              ; 此语句之后,SDA会很快的自动产生一个上升沿          
            CLR    SDA_C            ;设输出为L  SDA产生下降沿
            MOV    A,08H            ;设传输数据长度
            MOV    DATA_8,A 
 
  WRITE_ADDRESS_IN:                 ;输入写入地址   ;写地址
            CLR    SDA
            SZ     WORD_ADDRESS.7
            SET    SDA
            TIME_6US
            SET    SCL
            TIME_6US         
            CLR    SCL  
            RL     WORD_ADDRESS
            SDZ    DATA_8
            JMP    WRITE_ADDRESS_IN
   
            SET    SDA_C             ;设写地址ACK ;设SDA为输入模式
            SET    SCL 

  WRITE_ADDRESS_ACK:                 ;确认写地址是否正确;等待应答信号
            SZ     SDA
            JMP    WRITE_ADDRESS_ACK
            CLR    SCL
            CLR    SDA_C           ;设输出为L
            MOV    A,08H           ;设传输数据长度
            MOV    DATA_8,A
       
  WRITE_DATA_IN:                   ;写数据
           CLR     SDA
           SZ      WRITE_IN.7
           SET     SDA
           TIME_6US
           SET     SCL
           TIME_6US
        
           CLR    SCL
           RL     WRITE_IN
           SDZ    DATA_8
           JMP    WRITE_DATA_IN

           SET    SDA_C            ;设写数据ACK   ;设SDA为输入模式
           SET    SCL 

 WRITE_DATA_ACK:                   ;确认写数据是否正确;等待应答信号
           SZ     SDA
           JMP    WRITE_DATA_ACK
                      
           CLR    SCL  
           CLR    SDA_C    
           CLR    SDA
           SET     SCL	      
	       TIME_6US		
	       SET     SDA		     ;STOP
	       TIME_6US		

           CLR    SCL           ;为了结束置低
           CLR    SDA           ;为了结束置低

 ;DELAY5MS:                     ;为了给写足够的时间,24LC02B=5MS  ;延时 (2*R2+3)*R1+2=(2*27+3)*98+2=6000us 约6ms
           mov    a,27             
           mov    count1,a         
   ROM_D1:
           mov    a,98            
           mov    count2,a        
   ROM_D2:
          sdz    count2
          jmp    ROM_D2
          sdz    count1
          jmp    ROM_D1      
          RET
;---------------------------------------------------------
READ_ROM:
;读ROM                
;MOV    A,001H            
;MOV    WORD_ADDRESS,A   ;读地址 
; START...IC认证...ACK...写地址......ACK...START...IC认证...ACK...读数据......STOP

            CLR    SDA_C         ;设SDA为输出
            CLR    SCL_C         ;设SCL为输出

            SET   SDA
            SET   SCL            
            TIME_6US
            CLR   SDA            ;START
            TIME_6US
        
            CLR    SCL
            SET    SDA            ;1
            TIME_6US
            SET    SCL        
            TIME_6US    
            
            CLR    SCL
            CLR    SDA            ;0
            TIME_6US              ;可不用(24AA02工作在2.5V以下时要用)以下同
            SET    SCL
            TIME_6US
     
            CLR    SCL   
            SET    SDA            ;1
            TIME_6US
            SET    SCL
            TIME_6US
            
            CLR    SCL
            CLR    SDA            ;0
            TIME_6US              ;可不用
            SET    SCL
            TIME_6US
           
            CLR    SCL
          ; CLR    SDA            ;A2=0  ;可以不用,已经为L
            TIME_6US                    ;可不用
            SET    SCL
            TIME_6US

            CLR    SCL
          ; CLR    SDA            ;A1=0
            TIME_6US                     ;可不用
            SET    SCL
            TIME_6US
          
            CLR    SCL
          ; CLR    SDA            ;A0=0
            TIME_6US                      ;可不用
            SET    SCL
            TIME_6US
   
            CLR    SCL
            CLR    SDA            ;0 写模式
            TIME_6US              ;可不用
            SET    SCL
            TIME_6US
            
            CLR    SCL         
            SET    SDA_C           ;设IC地址ACK ;设SDA为输入模式
            ;TIME_6US                  
            SET    SCL
            ;TIME_6US                   
  
 R_IC_ACK:                        ;等待ACK应答信号,确认IC地址是否正确 
            SZ     SDA
            JMP    R_IC_ACK
            CLR    SCL

            CLR    SDA_C           ;设输出为L
            MOV    A,08H           ;设传输数据长度
            MOV    DATA_8,A
 
 READ_ADDRESS_IN:                 ;读入地址   ;读地址
            CLR    SDA
            SZ     WORD_ADDRESS.7
            SET    SDA
            TIME_6US
            SET    SCL
            TIME_6US
            CLR    SCL
            RL     WORD_ADDRESS
            SDZ    DATA_8
            JMP    READ_ADDRESS_IN

            SET    SDA_C          ;设输入
            SET    SCL
          
 R_ADDRESS_ACK: 
            SZ    SDA            ;等待ACK应答信号,确认读地址是否正确         SZ     SDA
            JMP    R_ADDRESS_ACK

            CLR    SCL        
            CLR    SDA_C         ;设SDA为输出                  

REREADROM:
           SET    SDA
           SET    SCL
           TIME_6US
           CLR    SDA             ;START
           TIME_6US
                      
           CLR    SCL
           SET    SDA             ;1
           TIME_6US
           SET    SCL
           TIME_6US
 
           CLR    SCL
           CLR    SDA             ;0
           TIME_6US               ;可不用
           SET    SCL        
           TIME_6US

           CLR    SCL
           SET    SDA             ;1
           TIME_6US
           SET    SCL
           TIME_6US

           CLR    SCL
           CLR    SDA              ;0
           TIME_6US                ;可不用
           SET    SCL        
           TIME_6US

           CLR    SCL
           ;CLR    SDA             ;A2=0
           TIME_6US                ;可不用
           SET    SCL        
           TIME_6US

           CLR    SCL
           ;CLR    SDA             ;A1=0
           TIME_6US                ;可不用
           SET    SCL        
           TIME_6US

           CLR    SCL
           ;CLR    SDA             ;A0=0
           TIME_6US                ;可不用
           SET    SCL        
           TIME_6US

           CLR    SCL
           SET    SDA              ;1 读模式
           TIME_6US
           SET    SCL        
           TIME_6US

           CLR    SCL
           SET    SDA_C            ;设IC地址ACK  ;设SDA为输入模式       
           SET    SCL
    
 RE_IC_ACK:                
           SZ     SDA              ;等待ACK应答信号,确认IC地址是否正确 
           JMP    RE_IC_ACK
           MOV    A,08H
           MOV    DATA_8,A
           
 RE_DATA_OUT:                      ;读数据输出
           CLR    SCL
           TIME_6US
           CLR    READ_OUT.7
           SZ     SDA
           SET    READ_OUT.7
           TIME_6US
           SET    SCL
           TIME_6US
           RL     READ_OUT
           SDZ    DATA_8
           JMP    RE_DATA_OUT 

           CLR    SCL
           CLR    SDA_C          
           CLR    SDA
           SET     SCL	      
	       TIME_6US		
	       SET     SDA			    ;STOP
	       TIME_6US		       

           CLR    SCL               ;为了结束置低
           CLR    SDA               ;为了结束置低
           RET


;---------------------------------------


end


⌨️ 快捷键说明

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