CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

I2C clock manual to ground by a interrupt

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Andmo



Joined: 04 May 2015
Posts: 14

View user's profile Send private message

I2C clock manual to ground by a interrupt
PostPosted: Thu Mar 03, 2016 8:17 am     Reply with quote

Hello

Sorry for my english. I have a problem with the I2C connection.
I read a MLX90615 and when a Interrupt comes, the clock SCL go at last Clock not back to Ground (during the Interrupt). Can i put the clock manual to ground?

Danks
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Thu Mar 03, 2016 9:33 am     Reply with quote

No.

I2C _idles high_. It sounds as if it is doing what it should. GND, is 'active'.
Andmo



Joined: 04 May 2015
Posts: 14

View user's profile Send private message

PostPosted: Thu Mar 03, 2016 11:26 pm     Reply with quote

I don't understand this! I had attached a Oscilloscope picture.
The yellow is the Interrupt and the red is the clock.
[img] https://www.dropbox.com/s/brxsdv9chnt8oan/SCRN0105.BMP?dl=0 [/img]
40inD



Joined: 30 Jul 2007
Posts: 112
Location: Moscow, Russia

View user's profile Send private message

PostPosted: Thu Mar 03, 2016 11:59 pm     Reply with quote

About Clock: You should use a smaller resistor.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Fri Mar 04, 2016 1:59 am     Reply with quote

It looks as if you are using _software_ I2C.

As such the clock will remain where it is while the interrupt is serviced, and then 'carry on' when it exits.

You must not interfere with the clock yourself. The chip is in the middle of a transaction, and this continues when the interrupt finishes.

Comments:
1) Yes, the rise times look poor. A smaller pull-up would be suggested.
2) Your interrupt handler is taking a long time. Poor design somewhere.
3) Preferably switch to using the I2C hardware.

If you must use software I2C (you are using a chip without the hardware), and you think that breaking the I2C transaction is causing a problem (it shouldn't, though since the device is SMBUS, it may implement a timeout - wouldn't matter if your interrupt handler was reasonably quick), then disable interrupts around each I2C transaction, so the interrupt only gets serviced between bytes.
Andmo



Joined: 04 May 2015
Posts: 14

View user's profile Send private message

PostPosted: Fri Mar 04, 2016 4:13 am     Reply with quote

I put this on the main.h

Code:
 #use I2C(Master, sda=PIN_C4, scl=PIN_C3,FAST=100000)


If i put a Force_HW on the line, it doesn't work. Why?
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Fri Mar 04, 2016 4:36 am     Reply with quote

You have not told us what PIC. Does the PIC have I2C hardware on these pins?.
However the other thing is that the chip will actually start generating the clock at 100K with the hardware. Your scope trace only shows it as being about 16K with the software. With your poor rise times (pull up resistor too large, or a lot of bus capacitance), 100K is not gong to work.
Andmo



Joined: 04 May 2015
Posts: 14

View user's profile Send private message

PostPosted: Fri Mar 04, 2016 5:26 am     Reply with quote

Sorry PIC18F97J94
Yes He has 2 hardware I2C
I have a 2.2K Pull-up but the bus-kabel is about 4meter. Its a MLX90615 Sensor.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Fri Mar 04, 2016 5:57 am     Reply with quote

2K2, would be reasonable for a 5v bus, but at 3v, is rather high for such a long wire. What is the capacitance specification for the wire?. You need to find this out, to see what data rate can be managed. The maximum supported capacitance for I2C, is 400pF, and you may well be getting quite close to this.
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Mar 04, 2016 5:57 am     Reply with quote

hmm..
Quote:
the bus-kabel is about 4meter.

!!!!
I2C is NOT designed for 4 meters (14 FEET).
I'd have to pull out my Philips manual on that but I2C was designed for SHORT distance, like on a small PCB.

Maybe the spec has changed in the past 2 decades but I don't think that much.....
Jay
Andmo



Joined: 04 May 2015
Posts: 14

View user's profile Send private message

PostPosted: Fri Mar 04, 2016 7:00 am     Reply with quote

This with the length of the cable is not the problem. The problem is that i dont no how i do the hardware i2c and handle the interrupt.
Andmo



Joined: 04 May 2015
Posts: 14

View user's profile Send private message

PostPosted: Fri Mar 04, 2016 7:05 am     Reply with quote

If i do this it works fine.

Code:
           
            i2c_start();                                // Start condition
            i2c_write(0xB6);                        // (Slave Address * 2) For R/W bit low for a write
    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    //interrupt funktion         
   for(i=0;i<=3;i++){
   auslesen_ADS8519();
   AD_summe+=AD_value;
   }
     
   AD_summe=AD_summe>>2;      //Mittelwert aus 4 Messungen   
   AD_toflash=AD_summe;        //INT32 in INT16 Variable
   //AD_toflash=zj;
   zj++;
   //if(zj==242) zj=0;

   AD_bh = (AD_toflash >> 8); //In 2 Byte aufteilen       
   AD_bl = (AD_toflash);
      while(bit_test(flash_status, 0))
   {
      FLASH_SELECT();
      spi_write(0x05);
      flash_status = spi_read(0);
      FLASH_DESELECT(); 
   }
   FLASH_SELECT();
   spi_write(0XAD);
   //FLASH_DESELECT();
   
   spi_write(AD_bh);
   spi_write(AD_bl);
   FLASH_DESELECT();

   
   //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
            i2c_write(0x27);                             // Device Temp Register address
            i2c_start();                           // Restart the bus
   //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//interrupt funktion         
   for(i=0;i<=3;i++){
   auslesen_ADS8519();
   AD_summe+=AD_value;
   }
     
   AD_summe=AD_summe>>2;      //Mittelwert aus 4 Messungen   
   AD_toflash=AD_summe;        //INT32 in INT16 Variable
   //AD_toflash=zj;
   zj++;
   //if(zj==242) zj=0;

   AD_bh = (AD_toflash >> 8); //In 2 Byte aufteilen       
   AD_bl = (AD_toflash);
         while(bit_test(flash_status, 0))
   {
      FLASH_SELECT();
      spi_write(0x05);
      flash_status = spi_read(0);
      FLASH_DESELECT(); 
   }
   FLASH_SELECT();
   spi_write(0XAD);
   //FLASH_DESELECT();
   
   spi_write(AD_bh);
   spi_write(AD_bl);
   FLASH_DESELECT();
    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
            i2c_write(0xB7);                 // (Slave Address * 2) - R/W bit high for a read
            TempLSB = i2c_read();                     // Read LSB of device temp from register
            TempMSB = i2c_read();                    // Read MSB of device temp from register
    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    //interrupt funktion     
   for(i=0;i<=3;i++){
   auslesen_ADS8519();
   AD_summe+=AD_value;
   }
     
   AD_summe=AD_summe>>2;      //Mittelwert aus 4 Messungen   
   AD_toflash=AD_summe;        //INT32 in INT16 Variable
   //AD_toflash=zj;
   zj++;
   //if(zj==242) zj=0;

   AD_bh = (AD_toflash >> 8); //In 2 Byte aufteilen       
   AD_bl = (AD_toflash);
         while(bit_test(flash_status, 0))
   {
      FLASH_SELECT();
      spi_write(0x05);
      flash_status = spi_read(0);
      FLASH_DESELECT(); 
   }
   FLASH_SELECT();
   spi_write(0XAD);
   //FLASH_DESELECT();
   
   spi_write(AD_bh);
   spi_write(AD_bl);
   FLASH_DESELECT();
   
   
    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
            PEC = i2c_read();                   // Read PEC
            i2c_stop();
         TempRAW = make16(TempMSB,TempLSB);              // Make 16bit TempRAW from 2 8bit reads
         Temperature = ((TempRAW * 0.02) - 273.15);      // Calculate Device Temperature
         fprintf(debug,":%f:",Temperature);
            delay_ms(20);   




If i do this, and the interrupt comes during the while loop every 200us, it doesn't work.


Code:
          while(messung_flag==1)
         {
         output_high(LEDgruen);
         flag_mlxread=1;
            i2c_start();                                // Start condition
            i2c_write(0xB6);                        // (Slave Address * 2) For R/W bit low for a write
            i2c_write(0x27);                             // Device Temp Register address
            i2c_start();                           // Restart the bus
            i2c_write(0xB7);                 // (Slave Address * 2) - R/W bit high for a read
            TempLSB = i2c_read();                     // Read LSB of device temp from register
            TempMSB = i2c_read();                    // Read MSB of device temp from register
            PEC = i2c_read();                   // Read PEC
            i2c_stop();
         flag_mlxread=0;
            delay_ms(20);           
         output_low(LEDgruen);
         }
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Mar 04, 2016 7:26 am     Reply with quote

You haven't posted your complete program BUT reading the first chunk of code and the term 'interrupt' I have concerns.

You should NOT do any 'fancy math', writing to SPI memory chips,NO delays,prints, etc. in an ISR. ISRs MUST be short ! Set a couple of flags then reurn to main().

I would code and load PCM P's I2C scanner program from the code library and confirm your PIC functions properly. I'm impressed you say it works at 4 m on 3 V BTW!

You also should use the 'hardware' I2C peripheral if possible. Without seeing your 'setup' code I can't tell what's really going on. A SW I2C is NOT as 'forgiving' or 'robust' as the HW I2C.

I'd also cut a simple 'read the sensor-display the data' program and confirm it runs fine for an hour or two THEN when satisfied, add any 'math' or other routines. Be aware that delay_ms(), any delay fucntion effectively 'stops' the PIC from doing anything else until it times out.


Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Fri Mar 04, 2016 8:48 am     Reply with quote

temtronic wrote:
hmm..
Quote:
the bus-kabel is about 4meter.

!!!!
I2C is NOT designed for 4 meters (14 FEET).
I'd have to pull out my Philips manual on that but I2C was designed for SHORT distance, like on a small PCB.

Maybe the spec has changed in the past 2 decades but I don't think that much.....
Jay


Yes.

You can make I2C go longer distances, but you have to use higher voltages, and transceivers designed to increase the drive currents.

The length of the cable _is_ part of the problem. The high capacitance is not allowing the I2C bus to run at 100KHz. Software I2C is only giving you a much lower rate that is working. It is because you can't use the hardware I2C, and are running so slow, that you are getting the I2C signal being affected by the interrupt.

Start by lowering the pull-up to 1.2KR.
Then reduce the rate you are asking for, to perhaps 80KHz.
I think (looking at the scope traces), this should just about work. You should then be able to use the hardware I2C.

You have a label saying 'interrupt function', but no sign that this is actually in an interrupt. If it is, then follow Temtronic's advice and think again.

The mantra for interrupts is:
An interrupt should _just_ do the minimum required to handle the hardware event it signals. Nothing else.

Even at 100KHz, your full I2C transaction is going to take 400uSec.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group