Difference Between Read Character and Read Byte I2c

Re: DS1307 Read Write functioning 2020/01/04 18:42:14 (permalink) ☼ Best Respond by abhi143 2020/01/04 xix:13:48

Here'due south some code using the MSSP peripheral off the superlative of my head.
Information technology'southward totally untested, then utilise at your ain take chances. You might acquire something debugging it. :)
Notation, I did Non do a REPEATED Kickoff when setting the read annals accost. It'south perfectly legal to do seperate write and so read transactions instead.
I'yard assuming a 20MHz oscillator.

// PIC16F877A Configuration Scrap Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Depression-Voltage (Single-Supply) In-Circuit Serial Programming Enable chip (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Retentivity Code Protection flake (Data EEPROM code protection off)
#pragma config WRT = OFF        // Wink Plan Retentiveness Write Enable bits (Write protection off; all programme retentiveness may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Retention Code Protection flake (Code protection off)

// #pragma config statements should precede project file includes.
// Utilise project enums instead of #define for ON and OFF.

#include <ninety.h>

#define _XTAL_FREQ 20000000
#ascertain DS1307_ADDR 0xD0    //I2C slave address of DS1307 (viii bit format)
#define SECONDS_REG 0   //offset of the "seconds" register in the DS1307

void i2c_init(void)
{
    TRISCbits.TRISC3 = 1;   // SCL every bit input
    TRISCbits.TRISC4 = ane;   // SDA as input
    SSPCONbits.SSPM = 0b1000;  // Primary mode using SSPADD as baud command
    SSPADD = 49;    //100kHz clock @ 20MHz Fosc
    SSPCONbits.SSPEN = 1;  //enable SSP
}

// Send an I2C START
// Return 0 if all ok, one if bus standoff
__bit i2c_start(void)
{
    BCLIF = 0;  //Clear 'Bus collision" flag
    SEN = one;    //initiate a START cycle
    while (SEN);    //wait until it has been sent
    return BCLIF;   //render value of BCLIF flag
}

// Transport an I2C Terminate
void i2c_stop(void)
{
    PEN = ane;    //initiate a Cease cycle
    while (PEN);    //await until it has been sent
}

// Send an I2C REPEATED Kickoff
void i2c_restart(void)
{
    RSEN = 1;    //initiate a REPEATED START cycle
    while (RSEN);    //wait until it has been sent
}

//Ship ane byte. Return 0 if ACK received, or 1 if NAK received
__bit i2c_sendbyte(unsigned char dat)
{
    SSPBUF = dat;
    while (R_W);    //wait until byte sent and ACK/NAK received
    render ACKSTAT;
}

//Receive one byte. ackflag=0 to ship ACK, or 1 to send NAK in reply
unsigned char i2c_recvbyte(unsigned char ackflag)
{
    RCEN = 1;   // initiate a RECEIVE cycle
    ACKDT = ackflag;    //specify if nosotros should transport ACK or NAK afterward receiving
    while (RCEN);   //wait until RECEIVE has completed
    ACKEN = ane;  //initiate an ACK cycle
    while (ACKEN);  //await until it has completed
    return SSPBUF;
}

//Ship an array of data to an I2C device.
//Return 0 if all OK, 1 if bus error, 2 if slave address NAK, iii if slave annals NAK, iv if slave data NAK
unsigned char i2c_writeblock(unsigned char slave_address, unsigned char start_reg, unsigned char buflen, unsigned char * bufptr)
{
    if (i2c_start() )   //send a start, and check if information technology succeeded
        render ane;   //abort if double-decker collision
    //send the I2C slave address (force R/W bit depression)
    if (i2c_sendbyte(slave_address & 0xFE))
    {
        i2c_stop(); //if accost was NAKed, end the cycle
        return 2;   //and return fault code
    }
    //send the device register index
    if (i2c_sendbyte(start_reg))
    {
        i2c_stop(); //if register was NAKed, cease the cycle
        return three;   //and return error code
    }
    //send the information. buflen might be naught!
    for (; buflen>0; --buflen)
    {
        if (i2c_sendbyte(*bufptr++))
        {
            i2c_stop(); //if annals was NAKed, terminate the cycle
            return four;   //and return mistake code
        }

            }
    i2c_stop();
    return 0;   //no error
}

//Receive an array of data from an I2C device.
//Render 0 if all OK, i if motorcoach error, two if slave address NAK, 3 if slave annals NAK
unsigned char i2c_readblock(unsigned char slave_address, unsigned char start_reg, unsigned char buflen, unsigned char * bufptr)
{
    //do a dummy zippo length write bicycle to ready the register address
    unsigned char retval = i2c_writeblock(slave_address, start_reg,0,0);
    if (retval)
    {
        return retval;  //abort if there was an error
    }
    //now kickoff the READ cycle
    if (i2c_start() )   //ship a showtime, and check if it succeeded
        return 1;   //arrest if bus collision
    //send the I2C slave address (force the R/W chip high)
    if (i2c_sendbyte(slave_address | 0x01))
    {
        i2c_stop(); //if address was NAKed, terminate the bike
        return 2;   //and render error code
    }
    //receive the information.
    for (; buflen>0; --buflen)
    {
        unsigned char ackflag = (buflen == 1);   //1 if this is the concluding byte to receive => transport NAK
        *bufptr++ = i2c_recvbyte(ackflag);
    }
    i2c_stop();
    return 0;   //no fault
}

const unsigned char rtc_data[] =
{
    0x56,   //56 seconds
    0x34,   //34 minutes
    0x12,   //12 hours & 24 hour manner
    0x01,   //01 solar day=Sunday
    0x03,   //03 date
    0x12,   //12 month=dec
    0x01,   //01 year=2001
};

unsigned char rd_buf[7];

void main(void) {
    i2c_init();

        //write some dummy fixed data to the RTC chip
    if (i2c_writeblock(DS1307_ADDR, SECONDS_REG, sizeof(rtc_data), rtc_data) )
    {
        // hither if failed
    } else
    {
        // here if succeeded
    }

        //read data dorsum from the RTC fleck
    if (i2c_readblock(DS1307_ADDR, SECONDS_REG, sizeof(rd_buf), rd_buf) )
    {
        // hither if failed
    } else
    {
        // here if succeeded
    }
    while(1);   //endless loop to avoid exiting principal() function)
}

post edited by ric - 2020/01/04 21:18:55

I besides mail at: PicForum
To get a useful answer, always state which Pic you lot are using!

delgadoenation1969.blogspot.com

Source: https://www.microchip.com/forums/m1123598-p2.aspx

0 Response to "Difference Between Read Character and Read Byte I2c"

Postar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel