View previous topic :: View next topic |
Author |
Message |
RickS
Joined: 18 Sep 2013 Posts: 4
|
Can't get i2c slave to work at all |
Posted: Mon Sep 29, 2014 1:22 pm |
|
|
I'm trying to use a simple i2c slave and can't get it to work at all. I never enter the interrupt. I have changed the name of the interrupt to every name found in the help file and still eyemhear never updates implying I'm never entering the interrupt.
I have a scope on my C3 and C4 pins and I'm certainly getting communication from my master but my slave refuses to interrupt. I'd like to post the scope image but I haven't a clue how to do it using this forum.
Also, Timer2 works fine.
Code: |
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x12, FAST=100000)
enable_interrupts (INT_SSP);
enable_interrupts (GLOBAL) ;
enable_interrupts (INT_TIMER2) ;
/******************************************************************/
/*
/* SSP interrupt
/*
/******************************************************************/
#INT_SSP
void SSP_isr()
{
int8 state;
char rcv_buffer[20];
char send_buffer[20];
eyemhear = 1;
state = i2c_isr_state();
if(state== 0 ) i2c_read(); // Master is sending data
{
i2c_read();
BeenThar++;
}
if(state == 0x80)
{
i2c_read(2);
DunThet++;
}
if(state >= 0x80)
{
i2c_write(send_buffer[state - 0x80]); // Master is requesting data from slave
BeenThar = BeenThar + 5;
}
else if(state > 0) // Master is sending data
{
rcv_buffer[state - 1] = i2c_read();
DunThet = DunThet + 5;
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 29, 2014 2:05 pm |
|
|
Post your PIC, compiler version and post your i2c master code.
And post your #fuses, #use delay(), etc. I.e., post test programs
for both master and slave.
Code: |
enable_interrupts (INT_SSP);
enable_interrupts (GLOBAL) ;
enable_interrupts (INT_TIMER2) ; |
Is this really hanging out in space, the way you posted it ? Or is it in main() ?
Post the connections between the two PICs. Post the values of the
pull-up resistors.
Also post the Vdd voltage of both the master and slave PICs.
Quote: | I haven't a clue how to do it using this forum. |
Post it on a free image hosting website. Example:
http://postimage.org/
Then post a link to it here. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon Sep 29, 2014 2:33 pm |
|
|
There are also lots of problems in the code posted.
Code: |
if(state== 0 ) i2c_read(); // Master is sending data
{
i2c_read();
BeenThar++;
}
|
This results in the first i2c_read being executed if state==0,
Then the second read, and the increment, are always executed....
You potentially end up reading three times in the states under 0x80, for each interrupt. Since the interrupt says 'one transaction has occurred', not a good start..... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Mon Sep 29, 2014 2:54 pm |
|
|
I'd start off with using PCM_P's 'I2C scanner ' program in the 'code library' to be sure the PIC can see the device THEN edit your code as needed.
Until you prove the hardware works using his program NO amount of recoding will help.
jay |
|
|
RickS
Joined: 18 Sep 2013 Posts: 4
|
|
Posted: Mon Sep 29, 2014 3:27 pm |
|
|
For the record I have a lot of code that is designed for data logging in one of our products. The code was all working except I could never get the RS232 working to talk to the processor (from our PC using Visual Basic) properly. I could read anything I wanted or write one character as a command, but I couldn't write more than one character to the processor so I gave up. We decided to redesign using I2C for communication. Now I'm trying to use the data logger as the slave and either write data to it or read data from it. I hope Microchip didn't do something brain dead like a one byte buffer for I2C also.
I'm trying to create a slave and my master is an Aardvark I2C/SPI Host Adapter. Don't know what the pullups are because it is just a switch in the command interface of the Aardvark. Hopefully my scope image shows up.
PIC18F45K22 Development Kit
Compiler Version 5.026
The code posted in my first post was code that I thought was pertinent. The #use came from the .h file. The enable interrupts code came from my main, and of course the interrupt was the entire interrupt.
Note: I got the example code from the CCS help file. I have not been able to find any code examples for i2c slave yet except in this forum. As each post that included a slave example was regarding that it was broken, I chose to start from the help file and build. Unfortunately, the help file is obviously incorrect and won't even allow the interrupt to occur. The fact that I'm not handling the interrupt correctly in the code is kind of moot if I can't even get into the interrupt to begin with.
I'm willing to take all the help I can get so if people know of working slave code, I'll be more than happy to use it.
This is my .h:
Code: | #device ICD=TRUE
#FUSES NOWDT
#FUSES INTRC_IO //Internal RC Osc
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
//#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTC //configuration registers not write protected
//#FUSES IESO //Internal External Switch Over mode enabled
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES MCLR //Master Clear pin enabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOCPB //No Boot Block code protection
#FUSES NOWRTB //Boot block not write protected
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O//#FUSES NOHFOFST
#FUSES NOBROWNOUT
//#FUSES PLLEN
//#device ADC=16
#use delay(internal=16000000)
//#use delay(clock=64M, crystal=16M)
//#use rs232(baud=9600,parity=N,xmit=PIN_B7,rcv=PIN_B5,bits=8, stop=1)
//#use fast_io(ALL)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x12, FAST=100000) |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Mon Sep 29, 2014 3:55 pm |
|
|
yipes that's aardvarks a $300 unit !!!...
simple question but is the I2C interface from aardvark only 3volts ? Is the PIC running on 5 volts? If so you may have the 'classic' 5 vs 3 problem.
Others who use I2C on a daily basis,especially a PIC in I2C 'slave' mode will be better help.
PC <>PIC via R-232 is usually trouble free. I do it at 115K200 all day long. there are a couple points though. 1-use a circular buffer (CCS provides an example as ex_sisr.c) , located in the examples folder. 2 - always add 'errors' to the use rs232(....options....). this is needed to prevent UART overrun condition. To use a PIC with a PC with USB only, I use a $3 USB<>TTL module.Simple,cheap, reliable.
Though I don't use VB for the PC, I have used QB4.5 as well as Delphi and never had problems communicating with PICs via RS-232.
just food for thought
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 29, 2014 4:12 pm |
|
|
You ignored the question in my post about the Vdd voltage of your slave
and master. Temtronix has pointed out that the Aardvark is +3.3v.
What is the Vdd of your PIC ? And what is the Vdd of your pullups ?
And the value of the pull-up resistors.
This post has links to slave code and master code that is known to work.
http://www.ccsinfo.com/forum/viewtopic.php?t=50861&start=1 |
|
|
RickS
Joined: 18 Sep 2013 Posts: 4
|
|
Posted: Tue Sep 30, 2014 9:16 am |
|
|
Thanks Guys.
Temtronic:
According to the PIC18F45K22 datasheet, the maximum low input voltage for I2C is 0.3*VDD or 1.5V. The minimum high input voltage for I2c is 0.7*VDD or 3.5V. This would imply you are correct as the Aardvark is running at 3.3V (see scope trace) which is not enough to satisfy the minimum required high voltage. I'll add a level shifter and see if that helps.
PCM Programmer:
I dug through the Aardvark manual and the pullup resistors are 2.2K. I think the problem is the 3.3V though. I thought the development kit was at 3.3V also but I was incorrect.
Thanks for the known working code. This is very helpful as it reduces the number of unknowns in the problem. I probably would have caught the voltage problem had I had some code that I was sure was good to activate the interrupt. As I had no clue what was correct, I was stuck thinking the problem was the code and never looked anywhere else. Of course, this is why I come to you guys. You're experience is always a huge help.
Now, off to get a level shifter.
Thanks, |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 30, 2014 9:34 am |
|
|
Quote: | According to the PIC18F45K22 datasheet, the maximum low input voltage
for I2C is 0.3*VDD or 1.5V. |
These levels can be changed with the SMBUS option. Add the parameter
shown in bold below:
Quote: | #use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x12, FAST=100000, SMBUS) |
Skip the level converter and try that. |
|
|
RickS
Joined: 18 Sep 2013 Posts: 4
|
|
Posted: Tue Sep 30, 2014 11:42 am |
|
|
Thanks! Everything is working fine now. I'm reading and writing over I2C. Now I'll integrate it into the rest of my program. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Tue Sep 30, 2014 12:14 pm |
|
|
Nice to hear it's 'up and running'....
Just a heads up...most if not all peripheral devices these days are 3 volt units so to make life easy(easier ?), use an 'L' rated PIC which WILL run at 3 volts. Seems 3 volts is the 'new' standard. By using the 3 volt PICS you eliminate any 'interface' logic level translation problems,reduce parts,smaller PCB and marginally faster.
jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 30, 2014 12:26 pm |
|
|
He has the 18F45K22 which will run at 3.3v. The LF version will run as
low as 1.8v for Vdd. He has the first one shown below.
Code: |
Special Microcontroller Features:
• 2.3V to 5.5V Operation – PIC18FXXK22 devices
• 1.8V to 3.6V Operation – PIC18LFXXK22 devices |
But his board from CCS is built with +5v as the Vdd voltage. |
|
|
|