issue with i2c interface between attiny2313a and pcf8563

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi

 

I am trying to interface between attiny2313a  with pcf8563 using i2c protocol.I am facing the problem with ACK ,where the attiny2313a is writing the address(0xA2) .

 

The ACK pulse is not going fully high, in between only the pulse is  pulled low and after that one extra pulse is generated for which, i didn't write any code.I am working on this problem for many days.

The waveform and the code is attached below.

 

*********CODE**********

 

/****i2c declarations***********/
#define HDEL _delay_us(60);
#define QDEL _delay_us(30);

#define SDA PORTB5
#define SCL PORTB7
#define PORT PORTB

//SCL
#define SCL_OUT DDRB|=(1<<SCL)

#define SCL_HI PORTB|=(1<<SCL);
#define SCL_LI PORTB&=~(1<<SCL);
//SDA
#define SDA_OUT DDRB|=(1<<SDA);
#define SDA_IN DDRB&=~(1<<SDA);

#define SDA_HI PORTB|=(1<<SDA);
#define SDA_LI PORTB&=~(1<<SDA);

/*******I2C DECLARATION END        ****************/

int main(void)
{
    unsigned char loopcounter,addr;
    unsigned char testbuff[30];
    usart_init();

   
//i2c init
        SDA_OUT;QDEL;
        SCL_OUT;QDEL;

    while(1)
    {
            
//i2c start
        SDA_HI;QDEL;
        SCL_HI;HDEL;
        SDA_LI;QDEL;
        SCL_LI;HDEL;

//i2c write address
    
        addr=0xA2;
        for(loopcounter=0;loopcounter<8;loopcounter++)        
        {
            if(addr & 0x80)
            {
                SDA_HI;
            }
            else
            {
                SDA_LI;
            }
            QDEL;
            SCL_HI;
            HDEL;
            SCL_LI;
            QDEL;
            addr<<=1;
        }

//ACK FOR WRITE BYTE
        SDA_HI;QDEL;
        SDA_IN;QDEL;
        SCL_HI;HDEL;

        if((PORT>>SDA) & 1)
            sprintf( testbuff,"failed wr\n\r");
        else
            sprintf( testbuff,"success wr\n\r");

        SCL_LI;QDEL;
        SDA_OUT;QDEL;//CHECK THEM PROPERLY
        

 

    
//i2c_stop
        SDA_LI;QDEL;
        SCL_HI;QDEL;
        SDA_HI;HDEL;
        _delay_ms(1000);
        usart_string( testbuff);
        usart_string("end\n\r");
    
    }

}

 

 

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It helps if you put the picture in the post - not attach it - so that we can see it:

 

 

For instructions, see Tip #1 - also how to properly post source code.

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

write byte

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You do not understand I2C.    I2C is never driven high.    It relies on the external pullup resistors.

 

In practice you use the DDRx.# register to flip between input and output with the PORTx.# latch low.

 

I suspect that you have developed your functions from 8051 code.

The 8051 ports cannot source current.  They only sink.   

When you write an 8051 Px.# high you are effectively making it an input.

When you write an 8051 Px.# low you are effectively making it an output that sinks current.

When you want to read a Px.# pin you use Px.#.   On an AVR there are separate DDRx, PORTx, PINx registers.

 

I suggest that you study the Fleury i2cmaster.S assembly code.

 

Then modify your macros to suit.    Remember to use PINx.# to read the state of a pin on an AVR.

 

My other advice is to use whitespace between your operators.  It make the code easier for YOU to read.

It is also wise to write functions for each primitive operation e.g. i2c_init(), i2c_start(), i2c_write(), i2c_read(), i2c_stop()

e.g. look at the Fleury i2cmaster.h for a sensible API.

 

Yes,  you can write a bitbang I2C in regular C.   There is no need to use ASM like Fleury.

 

David. 

Last Edited: Thu. Jul 12, 2018 - 09:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you David.

Now i am checking the pin instead of port.

 

why is my ACK pulse voltage level is less when compare to other pulse and after my ACK pulse, there is one more pulse coming for which i did not write any code.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you follow my advice and write separate functions, I will be happy to help you.
And explain your scope trace.
.
David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

David to share my complete code i should take the permission from management .

These are the same instruction that i have used  in my project,

so only i have  written the comments before the code is started for particular function.

 

I am not sure whether it is hardware issue or firmware issue.

How to determine whether it is hardware or software issue.

 

I guess i am missing out something, so please guide me.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So do you not have colleagues or supervisors who can assist you with this?

 

If you can't post the complete code, then create a simple project which just demonstrates your issue.

 

In doing that, you might even find the problem yourself!

 

See: https://www.avrfreaks.net/commen...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Go on.   Your management is not going to worry about a student program to display your I2C code.

 

I would strongly recommend that you just used the proven Fleury code.   And not write your own code.

 

I could post a solution for you.   But you will learn more by writing your own functions.    And someone help you with your questions.

Did you understand my explanation of "Open Drain" (8051) and "Push-Pull" (AVR) port outputs?

 

From an engineering point of view,  learning how to use standard components is more important than designing every component from scratch.

Precision large scale manufacturing was only possible when screw threads were standardised e.g. Springfield Rifle.

 

Designing a software library is a useful skill.    But not as productive as being able to use proven code according to its documentation.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Awneil I have re-created this code many times, but end up with same results,

I don't know how to rectify this problem. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Awneil I have re-created this code many times, but end up with same results,

I don't know how to rectify this problem. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes David I understood open drain and push-pull.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Seriously.   If you follow my advice,  I will give you help.

 

This thread has got to #12 without any progress.    My offer will be withdrawn if we just get pointless posts.

 

Edit your macros for "Open Drain".    Factor your program into separate I2C "library" functions.

 

David. 

Last Edited: Thu. Jul 12, 2018 - 01:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

david.prentice wrote:
I would strongly recommend that you just used the proven Fleury code. And not write your own code.

 

the above is good advise, writing I2C master applications is easy if you use proven code, you can always go back and write your own once you have a working example to compare with.

 

Good luck with your project.

 

Jim

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

manjesh wrote:
attiny2313a 

has a hardware I2C peripheral - so why not just use it?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The Tiny2313 has a USI peripheral which can work quite well as a I2C Slave.    It is possible but more trouble than it is worth as an I2C Master.

 

The OP would still need to factor the project into separate I2C functions.    Which is why I suggested the Fleury API.

 

+1 to ki0bk.    It is always wise to start with proven working code.    Then develop your own code.    You have something to compare.

 

Whether the OP is an apprentice or student,   (s)he will learn most from studying working code.    Then asking questions.

If she shows that she is implementing the advice,   progress can be made.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
The Tiny2313 has a USI

Ah - I was just going from the Microchip page:

 

 

 

Writing your own code from scratch requires a thorough understanding of I2C.

 

And that would have to include study of the I2C specification: https://www.nxp.com/docs/en/user-guide/UM10204.pdf

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Andy,

 

Bit-banging the I2C primitives is easy.    The OP has pretty much got it.

 

Using the USI as I2C Master is difficult.    Yes,  I have done it.

 

The USI peripheral works very well as a Slave SPI or Slave I2C.    It was never intended as a Master.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are getting a tri-state level on the ACK because you are wiring logic levels to PORTB5 instead of using DDRB5 to set the pin to be an input (in order to 'release' the SDA (make it high)).  You are forcing PORTB5 to be high (the ACK FOR WRITE BYTE code) at the same time that the PCF8563 is 'asserting' PORTB5 (SDA) by forcing it low.  A level that is halfway between ground and Vcc is a common sign of a 'logic contention'.  The I2C Master never does ACK after sending the Slave Address.  The Slave device that has the address makes the ACK.