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

📄 i2cbus.asm

📁 PIC单片机的汇编源码合集,应用比较广泛,设计程序时可做子程序来用
💻 ASM
字号:

FLAG    EQU     RLT             ; I2C状态标志寄存器
ERCODE  EQU     RLTH            ; 错误码备份
TXBUF   EQU     SOU             ; 发送数据缓冲器
RXBUF   EQU     SOUH            ; 接收数据缓冲器
BCOUNT  EQU     CNT             ; 位计数
;
TIMER0  EQU     18              ; Delay timer0
TIMER1  EQU     19              ; Delay timer1


; FLAG Bits

ERR     EQU     0               ; 出错标志
DI      EQU     1               ; 输入位缓存
DO      EQU     2               ; 输出位缓存
ACK     EQU     3               ; 应答位
;TXDONE  EQU     4               ; 发送结束标志
;RXDONE  EQU     5               ; 接受结束标志

ADDR    EQU     30H              ; EEPROM字地址
DATAI   EQU     31H              ; 存储器数据输入寄存器
DATAO   EQU     32H              ; 存储器数据输出寄存器
SLAVE   EQU     33H              ; Device address (1010xxx0)

        ;#DEFINE        SDA      PORTB,2     ; RB2, 数据输入输出
        ;#DEFINE        SCL      PORTB,1     ; RB1, 串行时钟
        #DEFINE        SDA      PORTC,4     ; RB2, 数据输入输出
        #DEFINE        SCL      PORTC,3     ; RB1, 串行时钟

 ;PAGE
;-----------------------------------------------------------------------------
;       I2C单片机通讯错误状态表以及子程序
;-----------------------------------------------------------------------------
;  input  :     W       = 错误码
;  output :     ERCODE  = 错误码
;           FLAG[ERR] = 1
;
;         错误码          错误类型
;       -------         ------------------------------------------------------
;           1   :       SCL 被从器件拉低 (总线忙)
;           2   :       SDA 被从器件拉低 (总线忙)
;           3   :       没有收到从器件的应答 (没有握手信号)
;           4   :       SDA 线没有释放,以至主控器件无法产生结束位
;-----------------------------------------------------------------------------
;根据错误状态表检测SCL和SDA的电平。代码用在总线裁决上。

ERRCODE
	BTFSS   FLAG,ERR      ; 是否保留上次的错误码
	MOVWF   ERCODE          ; 保存错误码
	BSF     FLAG,ERR      ; 设置出错标志
	RETLW   0

;-----------------------------------------------------------------------------
;       开始总线通讯程序
;-----------------------------------------------------------------------------
;产生启动位 (SCL高电平期间,SDA出现下降沿),并检查时钟信号线状态.

BSTART	BSF     SDA             ; SDA为保持为高
	BSF     SCL             ; 设置SCL为高电平
        BSF     STATUS,RP0
        MOVLW   B'00111111'     ; 设置 SCL, SDA 为输出
	MOVWF   TRISB	
        BCF     TRISC,3 ;
        BCF     TRISC,4 ;
        BCF     STATUS,RP0
	MOVLW   1               ; 准备出错状态码 1
	BTFSS   SCL             ; SCL被从器件锁定为低电平?
	CALL    ERR             ; 是
	BCF     SDA             ; 产生启动位
	NOP                     ; 时序调整
	NOP
	NOP
	NOP                     
	NOP
	NOP
	BCF     SCL             ; 开始时钟序列
	RETLW   0  
 ;PAGE

;-----------------------------------------------------------------------------
;       结束总线通信程序
;-----------------------------------------------------------------------------
;
;产生结束位 (SCL高电平期间,SDA从低电平到高电平)
;并检测总线状态

BSTOP	BCF     SDA       ; SDA=0
	BSF     SCL       ; SCL=1
        BSF     STATUS,RP0
        MOVLW   B'00111111'     ; SCL, SDA输出状态
	MOVWF   TRISB
        BCF     TRISC,3;
        BCF     TRISC,4;
        BCF     STATUS,RP0
	NOP
	NOP
	NOP
	MOVLW   1               ; 准备出错代码 1
	BTFSS   SCL             ; SCL高电平?
	CALL    ERR             ; 不是,则SCL被从器件锁定为低电平
	BSF     SDA             ; SDA 从低变高
	MOVLW   4               ; 准备出错代码 4
	BTFSS   SDA             ; 高电平?
	CALL    ERR             ; 不是,SDA没有被释放
	RETLW   0
;-----------------------------------------------------------------------------
;       移入1位数据子程序
;-----------------------------------------------------------------------------

BITIN
        BSF     SDA             ; SDA设为输入 
	BSF     STATUS,RP0
        BSF     TRISB,2
        BSF     TRISC,4;
	BCF     STATUS,RP0
	BSF     SCL             ; 时钟上升为高电平
	MOVLW   1
	BTFSC   SCL             ; 判断是否出错
	GOTO    BIT1
	BTFSS   FLAG,ERR      ; 保留上次的错误码
	MOVWF   ERCODE          ; 保存错误码
	BSF     FLAG,ERR      ; 设置错误标志
BIT1	BCF     FLAG,DI
        BTFSC   SDA             ; 读SDA
	BSF     FLAG,DI         
	NOP                     ; 延时
	BCF     SCL             ; 时钟返回低电平
	RETLW   0

 ;PAGE
;-----------------------------------------------------------------------------
;       移出1位数据子程序
;-----------------------------------------------------------------------------

BITOUT  BSF     STATUS,RP0
        BCF     TRISB,2       ;SDA设为输出
        BCF     TRISC,4
        BCF     STATUS,RP0 
	BTFSS   FLAG,DO
	GOTO    BIT0
	BSF     SDA             ; 输出1
	MOVLW   2
	BTFSC   SDA             ; 检测错误类型2
	GOTO    CLK1
	BTFSS   FLAG,ERR      ; 保留上次的错误码
	MOVWF   ERCODE          ; 保存错误码
	BSF     FLAG,ERR      ; 设置出错标志
	GOTO    CLK1            ; SDA被拉低
BIT0	BCF     SDA             ; 输出0
	NOP                     ; 延时
	NOP
	NOP
CLK1	BSF     SCL
	MOVLW   1               ; 错误码 1
	BTFSC   SCL             ; SCL被锁定为低电平?
	GOTO    BIT2            ; 不是
	BTFSS   FLAG,ERR      ; 是
	MOVWF   ERCODE          ; 保存错误码
	BSF     FLAG,ERR      ; 设定出错标志
BIT2
	NOP
	NOP
	BCF     SCL             ; SCL返回低电平
	RETLW   0
 ;PAGE

;-----------------------------------------------------------------------------
;       接收数据程序
;-----------------------------------------------------------------------------

I2CRX
	MOVLW   .8              ; 8 位数据
	MOVWF   BCOUNT
	CLRF    RXBUF
RXLP
	RLF     RXBUF,F         ; 数据移到缓冲器
	SKPC
	BCF     RXBUF,0         ; 进位位 ---> RXBUF[0]
	SKPNC
	BSF     RXBUF,0
	CALL    BITIN
	BTFSC   FLAG,DI
	BSF     RXBUF,0         ; 移入位 =1
	DECFSZ  BCOUNT,F        ; 8 位结束?
	GOTO    RXLP
        BCF     FLAG,DO
        BTFSC   FLAG,ACK
	BSF     FLAG,DO         ; 发送应答信号
	CALL    BITOUT          
	RETLW   0
;-----------------------------------------------------------------------------
;      发送数据程序
;-----------------------------------------------------------------------------
;       输入:       TXBUF
;       输出:       无
;-----------------------------------------------------------------------------
I2CTX
	MOVLW   .8
	MOVWF   BCOUNT
TXLP
	BCF     FLAG,DO         ; 移出数据.
	BTFSC   TXBUF,7         ; 
	BSF     FLAG,DO         ; 否则数据位 = 1
	CALL    BITOUT          ; 移出一位
	RLF     TXBUF,F         ; ITXBUF左移
	SKPC                    ; ITXBUF[6] ---> ITXBUF[7]
	BCF     TXBUF,0         ; ITXBUF[7] ---> 进位位
	SKPNC                   ; 进位位 ---> TXBUF[0]
	BSF     TXBUF,0
	DECFSZ  BCOUNT,F        ; 8位移完?
	GOTO    TXLP            ; 没有
	CALL    BITIN           ; 接收应答位
	MOVLW   3
	BTFSC   FLAG,DI         ; 检测有无应答
	CALL    ERRCODE         ; 没有应答
	RETLW   0
 ;PAGE

;-----------------------------------------------------------------------------
;       BYTE-WRITE, write one byte to EEPROM device
;-----------------------------------------------------------------------------
;       Input   :       DATAO= data to be written
;                       ADDR    = destination address
;                       SLAVE   = device address (1010xxx0)
;       Output  :       Data written to EEPROM device
;-----------------------------------------------------------------------------
;
;	     080             ; The location for BYTE-WRITE routine can be
;                               ; assigned anywhere between (377-777) octal.
WPORTBYTE
	MOVLW   10100000B       ; Get SLAVE address
	MOVWF   TXBUF           ; to TX buffer
	CALL    BSTART          ; Generate START bit
	CALL    I2CTX           ; Output SLAVE address
	MOVF    ADDR,W          ; Get WORD address
	MOVWF   TXBUF           ; into buffer
	CALL    I2CTX           ; Output WORD address
	MOVF    DATAO,W         ; Move DATA 
	MOVWF   TXBUF           ; into buffer
	CALL    I2CTX           ; Output DATA and detect acknowledgement
	CALL    BSTOP           ; Generate STOP bit
	GOTO    $
;
;
;
;-----------------------------------------------------------------------------
;       BYTE-READ, read one byte from serial EEPROM device
;-----------------------------------------------------------------------------
;       Input   :       ADDR    = source address
;                       SLAVE   = device address (1010xxx0)
;       Output  :       DATAI   = data read from serial EEPROM
;-----------------------------------------------------------------------------
;
;	ORG     0C0             ; The location for BYTE-READ routine can be
;                               ; assigned anywhere between (377-777) octal.
RDBYTE
	MOVLW   10100000B       ; Move SLAVE address 
	MOVWF   TXBUF           ; into buffer (R/W = 0)
	CALL    BSTART          ; Generate START bit
	CALL    I2CTX              ; Output SLAVE address. Check ACK.
	MOVF    ADDR,W          ; Get WORD address
	MOVWF   TXBUF
	CALL    I2CTX              ; Output WORD address. Check ACK.
	CALL    BSTART          ; START READ (if only one device is
	MOVLW    10100001B      ; connected to the I2C bus)
	MOVWF   TXBUF
	BSF     TXBUF,0         ; Specify READ mode (R/W = 1)
	CALL    I2CTX              ; Output SLAVE address
	CALL    I2CRX              ; READ in data and acknowledge
	CALL    BSTOP           ; Generate STOP bit
	MOVF    RXBUF,W         ; Save data from buffer
	MOVWF   DATAI           ; to DATAI file.
	goto    $

⌨️ 快捷键说明

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