• AVR Freaks

Helpful ReplyHot!Need help with I2C

Author
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
2019/05/19 02:54:17 (permalink)
0

Need help with I2C

Hello all. I'm trying to get my I2C to work but have not been successful.
Controller: PIC16F877A
EEPROM: AT24C32
I have tried all the solutions on this and other forums but none have worked.
#include <xc.h>
#define _XTAL_FREQ 8000000
#include"I2C_code1_header.h"
void I2C_init() //begin as master
{
 TRISCbits.TRISC3=1;
 TRISCbits.TRISC4=1;
 SSPCON=0x38;
 SSPCON2=0b00000000;
 SSPADD =0x13; //(_XTAL_FREQ/(4*feq_K*100))-1;
 SSPSTAT=0b00000000;
    SSPSTATbits.SMP=1;
    SSPIF=0; // clear SSPIF interrupt flag
    BCLIF=0;
}
//-------------------------------------------------------

void I2C_Hold()
{
    while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F)); //check the this on registers to make sure the IIC is not in progress
    
}
//---------------------------------------------------------

/*void I2C_Write(unsigned data)
{
  I2C_Hold(); //Hold the program is I2C as busy
  SSPBUF = data; //pg82
}
//--------------------------------------------------------

unsigned short I2C_Read(unsigned short ack)
{
  unsigned short incoming;
  I2C_Hold();
  RCEN = 1; //receive enable

  I2C_Hold();
  incoming = SSPBUF; //get the data saved in SSPBUF

  I2C_Hold();
  ACKDT = (ack)?0:1; //check if ack bit received
  ACKEN = 1; //pg 85

  return incoming;
}*/
//---------------------------------------------------------

void main(void)
{
    I2C_init();
    while(1)
 {
        I2C_Hold();
  SEN=1;
  SSPBUF=0xD0; //address
        //while(SSPCON2bits.ACKSTAT==1);
        SSPBUF=0x88;
        I2C_Hold();
        SSPBUF=0xFF;
        I2C_Hold();
  PEN=1;
  __delay_ms(1000);
 }
    return;
}

 
I have a few doubts:
Is the value assigned to SSPADD correct?
Is the sub function "void I2C_Hold()" correct?
 
I tested the code on the logical analyzer and there is no output.
 
Please help
thanks in advance
#1
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Need help with I2C 2019/05/19 03:29:10 (permalink) ☄ Helpfulby Abhishek ms 2019/05/19 19:20:19
+2 (2)
When you set SEN to initiate a START cycle, you MUST wait for it to complete before writing to SSPBUF.
You can either loop, waiting for the SEN bit to return to zero,
or just call your "I2C_Hold()" function.
Once you have done that, and then written to SSPBUF, you must again call I2C_Hold() before writing to SSPBUF again.
However, you should check the ACKSTAT bit after the call to I2C_Hold() to see if you got an ACK or a NAK.
I see you commented out a wait for ACKSTAT. That is good, because waiting for ACKSTAT is a newbie mistake that most people fall for the first time they attempt I2C. That is incorrect, you wait for the write transaction to complete, then read ACKSTAT once to see if it succeeded.
 

Nearly there...
#2
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: Need help with I2C 2019/05/19 19:44:10 (permalink)
0
thank you for replying grin: grin
Based on your suggestions I have made the following corrections
while(1)
{
    I2C_Hold();
    SEN=1;
    I2C_Hold();    //<-------------------    
    SSPBUF=0xD0; //address
       I2C_Hold();
       while(SSPCON2bits.ACKSTAT==1;)    //<---
       SSPBUF=0x88;
       I2C_Hold();
       while(SSPCON2bits.ACKSTAT==1;)    //<---
       SSPBUF=0xFF;
       I2C_Hold();
       while(SSPCON2bits.ACKSTAT==1;)    //<---
       PEN=1;
       __delay_ms(1000);
}
 
please do point out if any further corrections are required.
Also can you please let me know if the value assigned to SSPADD correct or not?
 
I take this opportunity to ask you if there is any way to verify the I2C and SPI programs other than using hardware kits like a logical analyzer?
 
#3
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Need help with I2C 2019/05/19 20:09:37 (permalink)
+2 (2)
Abhishek ms
     while(SSPCON2bits.ACKSTAT==1;)    //<---
 

This is just what I said NOT to do!
(Plus the syntax is wrong. You shouldn't have a semi-colon inside the parenthesis.)
You've already waited for the transaction to complete. If ACKSTAT is high at this point, the slave did NOT acknowledge, and you can wait as long as you like, that is not going to change.
Give up and get out of there!
 

Also can you please let me know if the value assigned to SSPADD correct or not?

Seems ok. It's not critical, so lng as you're not trying to run faster than the slave is rated for.
You can run an I2C bus as slow as you like, you control it.
 

I take this opportunity to ask you if there is any way to verify the I2C and SPI programs other than using hardware kits like a logical analyzer?

A digital scope is very helpful to see what is going on.
If that's not available, then just correctly checking the ACKSTAT bit is your easiest debugging aid.
You will get an ACK when you have addressed the chip correctly. If you get a NAK, something is wrong.
 

Nearly there...
#4
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: Need help with I2C 2019/05/19 23:43:07 (permalink)
0
qhb
 
This is just what I said NOT to do!
(Plus the syntax is wrong. You shouldn't have a semi-colon inside the parenthesis.)
You've already waited for the transaction to complete. If ACKSTAT is high at this point, the slave did NOT acknowledge, and you can wait as long as you like, that is not going to change.
Give up and get out of there!
 

On the back of my mind I knew I had misinterpreted your solution.
The semi-colon is a copy paste mistake which I had corrected in my previous attempts to reply which is was denied access to.
 

 
A digital scope is very helpful to see what is going on.
If that's not available, then just correctly checking the ACKSTAT bit is your easiest debugging aid.
You will get an ACK when you have addressed the chip correctly. If you get a NAK, something is wrong.
 



How do I do this? should I call a UART function and check it on a terminal on my PC?
 

 
However, you should check the ACKSTAT bit after the call to I2C_Hold() to see if you got an ACK or a NAK.




Sorry I got a bit confused, but the above sentence is why I added the ACKSTAT command after I2C_Hold().
#5
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Need help with I2C 2019/05/20 00:29:54 (permalink)
+1 (1)
Abhishek ms

A digital scope is very helpful to see what is going on.
If that's not available, then just correctly checking the ACKSTAT bit is your easiest debugging aid.
You will get an ACK when you have addressed the chip correctly. If you get a NAK, something is wrong.


How do I do this? should I call a UART function and check it on a terminal on my PC?

Serial output for debugging is VERY useful.
If that's too hard, then just a couple of LEDs can help. Light one if you get an ACK, or the other for a NAK.
 
 


However, you should check the ACKSTAT bit after the call to I2C_Hold() to see if you got an ACK or a NAK.

Sorry I got a bit confused, but the above sentence is why I added the ACKSTAT command after I2C_Hold().

I said to check it ONCE, not to loop waiting for it.
After the check, you need to indicate to yourself somehow what the result of the check was.
If you are using a debugger (PICkit3, ICD3 etc.) you can just step through the code and see what happens.
Otherwise, LEDs, or serial output as mentioned above.
 

Nearly there...
#6
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: Need help with I2C 2019/05/20 01:56:28 (permalink)
0
I implemented what you suggested
This is my code now
#include <xc.h>
#define _XTAL_FREQ 8000000
#include"I2C_code3_header.h"
void I2C_init() //begin as master
{
 TRISCbits.TRISC3=1;
 TRISCbits.TRISC4=1;
 SSPCON=0x28;
 SSPCON2=0x00;
 SSPADD =0x13; //(_XTAL_FREQ/(4*feq_K*100))-1;
 SSPSTAT=0x00;
    TRISB=0;
}
//-------------------------------------------------------

void I2C_Hold()
{
    while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F)); //check the this on registers to make sure the IIC is not in progress
    
}

//---------------------------------------------------------

void main(void)
{
    #define LED1 PORTBbits.RB1
    #define LED2 PORTBbits.RB2
    LED1=0;
 LED2=0;
    I2C_init();
    while(1)
 {
        SSPCON2bits.SEN=1;
 I2C_Hold();
 SSPBUF=0xAA; //address
 I2C_Hold();
        if(SSPCON2bits.ACKSTAT==1) //check for NACK
    {
         LED1=1;
         __delay_ms(500);
         LED1=0;
    }
        if(SSPCON2bits.ACKSTAT==0) //check for ACK
    {
         LED2=1;
         __delay_ms(500);
         LED2=0;
    }

        SSPBUF=0x88; //send data
 I2C_Hold();
            if(SSPCON2bits.ACKSTAT==1) //check for ACK
    {
         LED1=1;
         __delay_ms(500);
         LED1=0;
    }
     if(SSPCON2bits.ACKSTAT==0) //check for NACK
    {
         LED2=1;
         __delay_ms(500);
         LED2=0;
    }
  SSPCON2bits.PEN=1;
  I2C_Hold();
  __delay_ms(200);
 }
    return;
}


 
It seem that the slave is Acknowledging as LED2 Blinks for 0.5sec while LED1 is OFF all the time.
Can I take is as a successful transmission?
Or is(are) there any errors in the program?
Or am I interpreting the results wrong?
#7
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Need help with I2C 2019/05/20 02:06:26 (permalink)
0
Are you sure it's on for half a second?
If both bytes were ACKed, it should stay on for a full second.
If the second byte as NAKed, you'd see LED1 flash.
Note you forgot to initialise LED2 at the start.
 

Nearly there...
#8
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: Need help with I2C 2019/05/20 02:36:12 (permalink)
0
My delay is designed to turn the LEDs ON for half a second(500ms), but as I have observed LED2 is ON for half a second and turns of for just a fraction of a second before turning ON again.
  By Initialization if you meant LED2=0; in the beginning then I have done it in reply #7.
 
 
#9
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Need help with I2C 2019/05/20 03:02:55 (permalink)
0
Abhishek ms
My delay is designed to turn the LEDs ON for half a second(500ms), but as I have observed LED2 is ON for half a second and turns of for just a fraction of a second before turning ON again.

It should only be off for 9 bit times, which is 9/100kHz = 90 microseconds,
so I'm surprised you can see it blink off.
 

  By Initialization if you meant LED2=0; in the beginning then I have done it in reply #7.

Oops, I see it there now, but couldn't see it in the copy and paste into notepad I did earlier. Just ignore that comment then.
 

Nearly there...
#10
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: Need help with I2C 2019/05/20 23:38:25 (permalink)
0
Thank You very much for you help grin: grin
 
#11
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: Need help with I2C 2019/05/25 21:53:41 (permalink)
0
Please help!
I'm not able to post any new threads.
The page gives a HTTP error 403 every time.
#12
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Need help with I2C 2019/05/26 00:25:52 (permalink)
0
It is probably the CONTENT of your posts causing the problem.
There is a particularly dumb firewall running on the webserver that hosts this forum, that often interferes with the operation of the forum itself.
See:
Expressions which trigger the firewall
and
How to avoid errors when editing posts
 
Most likely you are trying to post some code which contains a function using "char" in its name.
Any occurrence of "char" followed by "(" will trigger the firewall.
 

Nearly there...
#13
Abhishek ms
New Member
  • Total Posts : 28
  • Reward points : 0
  • Joined: 2018/10/28 01:55:11
  • Location: 0
  • Status: offline
Re: Need help with I2C 2019/05/26 01:23:11 (permalink)
0
Thank you very much for replying qhb.
 
If I do figure out a way to a post new thread, I will not be posting again on this thread.
#14
Jump to:
© 2019 APG vNext Commercial Version 4.5