This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

I2C send receive general setup with RTC DS1307



i am using a lib for i2c comunication lib from this site

i2c communication tivaware example

I want to communicate atexas instrument launchpad with a ds1307. I did that with an arduino and i need to learn how to do that with texas instruments launchpads.

I want to set two 3 functions:1) to set the control register 2) read the control reg 3) send the hour

#define DS1307_ADDRESS  0x68
#define DS1307_CONTROL  0x07
#define OneHertzSQP 0x10

void RtcSetCTRL(){

    I2CSend(DS1307_ADDRESS,2,DS1307_CONTROL,OneHertzSQP);

}

uint32_t RtcReadCTRL()
{
    return I2CReceive(DS1307_ADDRESS,DS1307_CONTROL);

}

void RtcDS1307adjust(){

    I2CSend(DS1307_ADDRESS,7,
    myFullCalendar.seconds,myFullCalendar.minutes,myFullCalendar.hour,
    myFullCalendar.dayOfWeek,myFullCalendar.date,myFullCalendar.month,myFullCalendar.year);

where myFullCalendar is a struct.

also there is the init,receive and send functions for the i2c in the site.

I am not concerned about the last function.

I have a led in the pin for the that when i set the control reg to 1Hz it blinks every sec.

This is what i want to see in order to be sure that i use correctly the send recieve functions. So i will be sure i can use every i2c device correctly.

When i debug the program the launchpad stacks in the functions i2csend in the AT THE LINE:

while(I2CMasterBusy(I2C0_BASE)); /////IT STOPS HERE

i give you the code from the site.

void I2CSend(uint8_t slave_addr, uint8_t num_of_args, ...)
{
    //    Tell the master module what address it will place on the bus when
    //    communicating with the slave.
    I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false);

    //stores list of variable number of arguments
    va_list vargs;

    //specifies the va_list to "open" and the last fixed argument
    //so vargs knows where to start looking
    va_start(vargs, num_of_args);

    //put data to be sent into FIFO
    I2CMasterDataPut(I2C0_BASE, va_arg(vargs, uint32_t));

    //if there is only one argument, we only need to use the
    //single send I2C function
    if(num_of_args == 1)
    {
        //Initiate send of data from the MCU
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);

        // Wait until MCU is done transferring.
        while(I2CMasterBusy(I2C0_BASE));

        //"close" variable argument list
        va_end(vargs);
    }

    //otherwise, we start transmission of multiple bytes on the
    //I2C bus
    else
    {
        //Initiate send of data from the MCU
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);

        // Wait until MCU is done transferring.
        while(I2CMasterBusy(I2C0_BASE)); /////IT STOPS HERE

        //send num_of_args-2 pieces of data, using the
        //BURST_SEND_CONT command of the I2C module
        uint8_t i;
        for(i = 1 ; i < (num_of_args - 1) ; i++)
        {
            //put next piece of data into I2C FIFO
            I2CMasterDataPut(I2C0_BASE, va_arg(vargs, uint32_t));
            //send next data that was just placed into FIFO
            I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);

            // Wait until MCU is done transferring.
            while(I2CMasterBusy(I2C0_BASE));
        }

        //put last piece of data into I2C FIFO
        I2CMasterDataPut(I2C0_BASE, va_arg(vargs, uint32_t));
        //send next data that was just placed into FIFO
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
        // Wait until MCU is done transferring.
        while(I2CMasterBusy(I2C0_BASE));

        //"close" variable args list
        va_end(vargs);
    }
}

Do you find any problem in my functions? Why this does not work? Also i have desolder pull up resistors from the pcb in order to work in 3.3v lauchpad.

Is there any problem on the code that you see?

  • Moving to MSP430 forum.

    Are you using an MSP430 LaunchPad?
  • If the loop checking for a busy bus doesn’t exit, then the USCI device apparently thinks that the bus is busy. This may have several reasons. One of them would be that the I2C connection has no pull-up resistors (these are external and required by the I2C bus hardware concept). Or the GND connection is missing. Or one of the peers holds one or both lines low. (I2C peers can only pull the lines low, but can’t pull it up, so there is no way to force them up). It is also possible that the USCI has, since initialized, detected a start condition on the bus but not stop condition yet. This may have happened due to improper port pin configuration.
    It’s also possible that, if the I2C functions use interrupts, you forgot to enable interrupts, so the transfer can’t take place.
  • All the post about ds1307 say that if you want to use it with 3.3v board you have to remove the pullup resistors or you will damage the board. ( i do not understand this cause then you will send 3.3v in to the sda and scl pins that do not have any problem with this voltage).

    Except the lnfinate loop in order to check for a busy bus exists and the programm unstacks from it when i enable the loopback feature with this line: 

    HWREG(I2C0_BASE + I2C_O_MCR) |= 0x01;

    Can you give me a logic explanation why i try to send 0x10 and i read 0xFF from the register ?

  • I have managed to make it almost work. I have reconnected the pullup resistors for thew sda and scl of the i2c and i have deleted the loopback function. I manage to read the register 0x07 before  writing to it and the value was 0x03.After this i wrote to the register the value 0x10 and then i read it back. The value was correct but it did not opened the square pulse. Though it was correct the value i read the pulse is not working. So is it any chance that the read was not good? I am giving a photo that in order to prove that the correct value for 1Hz square pulse is 0x10.

    Is it possible to read a correct value and still the register not to be set?

  • The recommendation for removing the pull-ups probably is because they pull the bus up to something higher than 3.3V. If you have a 3.3V device on the bus, then you likely need to connect pull-ups to 3.3V. This will be usually sufficient 'high' level even if some of the slaves run on 5V supply.
    On I2C, there is no way to read an echo or a dummy value. There is, of course, some chance to get a wrong value due to bus problems. However, it is unlikely that you 'accidentally' read what you did send.
    So if you write 0x10, then you should see 1 1Hz square wave output. However, it is possible that you'll need a pull-up on this output pin too. Since this is often used to trigger an interrupt and shared with other interrupt sources, it could be an open collector output too, and without pull-up, you'll see 'nothing' and 'low', which is a flat line on the scope.

**Attention** This is a public forum