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 support@ccsinfo.com

i2c bus scanner program

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 20102

View user's profile Send private message

i2c bus scanner program
PostPosted: Wed Jan 09, 2013 2:41 pm     Reply with quote

Here is a diagnostic program (see below) which will look for any i2c slave
devices that are on the i2c bus, and report the slave address for each
one. This program is useful if you want to be sure that your PIC actually
sees the i2c slave device on the i2c bus. It's important to check for this
if you wonder if the PIC is really talking to the i2c slave chip. This
program also lets you verify that the i2c slave chip is really at the same
slave address that you think it is.

This i2c bus scanner program works if the PIC is using either hardware
or software i2c. Note: CCS defaults to software i2c, unless you use the
hardware i2c pins and add the FORCE_HW parameter to the #use i2c()
statement.

For example, if I run this program on my PicDem2-Plus board, it
shows the following result in a terminal window (TeraTerm) on my PC:
Quote:

Start:
ACK addr: 9A
ACK addr: A0

Number of i2c chips found: 2

This means that it found the TC74 temperature chip (slave address 0x9A)
and the 24LC256 eeprom (slave address 0xA0). Run the program on
your board and see what it finds. Note: change the #include, #fuses,
#use delay() and the i2c and RS232 pins (if necessary) so they fit your
development board.
Code:
 
#include <16F887.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(clock=4M)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

// This function writes the slave address to the i2c bus.
// If a slave chip is at that address, it should respond to
// this with an "ACK".   This function returns TRUE if an
// ACK was found.  Otherwise it returns FALSE.
int8 get_ack_status(int8 address)
{
int8 status;

i2c_start();
status = i2c_write(address);  // Status = 0 if got an ACK
i2c_stop();

if(status == 0)
   return(TRUE);
else
   return(FALSE);
}


//=================================
void main()
{
unsigned int8 i;
unsigned int8 status;
unsigned int8 count = 0;

printf("\n\rStart:\n\r");

delay_ms(1000);

// Try all slave addresses from 0x10 to 0xEF.
// See if we get a response from any slaves
// that may be on the i2c bus.
for(i=0x10; i < 0xF0; i+=2)
   {
    status = get_ack_status(i);
    if(status == TRUE)
      { 
       printf("ACK addr: %X\n\r", i);
       count++;
       delay_ms(2000);
      }
   }

if(count == 0)
   printf("\n\rNothing Found");
else
   printf("\n\rNumber of i2c chips found: %u", count);

while(1);


The PIC must be connected to the i2c slave device's SDA and SCL pins.
The SDA and SCL pins must have pull-up resistors on them. There must
also be a ground connection between the Vss pin on the PIC and the
ground or Vss pin on the i2c slave chip. And of course, both the PIC
and the i2c slave chip must have power (Vdd) applied. If you bought
a development board, then these connections normally already exist.
Example:
Code:

              +5v
               |
               <
               > 4.7K       
               <         
To PIC         |          To i2c slave
pin C4 ------------------ SDA pin 
(SDA)                     


              +5v
               |
               <
               > 4.7K       
               <         
To PIC         |          To i2c slave
pin C3 ------------------ SCL pin 
(SCL)

To PIC                    To i2c slave
Vss pin ----------------- Vss or ground pin 
                |
              -----
               ---  Ground
                - 

Please don't use this thread to get help for writing an i2c driver program.
Start a new thread in the CCS General Discussion forum and ask for help there:
http://www.ccsinfo.com/forum/viewforum.php?f=1

----------------------
Edit: Made each variable be 'unsigned' for compatiblity with the PCD
compiler, per Jeremiah's suggestion.


Last edited by PCM programmer on Fri Jan 20, 2017 12:41 pm; edited 1 time in total
MikeW



Joined: 15 Sep 2003
Posts: 165
Location: Warrington UK

View user's profile Send private message

PostPosted: Wed Jan 16, 2013 12:27 pm     Reply with quote

@ PCM programmer.

You are a diamond !!

I found and used your I2C diagnostic program (found in an old thread) last week to help me get started on an SSD1306 design.

Once I had got the hardware sorted, it found the device straight away.

It's a great tool for helping to debug the hardware.

Many many thanks.
Gabriel



Joined: 03 Aug 2009
Posts: 913
Location: Panama

View user's profile Send private message

PostPosted: Sun Jul 07, 2013 11:31 am     Reply with quote

Hi PCM Programmer,

Thanks for the code... I think i found a bug?... maybe..
This is my first time using I2C, so i thought a good place to start was your test code.

Quote:
Start:
ACK addr: 4E

Number of i2c chips found: 1


as you can see, it worked.
I'm using a Breakout board from Sparkfun for the HIH-6130, on a tried and tested dev board I've made a while back...


I later went ahead to use this driver:
http://www.ccsinfo.com/forum/viewtopic.php?t=48077

But it did NOT work using "0x4E" as the address, like your code reported.
I tried "0x24" as the original poster, and that didn't work...

So further checking the datasheet i found the appropriate address to be "0x27" which happens to be =0x4E/2.

Although i have no idea what i am doing, i figured you could share some light on why the code is reporting an address value x2.

thanks..
G.
_________________
CCS PCM 4.135 - PIC: 16F886, 88', 876' 877A
CCS PCH 5.012 - PIC: 18F97j60
jeremiah



Joined: 20 Jul 2010
Posts: 966

View user's profile Send private message

PostPosted: Sun Jul 07, 2013 12:14 pm     Reply with quote

In the driver you linked, it shifts the address to the left one bit (or *2 to the address). That is why you have to specify it as /2 in that driver. PCM's uses 8-bit address format while the other driver uses 7-bit address format.

PCM's test is correct.
Gabriel



Joined: 03 Aug 2009
Posts: 913
Location: Panama

View user's profile Send private message

PostPosted: Mon Jul 08, 2013 7:10 am     Reply with quote

I see it.
Thanks for the explanation.
Quote:
PCM's test is correct.


I was sure the "error" was mine, so thats why i asked this question.

anyways, thanks for clearing that up.

G.
_________________
CCS PCM 4.135 - PIC: 16F886, 88', 876' 877A
CCS PCH 5.012 - PIC: 18F97j60
th3gr8



Joined: 16 Jul 2013
Posts: 12
Location: Pakistan

View user's profile Send private message

Gr8 ..
PostPosted: Wed Jul 02, 2014 3:04 pm     Reply with quote

Wow.. Really a nice program .. Thanks PCM Programmer ..
_________________
A learner
UgurSezgin



Joined: 06 Aug 2015
Posts: 1
Location: Turkey

View user's profile Send private message

PostPosted: Thu Aug 06, 2015 1:25 am     Reply with quote

Very Useful Program Very Happy Thank You So Much @PCM Programmer..

I tried on 18F452 and Working Very Well..
I Edited SomeCodes (actualy cut cut cut and paste..) and Oversimplify.

i2cScanner.c
Code:
void i2cScanner() {
   int8 count = 0;
   printf("\n\rStart I2C Scanner..\n\r");
   for(int8 i=0x10; i < 0xF0; i+=2) {
      i2c_start();
      if(i2c_write(i) == 0) { printf("ACK addr: 0x%X\n\r", i); count++;  }
      i2c_stop();
   }
   if(count == 0) {printf("Nothing Found\n\r"); }
   else { printf("Number of i2c chips found: %u\n\r", count); }
}


main.c
Code:
#include <18F452.h>
#fuses PROTECT,NOWDT,PUT,NOLVP,NOBROWNOUT
#use delay(crystal=16MHz)

#use i2c(Master,Fast=400000,sda=PIN_C4,scl=PIN_C3,force_hw) // maybe force_sw
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)

#include <i2cScanner.c>

void main() {
   i2cScanner();
   while(1);
}


I Wanted to Share Wink
jeremiah



Joined: 20 Jul 2010
Posts: 966

View user's profile Send private message

PostPosted: Fri Jan 20, 2017 11:44 am     Reply with quote

We recently had trouble running this in an older version PCD for a chip due to the int8 variables being considered signed by default and thus the for loop not acting completely correct. One suggestion is to manually indicate the unsigned keyword to avoid those situations.
PCM programmer



Joined: 06 Sep 2003
Posts: 20102

View user's profile Send private message

PostPosted: Fri Jan 20, 2017 12:42 pm     Reply with quote

Done. Thanks.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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