PIC的I2C讀寫程序
***************************************** PIC的I2C讀寫程序 *****************************************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.;;; Program: I2CBUS.ASM ; Revision Date: ; 12-12-95 Compatibility with MPASMWIN 1.30;;********************************************************************** ;;*****************************************************************************;;-----------------------------------------------------------------------------; Files Assignment;-----------------------------------------------------------------------------;PC EQU 2 ; Program counterSTAT EQU 3 ; PIC status byteFSR EQU 4 ; File Select RegisterRA EQU 5 ; Port A use to select device addressRB EQU 6 ; RB7 = SDA, RB6 = SCL;STATUS EQU 08 ; Status registerFLAG EQU 09 ; Common flag bits registerEEPROM EQU 0A ; Bit bufferERCODE EQU 0B ; Error code (to indicate bus status)ADDR EQU 10 ; Address registerDATAI EQU 11 ; Stored data input registerDATAO EQU 12 ; Stored data output registerSLAVE EQU 13 ; Device address (1010xxx0)TXBUF EQU 14 ; TX bufferRXBUF EQU 15 ; RX bufferCOUNT EQU 16 ; Bit counter;TIMER0 EQU 18 ; Delay timer0TIMER1 EQU 19 ; Delay timer1;;;-----------------------------------------------------------------------------; Bit Assignments;-----------------------------------------------------------------------------;; Status bits;Z EQU 2C EQU 0;; FLAG Bits;ERR1 EQU 0 ; Error flag;; Instruction Destination Bits;F EQU 1W EQU 0;; EEPROM Bits;DI EQU 7 ; EEPROM inputDO EQU 6 ; EEPROM output;; I2C Device Bits;SDA EQU 7 ; RB7, data in/outSCL EQU 6 ; RB6, serial clock;;END FILES/BITS EQUATEPAGE;;-----------------------------------------------------------------------------; Two wire/I2C - CPU communication error status table and subroutine;-----------------------------------------------------------------------------; input : W-reg = error code; output : ERCODE = error code; FLAG(ERR1) = 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.;ERRBTFSS FLAG,ERR1 ; Remain as first error encounteredMOVWF ERCODE ; Save error codeBSF FLAG,ERR1 ; Set error flagRETLW 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.BSTARTMOVLW B'00111111' ; Put SCL, SDA line in output stateTRIS RB;***************************************************************************bsf RB,SDA ;make sure sda is high;***************************************************************************BSF RB,SCL ; Set clock highMOVLW 1 ; Ready error status code 1BTFSS RB,SCL ; Locked?CALL ERR ; SCL locked low by deviceBCF RB,SDA ; SDA goes low during SCL highNOP ; Timing adjustmentNOPNOPBCF RB,SCL ; Start clock trainRETLW 0;;END SUBPAGE;;-----------------------------------------------------------------------------; 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 stateTRIS RB;****************************************************************************BCF RB,SDA ; Return SDA to lowBSF RB,SCL ; Set SCL highnopnopnopMOVLW 1 ; Ready error code 1BTFSS RB,SCL ; High?CALL ERR ; No, SCL locked low by deviceBSF RB,SDA ; SDA goes from low to high during SCL highMOVLW 4 ; Ready error code 4BTFSS RB,SDA ; High?CALL ERR ; No, SDA bus not release for STOPRETLW 0;;END SUB;;-----------------------------------------------------------------------------; Serial data send from PIC to serial EEPROM, bit-by-bit subroutine;-----------------------------------------------------------------------------; Input : None; Output : To (DI) of serial EEPROM device;-----------------------------------------------------------------------------;BITINMOVLW B'10111111' ; Force SDA line as inputTRIS RBBSF RB,SDA ; Set SDA for inputBCF EEPROM,DIBSF RB,SCL ; Clock highMOVLW 1BTFSC RB,SCL ; Skip if SCL is highGOTO BIT1BTFSS FLAG,ERR1 ; Remain as first error encounteredMOVWF ERCODE ; Save error codeBSF FLAG,ERR1 ; Set error flagBIT1BTFSC RB,SDA ; Read SDA pinBSF EEPROM,DI ; DI = 1NOP ; DelayBCF RB,SCL ; Return SCL to low RETLW 0;;END SUBPAGE;;-----------------------------------------------------------------------------; Serial data receive from serial EEPROM to PIC, bit-by-bit subroutine;-----------------------------------------------------------------------------; Input : EEPROM file; Output : From (DO) of serial EEPROM device to PIC;-----------------------------------------------------------------------------;BITOUTMOVLW B'00111111' ; Set SDA, SCL as outputsTRIS RBBTFSS EEPROM,DOGOTO BIT0BSF RB,SDA ; Output bit 0MOVLW 2BTFSC RB,SDA ; Check for error code 2GOTO CLK1BTFSS FLAG,ERR1 ; Remain as first error encounteredMOVWF ERCODE ; Save error codeBSF FLAG,ERR1 ; Set error flagGOTO CLK1 ; SDA locked low by device;BIT0BCF RB,SDA ; Output bit 0NOP ; DelayNOPNOPCLK1BSF RB,SCLMOVLW 1 ; Error code 1BTFSC RB,SCL ; SCL locked low?GOTO BIT2 ; No.BTFSS FLAG,ERR1 ; Yes.MOVWF ERCODE ; Save error codeBSF FLAG,ERR1 ; Set error flagBIT2NOPNOPBCF RB,SCL ; Return SCL to lowRETLW 0;;END SUBPAGE;;;-----------------------------------------------------------------------------; RECEIVE DATA subroutine;-----------------------------------------------------------------------------; Input : None; Output : RXBUF = Receive 8-bit data;-----------------------------------------------------------------------------;RXMOVLW .8 ; 8 bits of dataMOVWF COUNTCLRF RXBUF;RXLPRLF RXBUF, F ; Shift data to bufferSKPCBCF RXBUF,0 ; carry ---> f(0)SKPNCBSF RXBUF,0CALL BITINBTFSC EEPROM,DIBSF RXBUF,0 ; Input bit =1DECFSZ COUNT, F ; 8 bits?GOTO RXLPBSF EEPROM,DO ; Set acknowledge bit = 1CALL BITOUT ; to STOP further inputRETLW 0;;END SUB;;-----------------------------------------------------------------------------; TRANSMIT DATA subroutine;-----------------------------------------------------------------------------; Input : TXBUF; Output : Data X'mitted to EEPROM device;-----------------------------------------------------------------------------;TXMOVLW .8MOVWF COUNT;TXLPBCF EEPROM,DO ; Shift data bit out.BTFSC TXBUF,7 ; If shifted bit = 0, data bit = 0BSF EEPROM,DO ; Otherwise data bit = 1CALL BITOUT ; Serial data outRLF TXBUF, F ; Rotate TXBUF leftSKPC ; f(6) ---> f(7)BCF TXBUF,0 ; f(7) ---> carrySKPNC ; carry ---> f(0)BSF TXBUF,0DECFSZ COUNT, F ; 8 bits done?GOTO TXLP ; No.CALL BITIN ; Read acknowledge bitMOVLW 3BTFSC EEPROM,DI ; Check for acknowledgementCALL ERR ; No acknowledge from deviceRETLW 0;;END SUBPAGE;;-----------------------------------------------------------------------------; 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.WRBYTEMOVF SLAVE,W ; Get SLAVE addressMOVWF TXBUF ; to TX bufferCALL BSTART ; Generate START bitCALL TX ; Output SLAVE addressMOVF ADDR,W ; Get WORD addressMOVWF TXBUF ; into bufferCALL TX ; Output WORD addressMOVF DATAO,W ; Move DATA MOVWF TXBUF ; into bufferCALL TX ; Output DATA and detect acknowledgementCALL BSTOP ; Generate STOP bitgoto 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.RDBYTEMOVF SLAVE,W ; Move SLAVE address MOVWF TXBUF ; into buffer (R/W = 0)CALL BSTART ; Generate START bitCALL TX ; Output SLAVE address. Check ACK.MOVF ADDR,W ; Get WORD addressMOVWF TXBUFCALL TX ; Output WORD address. Check ACK.CALL BSTART ; START READ (if only one device isMOVF SLAVE,W ; connected to the I2C bus)MOVWF TXBUFBSF TXBUF,0 ; Specify READ mode (R/W = 1)CALL TX ; Output SLAVE addressCALL RX ; READ in data and acknowledgeCALL BSTOP ; Generate STOP bitMOVF RXBUF,W ; Save data from bufferMOVWF DATAI ; to DATAI file.goto rd_end;;Test program to read and write ramdomstartmovlw 0AE ;set A2=A1=A0=1movwf SLAVE ; /movlw 2 ;set r/w loc. = 2movwf ADDR ; /movlw 55 ;write 55 to SEEPROMmovwf DATAO ; /goto WRBYTE ;write a bytewrt_endcall delay ;wait for write;operation (internal)goto RDBYTE ;read back datard_endmovlw 55 ;test if readxorwf DATAI,W ;correct?btfss STAT,Z ;yes then skipwrong goto wrongcorrectgoto correct;;At 2.0Mhz, delay = approx. 3mS.delayclrf 1F ;clear last locationdly1nopnopnopdecfsz 1F, F ;reduce countgoto dly1 ;loopretlw 0;org 0x1FFgoto start;END
51單片機相關文章:51單片機教程
評論