View previous topic :: View next topic |
Author |
Message |
arunkish
Joined: 23 Dec 2008 Posts: 83
|
18F2550 I2C Problem |
Posted: Wed Jun 25, 2014 1:59 am |
|
|
Helllo
I have been using 16F876 before with I2C interrupt included below and it worked well. I changed the controller to 18F2550 for more memory.
But.... the code I used and what worked with 16F876 did not work. Can someone please look at the code and advise me on the mistake that I have made. Am I missing something for 18F2250 ?? Compiler Version 3.222
Code: |
#include <18F2550.h>
#fuses HS,NOWDT,NOBROWNOUT
#use delay(clock=4000000)
//*************** USER DECLARATION **************************//
#define SLAVE_ID 1 // Define Slave ID here***
//*************** END OF USER DECLARATION **************************//
#define hi(x) (*(&x+1))
#define low(x) (*(&x))
#define uchar unsigned char
#define ADR=SLAVE_ID<<1
#byte SSPADD = 0xFC8
#use i2c(SLAVE,FAST,SDA=PIN_B0, SCL=PIN_B1,ADDRESS=0x02,FORCE_HW)
#byte PIR1=0xF9E
#bit SSPIF=PIR1.3 //clean flag ssp
#byte SSPCON2 = 0xFC5
#bit GCEN = SSPCON2.7
#byte INTCON=0xFF2
#bit GIE = INTCON.7
#BYTE INTCON2 = 0XFF1
#bit EDGE = INTCON2.4
#byte INTCON3=0xFF0
#bit INTE = INTCON3.4
#bit INTF = INTCON3.1
#byte PORTA = 0xF80
#byte TRISA = 0xF92
#byte PORTB = 0xF81
#byte TRISB = 0xF93
#byte PORTC = 0xF82
#byte TRISC = 0xF94
#bit R_LED = PORTB.3
#bit T_LED = PORTB.4
#bit MAS_RDY = PORTB.7 /// Input PIN
#bit DAT_RDY = PORTC.0 /// Output PIN
typedef enum {NOTHING, ADDRESS,
DATA} I2C_STATE;
I2C_STATE fState;
BYTE i2c_write_buffer[10],i2c_read_buffer[10];
/********************************************************************************************************************************************/
byte icount=0,i2c_read_complete=0,i2c_send_complete=0;
byte i;
/********************************************************************************************************************************************/
#INT_SSP
void ssp_interupt()
{
BYTE incoming,x;
if (i2c_poll() == FALSE) // Master Requesting Data
{
if(fState==ADDRESS)
{
T_LED=1;
for(x=0;x<=7;x++) i2c_write(i2c_write_buffer[x]);
T_LED=0;
fState = ADDRESS;
i2c_send_complete=1;
}
}
else // Master Sending Data
{
if(fState== ADDRESS)
{
incoming = i2c_read();
fState=DATA;
icount=0;
}
else if (fState==DATA)
{
i2c_read_buffer[icount]=i2c_read();
if(icount++>=7){icount=0;i2c_read_complete=1;fState=ADDRESS;}
}
}
}
//#ZERO_RAM
#use delay(clock=4000000)
void main ()
{
TRISA=0b00000000;
TRISB=0b10000011;
TRISC=0b00011000;
// SSPADD=SLAVE_ID<<1;
icount=0; i2c_read_complete=0;
fState = ADDRESS;
for (i=0;i<10;i++){i2c_read_buffer[i] =i2c_write_buffer[i]=0xAA;}
SSPIF=0;
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
port_b_pullups (false);
SSPIF=0;
DAT_RDY=0;
T_LED=R_LED=1;
delay_ms(20);
T_LED=R_LED=0;
T_LED=R_LED=1; //test
while(1)
{
if(MAS_RDY && i2c_read_complete)
{
T_LED=R_LED=0;
} // End of IF
} // End of While
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Wed Jun 25, 2014 5:32 am |
|
|
stuff to consider....
1) Does the PIC perform the '1Hz LED' program at the correct speed ?
2) You should use the getenv(xxx); function to properly find PIC registers.
3) Run PCM_P's 'I2C scanner program' to confirm the PIC can access the I2C device.
Providing the PIC is up and running and this EXACT code(less register locations) does work in the othe rPIC, then it should work on the new PIC.
hth
jay |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Wed Jun 25, 2014 6:08 am |
|
|
I suspect the PIC is not even running. The speed is only 4Mhz and the HS
fuse is being used. You need to change HS to XT with 4Mhz oscillator.
As temtronic says, can you get it to blink an LED at a 1hz rate?
A couple more things:
You have a second #use delay() next to main, get rid of that, it doesn't belong there.
TRIS is being used without FAST_IO so they need to be removed. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
arunkish
Joined: 23 Dec 2008 Posts: 83
|
|
Posted: Wed Jun 25, 2014 8:46 pm |
|
|
Hello
As you have suggested,
1. I changed to fuse to XT
2. Commented out the TRIS section
3. Tried using fast_IO
Still there is no response. SCL , SDA lines are low. PIC receives the ADDRESS from the MASTER and STOPS WORKING.
The other PIC (16F876) works well on the same code.
Confused! |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Wed Jun 25, 2014 9:19 pm |
|
|
Now the problem has changed!
Quote: |
But.... the code I used and what worked with 16F876 did not work. |
"did not work" apparently tells us nothing...
This is the reason why we ask posters to be CLEAR about the problem.
I didn't tell you to use FAST_IO, I said to remove the TRIS statements...
you shouldn't use them normally anyway.
Now please CLEARLY explain this comment and what led you to this conclusion.
Quote: | Still there is no response. SCL , SDA lines are low. PIC receives the ADDRESS from the MASTER and STOPS WORKING. |
sounds like to me you need to set up the standard 1hz led blink check before you go any further. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
arunkish
Joined: 23 Dec 2008 Posts: 83
|
|
Posted: Wed Jun 25, 2014 10:17 pm |
|
|
Hello
Yes, I checked the LED blink, and it Blinks LED at 1 HZ. I completely removed TRIS and FAST IO as suggested. Eitherway SLAVE doesnt work. I mean slave receives the address and not the data. It doesn't get through this condition.
Code: |
else if (fState==DATA)
{
i2c_read_buffer[icount]=i2c_read();
if(icount++>=7){icount=0;i2c_read_complete=1;fState=ADDRESS;}
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Thu Jun 26, 2014 5:17 am |
|
|
1) can you confirm that PCM_P's I2C scanner program works and detects your slave?
2) looking at your ssp_ISR, I don't think the logic is correct. The first 'if' checks for ADDRESS,does a couple things then exits but your 'else' then checks for ADDRESS again.Somehow it seems flawed to me......
hth
jay |
|
|
alan
Joined: 12 Nov 2012 Posts: 357 Location: South Africa
|
|
Posted: Thu Jun 26, 2014 5:46 am |
|
|
Maybe being ignorant here but
Code: | #use i2c(SLAVE,FAST,SDA=PIN_B0, SCL=PIN_B1,ADDRESS=0x02,FORCE_HW) |
Does this define a ADDRESS = 0x02 as the OP uses this for checking the address or put another way is this the same as
#define ADDRESS 0x02 to be used in the conditional test.
Regards |
|
|
|