hi guys!
im making a project that has two PIC18f452. one pic is acting as SPI master, the other is acting as SPI slave. The master makes portB.0 of SPI slave low which it takes as INT0 interrupt. then master sends "?" through SPI, in return slave has to send "!" after which the master will send its data through SPI to slave. before using external interrupt(INT0), the SPI communication was working well. But when i enabled this interrupt, the slave is not sending the "!" to the master as a result master is unable to send its data to slave through SPI. Here is my coding of master:
Code:Include "Modedefs.Bas" DEFINE HSER_RCSTA 90h DEFINE HSER_TXSTA 24h DEFINE HSER_BAUD 9600 DEFINE HSER_SPBRG 25 define OSC 4 DEFINE ADC_BITS 8 ' Set number of bits in result DEFINE ADC_CLOCK 2 ' Set clock source (rc = 3) DEFINE ADC_SAMPLEUS 50 ' Set sampling time in microseconds ' Set LCD Data port DEFINE LCD_DREG PORTD ' Set starting Data bit (0 or 4) if 4-bit bus DEFINE LCD_DBIT 0 ' Set LCD Register Select port DEFINE LCD_RSREG PORTC ' Set LCD Register Select bit DEFINE LCD_RSBIT 0 ' Set LCD Enable port DEFINE LCD_EREG PORTC ' Set LCD Enable bit DEFINE LCD_EBIT 1 ' Set LCD bus size (4 or 8 bits) DEFINE LCD_BITS 8 ' Set number of lines on LCD DEFINE LCD_LINES 2 ' Set command delay time in us DEFINE LCD_COMMANDUS 2000 ' Set data delay time in us DEFINE LCD_DATAUS 50 SSPEN VAR SSPCON1.5 'SSP Enable bit CKP VAR SSPCON1.4 'Clock Polarity Select SMP VAR SSPSTAT.7 'Data input sample phase CKE VAR SSPSTAT.6 'Clock Edge Select bit SSPIF VAR PIR1.3 'SPI interrupt flag i VAR BYTE 'loop counter a VAR byte[6] 'Holds 6 characters read from slave b VAR byte[6] 'Holds 6 characters read from slave c var byte[6] 'Holds 6 characters read from slave ADCON1 = 7 'Set PORTA and PORTE to digital Low PORTE.2 'LCD R/W line low (W) Pause 100 'Wait for LCD to start up TRISC = %10010000 'set PORTC I/O SSPEN = 1 'enable SPI pins CKP = 0 'clock idle low CKE = 0 'transmit on idle to active transition SSPIF = 0 'clear buffer full status SMP = 0 'sample in middle of data SSPCON1.0 = 0 SSPCON1.1 = 0 SSPCON1.2 = 0 SSPCON1.3 = 0 loop: high portB.0 HSERIN [WAIT("a"),STR a\4\"\"] pause 50 hserout["ok",13,10] pause 50 HSERIN [WAIT("a"),STR b\4\"\"] pause 50 hserout["ok",13,10] pause 50 HSERIN [WAIT("a"),STR c\4\"\"] pause 50 hserout["ok",13,10] pause 50 low portB.0 GoSub senddata 'initiate conversion and receive data GoTo loop 'do it forever senddata: SSPBUF = "?" 'send ? to start conversion hserout["? sent",13,10] GoSub letclear 'wait for buffer to clear IF SSPBUF<>"!" Then senddata 'wait for reply (!) For i = 0 to 4 'loop for 6 characters SSPBUF = 0 'write to SSPBUF to start clock GoSub letclear 'wait for receipt SSPBUF=a[i] 'store received character in array Next i 'get next character For i = 0 to 4 'loop for 6 characters SSPBUF = 0 'write to SSPBUF to start clock GoSub letclear 'wait for receipt SSPBUF=b[i] 'store received character in array Next i For i = 0 to 4 'loop for 6 characters SSPBUF = 0 'write to SSPBUF to start clock GoSub letclear 'wait for receipt SSPBUF=c[i] 'store received character in array Next i Return letclear: IF SSPIF = 0 Then letclear 'wait for SPI interupt flag PauseUs 25 '25uS fudge factor SSPIF = 0 'reset flag Return
and here is my coding for the slave:
Code:Include "Modedefs.Bas" DEFINE HSER_RCSTA 90h DEFINE HSER_TXSTA 24h DEFINE HSER_BAUD 9600 DEFINE HSER_SPBRG 25 define osc 4 DEFINE ADC_BITS 8 ' Set number of bits in result DEFINE ADC_CLOCK 8 ' Set clock source (rc = 3) DEFINE ADC_SAMPLEUS 50 ' Set sampling time in microseconds dataout VAR BYTE[8] 'Data out array dataout2 var byte[8] dataout3 var byte[8] SSPEN VAR SSPCON1.5 'SSP Enable bit CKP VAR SSPCON1.4 'Clock Polarity Select SMP VAR SSPSTAT.7 'Data input sample phase CKE VAR SSPSTAT.6 'Clock Edge Select bit SSPIF VAR PIR1.3 'interrupt flag - last bit set SCL Var PortB.6 ' I2C data pin SDA Var PortB.7 ' I2C clock pin i VAR BYTE 'loop counter a VAR BYTE[6] 'Holds 6 characters of data addr var word E_ByteOut Var Byte ' Data byte to be written to the Eeprom E_ByteIn Var Byte b var byte c var byte Define I2C_SCLOUT 1 on interrupt goto DECIDE INTCON.7=1 INTCON.6=1 INTCON.4=1 INTCON2.7=0 INTCON2.6=0 INTCON2.4=0 INTCON2.5=0 INTCON3.7=0 INTCON3.6=1 INTCON3.4=1 INTCON3.3=1 find: HIGH PORTC.1 PAUSE 100 LOW PORTC.1 PAUSE 100 goto find TRISC = %11011111 'set PORTC I/O SSPCON1 = %00000101 'configure SPI slave, no SS CKP = 0 'clock idle low CKE = 0 'transmit on idle to active transition SSPIF = 0 'clear SPI interrupt SMP = 0 'sample in middle of data ADCON1 = $00 'PORTA.0 analog, rest PORTA and PORTE pins to digital loop: DISABLE toggle intcon2.6 intcon.1=0 if portB.0=0 then HSEROUT["INT1 CONNECTED ",13,10] if portB.0=1 then HSEROUT["INT1 REMOVED ",13,10] hserout["hello",13,10] gosub letclear SSPEN = 0 'disable/enable SSP to reset port hserout["hello1",13,10] SSPEN = 1 'hserout["hello2",13,10] hserout["ok",13,10] GoSub letclear 'wait for byte received IF (SSPBUF <> "?") Then loop 'wait for ? to start conversion hserout["? received",13,10] GoSub getdata 'send "!" and string of data hserout[str dataout\5,13,10] hserout[str dataout2\5,13,10] hserout[str dataout3\5,13,10] b=0 c=0 for addr=0 to 5 e_byteout=dataout[addr] hserout[E_byteout,13,10] gosub EWrite next for addr=6 to 11 e_byteout=dataout2[b] b=b+1 hserout[E_byteout,13,10] gosub EWrite next for addr=12 to 17 e_byteout=dataout3[c] c=c+1 hserout[E_byteout,13,10] gosub EWrite next pause 1000 for addr=0 to 17 a[addr]=E_bytein gosub ERead next hserout[str a\18,13,10] hserout["read done",13,10] resume enable GoTo loop 'do it forever getdata: GoSub letclear 'wait until buffer ready SSPBUF = "!" 'send reply gosub letclear SSPBUF = 0 For i = 0 to 4 'loop for 6 array locations gosub letclear 'wait until buffer ready dataout[i]=SSPBUF 'send array variable Next i 'next location For i = 0 to 4 'loop for 6 array locations gosub letclear 'wait until buffer read dataout2[i]=SSPBUF 'send array variable Next i For i = 0 to 4 'loop for 6 array locations gosub letclear 'wait until buffer read dataout3[i]=SSPBUF 'send array variable Next i Return letclear: hserout["letclear entered",13,10] IF SSPIF = 0 Then letclear 'wait for interrupt flag pauseus 25 hserout["sspif",13,10] SSPIF = 0 'reset flag hserout["return",13,10] Return EWrite: I2CWRITE SDA,SCL,%10100000,Addr,[E_ByteOut] ' Write out the byte Pause 10 ' Delay 10ms after each write Return ERead: I2CREAD SDA,SCL,%10100000,Addr,[E_ByteIn] ' Read in the byte Return myint2: hserout["int 2 is not defined",13,10] goto find myint3: hserout["int 3 is not defined",13,10] goto find decide: disable if intcon.1=1 then loop if intcon3.0=1 then myint2 if intcon3.1=1 then myint3
One very important thing that i want to tell you in the slave program is this, that if you see the loop label in this program, the control successfuly displays "INT1 connected" then "hello", then "hello1", then "hello2", then "ok" but then when it comes to GOSUB letclear statement, it doesnt executes it at all. and nothing happens then. PLease see what is the problem,




Bookmarks