TITLE " TWO WIRE/I2C BUS INTERFACE WITH PIC16C5x "
;
LIST P=16C54
;
;************************************************************
;** Two wire/I2C Bus READ/WRITE Sample Routines of Microchip's
;** 24Cxx / 85Cxx serial CMOS EEPROM interfacing to a
;** PIC16C54 8-bit CMOS single chip microcomputer
;** Revsied Version 2.0 (4/2/92).
;**
;** Part use = PIC16C54-XT/JW
;** Note: 1) All timings are based on a reference crystal frequency of 2MHz
;** which is equivalent to an instruction cycle time of 2 usec.
;** 2) Address and literal values are read in octal unless otherwise
;** specified.
;********************************************************
;
;-----------------------------------------------------------------------------
; Files Assignment
;-----------------------------------------------------------------------------
;
PC EQU 2 ; Program counter
STAT EQU 3 ; PIC status byte
FSR EQU 4 ; File Select Register
RA EQU 5 ; Port A use to select device address
RB EQU 6 ; RB7 = SDA, RB6 = SCL
;
STATUS EQU 08 ; Status register
FLAG EQU 09 ; Common flag bits register
EEPROM EQU 0A ; Bit buffer
ERCODE EQU 0B ; Error code (to indicate bus status)
ADDR EQU 10 ; Address register
DATAI EQU 11 ; Stored data input register
DATAO EQU 12 ; Stored data output register
SLAVE EQU 13 ; Device address (1010xxx0)
TXBUF EQU 14 ; TX buffer
RXBUF EQU 15 ; RX buffer
COUNT EQU 16 ; Bit counter
;
TIMER0 EQU 18 ; Delay timer0
TIMER1 EQU 19 ; Delay timer1
;
;
;-----------------------------------------------------------------------------
; Bit Assignments
;-----------------------------------------------------------------------------
;
; Status bits
;
Z EQU 2
C EQU 0
;
; FLAG Bits
;
ERROR EQU 0 ; Error flag
;
; EEPROM Bits
;
DI EQU 7 ; EEPROM input
DO EQU 6 ; EEPROM output
;
; I2C Device Bits
;
SDA EQU 7 ; RB7, data in/out
SCL EQU 6 ; RB6, serial clock
;
;END FILES/BITS EQUATE
PAGE
;
;-----------------------------------------------------------------------------
; Two wire/I2C - CPU communication error status table and subroutine
;-----------------------------------------------------------------------------
; input : W-reg = error code
; output : ERCODE = error code
; FLAG(ERROR) = 1
;
; code error status mode
; ------- ------------------------------------------------------
; 1 : SCL locked low by device (bus is still busy)
; 2 : SDA locked low by device (bus is still busy)
; 3 : No acknowledge from device (no handshake)
; 4 : SDA bus not released for master to generate STOP bit
;-----------------------------------------------------------------------------
;
;Subroutine to identify the status of the serial clock (SCL) and serial data
;(SDA) condition according to the error status table. Codes generated are
;useful for bus/device diagnosis.
;
ERR
BTFSS FLAG,ERROR ; Remain as first error encountered
MOVWF ERCODE ; Save error code
BSF FLAG,ERROR ; Set error flag
RETLW 0
;
;-----------------------------------------------------------------------------
; START bus communication routine
;-----------------------------------------------------------------------------
; input : none
; output : initialize bus communication
;-----------------------------------------------------------------------------
;
;Generate START bit (SCL is high while SDA goes from high to low transition)
;and check status of the serial clock.
BSTART
MOVLW B'00111111' ; Put SCL, SDA line in output state
TRIS RB
;**************************************************************
bsf RB,SDA ;make sure sda is high
;*******************************************************
BSF RB,SCL ; Set clock high
MOVLW 1 ; Ready error status code 1
BTFSS RB,SCL ; Locked?
CALL ERR ; SCL locked low by device
BCF RB,SDA ; SDA goes low during SCL high
NOP ; Timing adjustment
NOP
NOP
BCF RB,SCL ; Start clock train
RETLW 0
;
;END SUB
PAGE
;
;-----------------------------------------------------------------------------
; STOP bus communication routine
;-----------------------------------------------------------------------------
; Input : None
; Output : Bus communication, STOP condition
;-----------------------------------------------------------------------------
;
;Generate STOP bit (SDA goes from low to high during SCL high state)
;and check bus conditions.
;
BSTOP
;*********************************************************
MOVLW B'00111111' ; Put SCL, SDA line in output state
TRIS RB
;**************************************************************
BCF RB,SDA ; Return SDA to low
BSF RB,SCL ; Set SCL high
nop
nop
nop
MOVLW 1 ; Ready error code 1
BTFSS RB,SCL ; High?
CALL ERR ; No, SCL locked low by device
BSF RB,SDA ; SDA goes from low to high during SCL high
MOVLW 4 ; Ready error code 4
BTFSS RB,SDA ; High?
CALL ERR ; No, SDA bus not release for STOP
RETLW 0
;
;END SUB
;
;-----------------------------------------------------------------------------
; Serial data send from PIC to serial EEPROM, bit-by-bit subroutine
;-----------------------------------------------------------------------------
; Input : None
; Output : To (DI) of serial EEPROM device
;-----------------------------------------------------------------------------
;
BITIN
MOVLW B'10111111' ; Force SDA line as input
TRIS RB
BSF RB,SDA ; Set SDA for input
BCF EEPROM,DI
BSF RB,SCL ; Clock high
MOVLW 1
BTFSC RB,SCL ; Skip if SCL is high
GOTO BIT1
BTFSS FLAG,ERROR ; Remain as first error encountered
MOVWF ERCODE ; Save error code
BSF FLAG,ERROR ; Set error flag
BIT1
BTFSC RB,SDA ; Read SDA pin
BSF EEPROM,DI ; DI = 1
NOP ; Delay
BCF RB,SCL ; Return SCL to low
RETLW 0
;
;END SUB
PAGE
;
;-----------------------------------------------------------------------------
; Serial data receive from serial EEPROM to PIC, bit-by-bit subroutine
;-----------------------------------------------------------------------------
; Input : EEPROM file
; Output : From (DO) of serial EEPROM device to PIC
;-----------------------------------------------------------------------------
;
BITOUT
MOVLW B'00111111' ; Set SDA, SCL as outputs
TRIS RB
BTFSS EEPROM,DO
GOTO BIT0
BSF RB,SDA ; Output bit 0
MOVLW 2
BTFSC RB,SDA ; Check for error code 2
GOTO CLK1
BTFSS FLAG,ERROR ; Remain as first error encountered
MOVWF ERCODE ; Save error code
BSF FLAG,ERROR ; Set error flag
GOTO CLK1 ; SDA locked low by device
;
BIT0
BCF RB,SDA ; Output bit 0
NOP ; Delay
NOP
NOP
CLK1
BSF RB,SCL
MOVLW 1 ; Error code 1
BTFSC RB,SCL ; SCL locked low?
GOTO BIT2 ; No.
BTFSS FLAG,ERROR ; Yes.
MOVWF ERCODE ; Save error code
BSF FLAG,ERROR ; Set error flag
BIT2
NOP
NOP
BCF RB,SCL ; Return SCL to low
RETLW 0
;
;END SUB
PAGE
;
;
;-----------------------------------------------------------------------------
; RECEIVE DATA subroutine
;-----------------------------------------------------------------------------
; Input : None
; Output : RXBUF = Receive 8-bit data
;-----------------------------------------------------------------------------
;
RX
MOVLW .8 ; 8 bits of data
MOVWF COUNT
CLRF RXBUF
;
RXLP
RLF RXBUF ; Shift data to buffer
SKPC
BCF RXBUF,0 ; carry ---> f(0)
SKPNC
BSF RXBUF,0
CALL BITIN
BTFSC EEPROM,DI
BSF RXBUF,0 ; Input bit =1
DECFSZ COUNT ; 8 bits?
GOTO RXLP
BSF EEPROM,DO ; Set acknowledge bit = 1
CALL BITOUT ; to STOP further input
RETLW 0
;
;END SUB
;
;-----------------------------------------------------------------------------
; TRANSMIT DATA subroutine
;-----------------------------------------------------------------------------
; Input : TXBUF
; Output : Data X'mitted to EEPROM device
;-----------------------------------------------------------------------------
;
TX
MOVLW .8
MOVWF COUNT
;
TXLP
BCF EEPROM,DO ; Shift data bit out.
BTFSC TXBUF,7 ; If shifted bit = 0, data bit = 0
BSF EEPROM,DO ; Otherwise data bit = 1
CALL BITOUT ; Serial data out
RLF TXBUF ; Rotate TXBUF left
SKPC ; f(6) ---> f(7)
BCF TXBUF,0 ; f(7) ---> carry
SKPNC ; carry ---> f(0)
BSF TXBUF,0
DECFSZ COUNT ; 8 bits done?
GOTO TXLP ; No.
CALL BITIN ; Read acknowledge bit
MOVLW 3
BTFSC EEPROM,DI ; Check for acknowledgement
CALL ERR ; No acknowledge from device
RETLW 0
;
;END SUB
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
;-----------------------------------------------------------------------------
;
ORG 080 ; The location for BYTE-WRITE routine can be
; ; assigned anywhere between (377-777) octal.
WRBYTE
MOVF SLAVE,W ; Get SLAVE address
MOVWF TXBUF ; to TX buffer
CALL BSTART ; Generate START bit
CALL TX ; Output SLAVE address
MOVF ADDR,W ; Get WORD address
MOVWF TXBUF ; into buffer
CALL TX ; Output WORD address
MOVF DATAO,W ; Move DATA
MOVWF TXBUF ; into buffer
CALL TX ; Output DATA and detect acknowledgement
CALL BSTOP ; Generate STOP bit
goto wrt_end
;
;
;
;-----------------------------------------------------------------------------
; 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
MOVF SLAVE,W ; Move SLAVE address
MOVWF TXBUF ; into buffer (R/W = 0)
CALL BSTART ; Generate START bit
CALL TX ; Output SLAVE address. Check ACK.
MOVF ADDR,W ; Get WORD address
MOVWF TXBUF
CALL TX ; Output WORD address. Check ACK.
CALL BSTART ; START READ (if only one device is
MOVF SLAVE,W ; connected to the I2C bus)
MOVWF TXBUF
BSF TXBUF,0 ; Specify READ mode (R/W = 1)
CALL TX ; Output SLAVE address
CALL RX ; READ in data and acknowledge
CALL BSTOP ; Generate STOP bit
MOVF RXBUF,W ; Save data from buffer
MOVWF DATAI ; to DATAI file.
goto rd_end
;
;Test program to read and write ramdom
start
movlw 0AE ;set A2=A1=A0=1
movwf SLAVE ; /
movlw 2 ;set r/w loc. = 2
movwf ADDR ; /
movlw 55 ;write 55 to SEEPROM
movwf DATAO ; /
goto WRBYTE ;write a byte
wrt_end
call delay ;wait for write
;operation (internal)
goto RDBYTE ;read back data
rd_end
movlw 55 ;test if read
xorwf DATAI,W ;correct?
btfss STAT,Z ;yes then skip
wrong
goto wrong
correct
goto correct
;
;At 2.0Mhz, delay = approx. 3mS.
delay
clrf 1F ;clear last location
dly1
nop
nop
nop
decfsz 1F ;reduce count
goto dly1 ;loop
retlw 0
;
org 0x1FF
goto start
;
END
PIC的一个读写I2C程序
- I2C(120546)
相关推荐
I2C Labview 解决方法
`各位大虾,帮忙解决一个问题,我有个芯片是CY8C3246芯片,有I2C接口,需要用Labview来读写内容,不知道大家是否有做过?或有相同的VI共享下.`
2012-12-13 16:13:01
I2C Master到Master通信可能吗?
嗨,我有一个项目,一个PIC24FJ256GB210是一个I2C主控器,一个PIC16F18326,一个I2C从机和一个I2C EEPROM。所以,在特殊情况下,必须有可能PIC16给PIC24一个
2018-12-27 16:04:05
I2C读写EEPROM写数据子程序调用时卡住了
_writeByte(addr);//写低位地址 while (!I2C_xrdy()); I2C_writeByte(data);//写数据 I2C_sendStop();delay(5000);]我用I2C读写EEPROM,写了个写数据子程序,调用时发现卡住了,位置见上面。请问高手,哪里有问题?谢谢!
2019-01-30 07:46:32
I2C读写与使用
这一届爽是真的爽,hal库和cubemx节省一半时间工作量23333终于学到I2C了,单片机的时候就没把I2C学好,现在来恶补,,,这个博主把为什么I2C读、写要先设置0xA1、0xA0讲得很到位
2022-01-11 07:12:02
I2C不工作
自己的代码。我就是不能让它工作。这是不可能的。这里是我的代码:对于I2C:主程序:我得到的是255。是的,我尝试了“0xA0”和“0xA1”作为EEPROM读写地址。如果你不能给我一个好的答案,请不要
2019-09-29 07:34:13
I2C不工作是MCC问题吗?
试图编写一个I2C驱动程序,我在另一个文件中工作,我刚刚移植了这些函数。PIC12LF1840的后端代码是使用MCC创建的。我试图建立与MMA845 2Q加速度计的COMS。我怀疑别针是断开的,但我
2018-12-20 16:17:26
I2C协议介绍
文章目录I2C 调查标准I2C协议介绍I2C时序介绍起始信号停止信号重启信号总线闲信号总线忙信号读写信号应答信号非应答信号标准I2C协议读写介绍I2C写一个寄存器I2C 读一个寄存器I2C 连续写
2022-01-20 08:04:17
I2C协议以及I2C读写EEPROM
I2C协议以及I2C读写EEPROM实验文章目录I2C协议以及I2C读写EEPROM实验I2C 协议简介一、I2C 物理层二、I2C 协议层2-1 I2C 基本读写过程2-2 通讯的起始和停止信号
2021-08-23 08:25:55
I2C协议的相关资料推荐
I2C协议总结两个方面物理层电气特性协议层I2C基本读写过程#写过程通讯复合格式通讯信号的判断通讯的起始和停止信号数据有效性地址及数据方向响应信号通讯过程部分代码讲解总结**顺便找一下玩过
2022-02-23 06:52:10
I2C只发送地址
你好,我想从我的PIC32 MZ中使用I2C作为主控器。我使用的是和声样本共现,我只看到第一个地址字节。我从来没有看到缓冲区的其余部分。有人以前有过这个问题吗?谢谢。 以上来自于百度翻译 以下
2018-10-15 16:19:21
I2C和输出比较或PPS有什么联系吗?
我的图片是:PIC32 MZ2048 EFM144。有了这个PIC我参加LCD(与DMA,定时器,输出比较),直到今天的一切工作,但我需要参加电容触摸面板通过I2C。我写代码的I2C和通信工作(X
2019-10-11 12:08:28
I2C在SLaveFio期间不工作
你好。我有一个问题,I2C在SLaveFio期间不工作。I2C的读写数据只工作SLaveFIFO工作结束。那么我怎么才能解决这个问题呢?
2019-08-29 10:13:39
评论