I tried to use above code with 24C32 and PIC16F887 but it does not works. It stuck on this loop: while SSPCON2.0 = 1 : wend
Here's complete code:
Code:'**************************************************************** '* Name : I2C EEPROM * '* Author : Daniel T. Barber * '* Notice : Copyright (c) 2018 * '**************************************************************** @ ERRORLEVEL -306 ' turn off crossing page boundary message '************ Config Settings for 16F877A ************* #CONFIG cfg1 = _INTRC_OSC_NOCLKOUT ; INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN cfg1&= _WDT_ON ; WDT enabled cfg1&= _PWRTE_OFF ; PWRT disabled cfg1&= _MCLRE_OFF ; RE3/MCLR pin function is digital input, MCLR internally tied to VDD cfg1&= _CP_OFF ; Program memory code protection is disabled cfg1&= _CPD_OFF ; Data memory code protection is disabled cfg1&= _BOR_OFF ; BOR disabled cfg1&= _IESO_ON ; Internal/External Switchover mode is enabled cfg1&= _FCMEN_ON ; Fail-Safe Clock Monitor is enabled cfg1&= _LVP_OFF ; RB3 pin has digital I/O, HV on MCLR must be used for programming cfg1&= _DEBUG_OFF ; In-Circuit Debugger disabled, RB6/ICSPCLK and RB7/ICSPDAT are general purpose I/O pins __CONFIG _CONFIG1, cfg1 cfg2 = _BOR40V ; Brown-out Reset set to 4.0V cfg2&= _WRT_OFF ; Write protection off __CONFIG _CONFIG2, cfg2 #ENDCONFIG TRISA=%00000000 'SET A TO OUTPUT 1=input TRISC=%00011000 'set C 3 4 input TRISB=%00000000 'set PortB to output ANSELH=%00000000 ' ADC OFF B ANSEL=%00000000 'configure PortA as digital except first 2 ADCON1=%10000000 'adc justify OSCCON=%01110101 'SET FREQUENCY TO 8MHZ WPUB=%00000000 'turn off Pullups CM1CON0=0 'DISABLE COMPARATORS CM2CON0=0 'SAME HERE Define OSC 8 'Adjust consistent with oscillator speed being used ADCON1 = 7 ' Set PORTA and PORTE to digital DEFINE LCD_DREG PORTB DEFINE LCD_DBIT 4 DEFINE LCD_RSREG PORTB DEFINE LCD_RSBIT 2 DEFINE LCD_EREG PORTB DEFINE LCD_EBIT 3 DEFINE LCD_BITS 4 DEFINE LCD_LINES 2 DEFINE LCD_COMMANDUS 1500 DEFINE LCD_DATAUS 44 'clear I2CBufferSize con 64 Reg_Pointer Var Byte ; Address register I2CDATA Var Byte ; data to read/write I2CAddr Var Byte ; Device address I2C_Wait var byte countI2C var byte I2CWRBuff var byte (I2CBufferSize) I2CWRsize Var Byte I2CRDBuff var byte (I2CBufferSize) I2CRDsize Var Byte I2CErrCode Var Byte I2CErrCode = 0 x var byte 'temp var SSPSTAT.7 = 0 ; SMP<7> - Slew rate control Enabled (400kHz) SSPCON = %00101000 ; | ''''-- SSPM<3:0> - I2C Master mode, clock = FOSC / (4 * (SSPADD+1)) ; '-------- SSPEN<5> - Synchronous Serial Port Enable bit SSPADD = $0E ; set I2C clock rate to 400kHz 'SSPADD = $59 ; set I2C clock rate to 100kHz for x=0 to 255 lcdout $fe, $2, "wait..." I2CAddr=x gosub read1byte lcdout $fe, $2, "data=", dec i2cdata pause 1000 next stop ;----------------------------------------------------------- ; Main Routines ;----------------------------------------------------------- Write1Byte: I2CErrCode.1 = 0 I2CAddr.0 = 0 ;Set Write Bit Gosub StartI2C ;Send Start, Addr, Wait for Ack if I2CErrCode.1 = 1 then RETURN I2CDATA = I2CWRBuff(0) gosub I2CWRByte ;Send I2CDATA Byte Gosub SendStopBit ;Send Stop Bit Return ;----------------------------------------------------------- WriteXBytes: I2CErrCode.1 = 0 I2CAddr.0 = 0 ;Set Write Bit Gosub StartI2C ;Send Start, Addr, Wait for Ack if I2CErrCode.1 = 1 then RETURN For countI2C = 0 to I2CWRsize-1 I2CDATA = I2CWRBuff(countI2C) ; hserout [dec countI2C,"-",ihex2 I2CDATA," ",13,10] gosub I2CWRByte ;Send I2CDATA Byte next countI2C Gosub SendStopBit ;Send Stop Bit Return ;----------------------------------------------------------- Read1Byte: I2CErrCode.1 = 0 I2CAddr.0 = 1 ;Set Read Bit Gosub StartI2C ;Send Start, Addr, Wait for Ack if I2CErrCode.1 = 1 then RETURN gosub I2CRDByte I2CRDBuff(0) = I2CDATA gosub Send_NO_Ack Gosub SendStopBit Return ;----------------------------------------------------------- ReadXBytes: I2CErrCode.1 = 0 I2CAddr.0 = 1 ;Set Read Bit Gosub StartI2C ;Send Start, Addr, Wait for Ack if I2CErrCode.1 = 1 then RETURN for countI2C = 0 to I2CRDsize-2 gosub I2CRDByte gosub Send_Ack I2CRDBuff(countI2C) = I2CDATA next countI2C countI2C = I2CRDsize - 1 gosub I2CRDByte gosub Send_NO_ACK Gosub SendStopBit I2CRDBuff(countI2C) = I2CDATA Return ;----------------------------------------------------------- ; Process Routines ;----------------------------------------------------------- StartI2C: ;Send Start Bit SSPCON2.0 = 1 ; SEN<0> - Send start bit while SSPCON2.0 = 1 : wend ; Wait for completion ;Send Slave Address PIR1.3 = 0 ; SSPIF - Clear interrupt Flag SSPBUF = I2CAddr ; move slave address to SSPBUF While PIR1.3 = 0 : Wend ; SSPIF - Wait for SSP to complete sending slave address ;Wait for Acknowledge or Restart i2c_wait = 0 ; Reset wait counter While SSPCON2.6 = 1 ; Wait for Acknowledge from slave 1=NotAck I2C_Wait = I2C_Wait + 1 ; Increment wait counter if I2C_Wait = 0 then ; Wait for 256 counts goto I2CResError ; Acknowledge "Time Out" - Report error and RETURN else ; Send Repeated Start SSPCON2.1 = 1 ; RSEN - Send Repeated Start while SSPCON2.1 = 1 : wend ; Wait for completion ; Resend the Slave Address PIR1.3 = 0 ; SSPIF - Clear interrupt Flag SSPBUF = I2CAddr ; move slave address to SSPBUF While PIR1.3 = 0 : Wend ; SSPIF - Wait to complete sending Slave Address endif wend RETURN ; Acknowledge recieved Return ;----------------------------------------------------------- I2CWRByte: PIR1.3 = 0 ; SSPIF - Clear interrupt Flag SSPBUF = I2CDATA ; Move data to SSPBUF While PIR1.3 = 0 : Wend ; SSPIF - Wait for SSP to complete sending ;Wait for Acknowledge or Abort i2c_wait = 0 ; Reset wait counter While SSPCON2.6 = 1 ; Wait for Acknowledge from slave 1=NotAck I2C_Wait = I2C_Wait + 1 ; Increment wait counter if I2C_Wait = 0 then ; Wait for 256 counts goto I2CResError ; Acknowledge "Time Out" - Report error and RETURN endif wend RETURN ; Acknowledge recieved Return ;----------------------------------------------------------- I2CRDByte: PIR1.3 = 0 ; SSPIF - Clear interrupt Flag SSPCON2.3 = 1 ; RCEN - Enable receive mode While PIR1.3 = 0 : Wend ; SSPIF - Wait for SSP to complete receiving I2CDATA = SSPBUF Return ;----------------------------------------------------------- SendStopBit SSPCON2.2 = 1 ; PEN - send stop bit While SSPCON2.2 = 1 : Wend ; Wait for SSP to complete Return ;----------------------------------------------------------- Send_NO_Ack: SSPCON2.5 = 1 ; ACKDT - Set Ack bit to NotAck SSPCON2.4 = 1 ; ACKEN - send ACKDT bit While SSPCON2.4 = 1 : Wend ; Wait for SSP to complete Return ;----------------------------------------------------------- Send_Ack: SSPCON2.5 = 0 ; ACKDT - Set Ack bit to Ack SSPCON2.4 = 1 ; ACKEN - send ACKDT bit While SSPCON2.4 = 1 : Wend ; Wait for SSP to complete Return ;----------------------------------------------------------- I2CResError: I2CErrCode.1 = 1 lcdout $fe, $2, "I2C Error!!!" Return ;-----------------------------------------------------------




Bookmarks