Actions

EmSys

DS1307 Programming

From EdWiki

Revision as of 09:53, 16 August 2018 by Jshankar (Talk | contribs) (Source Code)

RTC DS1307 Programming Examples

Ds1307 tm4c connections.png
Figure:DS1307 Connectons

Source Code

  1. /*
  2. * I2C to DS1307 single byte writes
  3.  
  4. * This program communicates with the DS1307 Real-time Clock via I2C.
  5. *
  6. * The DS1307 has a total of 64 bytes of RAM space with addresses 00–3FH.
  7. * The first seven locations, 00–06, are set aside for RTC values of time and date.
  8. * The next byte is used for the control register. It is located at address 0x07.
  9. * That leaves 56 bytes, from addresses 0x08 to 0x3F, available for general-purpose data storage.
  10. * That means the entire 64 bytes of RAM are accessible directly for read or write
  11. *
  12. */
  13.  
  14. /* DS1307 parameters:  fmax = 100 kHz
  15.  *                     I2C1SCL PA6
  16.  *                     I2C1SDA PA7
  17.  *
  18. */
  19.  
  20. #include <stdint.h>
  21. #include "inc/tm4c123gh6pm.h"
  22.  
  23. #define SLAVE_ADDR 0x68             /* 1100 1000 */
  24. #define MAX_BUF_SIZE                56
  25. #define I2C_START_ADDR              0x08
  26.  
  27. void I2C1_init(void);
  28. char I2C1_byteWrite(int slaveAddr, char memAddr, char data);
  29. char I2C1_read(int slaveAddr, char memAddr, int byteCount, char* data);
  30.  
  31. char readBuf[MAX_BUF_SIZE];
  32.  
  33. int main(void)
  34. {
  35.     char err, i;
  36.  
  37.     char writeBuf;
  38.  
  39.     writeBuf = I2C_START_ADDR;
  40.     I2C1_init();
  41.  
  42.     /* write 56 bytes with single byte writes */
  43.     for( i = 0; i < MAX_BUF_SIZE; i++) {
  44.         err = I2C1_byteWrite(SLAVE_ADDR, writeBuf++, i);
  45.         if(err) break;
  46.     }
  47.  
  48.     if( err ) {
  49.         ;                       /* Handle error condition */
  50.     } else {
  51.         /* uses burst read to read 56 bytes of data */
  52.         err = I2C1_read(SLAVE_ADDR, I2C_START_ADDR, MAX_BUF_SIZE, readBuf);
  53.     }
  54.  
  55.     for(;;) {
  56.         ;
  57.     }
  58. }
  59.  
  60. /* initialize I2C1 as master and the port pins */
  61. void I2C1_init(void)
  62. {
  63.     SYSCTL_RCGCI2C_R |= 0x02;       /* enable clock to I2C1 */
  64.     SYSCTL_RCGCGPIO_R |= 0x01;      /* enable clock to GPIOA */
  65.  
  66.     /* PORTA 7, 6 for I2C1 */
  67.     GPIO_PORTA_AFSEL_R |= 0xC0;     /* PORTA 7, 6 for I2C1 */
  68.     GPIO_PORTA_PCTL_R &= ~0xFF000000; /* PORTA 7, 6 for I2C1 */
  69.     GPIO_PORTA_PCTL_R |= 0x33000000;
  70.     GPIO_PORTA_DEN_R |= 0xC0;       /* PORTA 7, 6 as digital pins */
  71.     GPIO_PORTA_ODR_R |= 0x80;       /* PORTA 7 as open drain */
  72.  
  73.     I2C1_MCR_R = 0x10;              /* master mode */
  74.     I2C1_MTPR_R = 7;                /* 100 kHz @ 16 MHz */
  75. }
  76.  
  77.  
  78. /* Wait until I2C master is not busy and return error code */
  79. /* If there is no error, return 0 */
  80. static int I2C_wait_till_done(void)
  81. {
  82.     while(I2C1_MCS_R & 1)
  83.         ;                           /* wait until I2C master is not busy */
  84.     return I2C1_MCS_R & 0xE;        /* return I2C error code */
  85. }
  86.  
  87. /* Write one byte only */
  88. /* byte write: S-(saddr+w)-ACK-maddr-ACK-data-ACK-P */
  89. char I2C1_byteWrite(int slaveAddr, char memAddr, char data)
  90. {
  91.     char error;
  92.  
  93.     /* send slave address and starting address */
  94.     I2C1_MSA_R = slaveAddr << 1;
  95.     I2C1_MDR_R = memAddr;
  96.     I2C1_MCS_R = 3;                 /* S-(saddr+w)-ACK-maddr-ACK */
  97.  
  98.     error = I2C_wait_till_done();   /* wait until write is complete */
  99.     if(error) return error;
  100.  
  101.     /* send data */
  102.     I2C1_MDR_R = data;
  103.     I2C1_MCS_R = 5;                 /* -data-ACK-P */
  104.     error = I2C_wait_till_done();   /* wait until write is complete */
  105.     while( I2C1_MCS_R & 0x40 )
  106.         ;                           /* wait until bus is not busy */
  107.     error = I2C1_MCS_R & 0xE;
  108.     if(error) return error;
  109.  
  110.     return 0;                       /* no error */
  111. }
  112.  
  113. /* Read memory */
  114. /* read: S-(saddr+w)-ACK-maddr-ACK-R-(saddr+r)-ACK-data-ACK-data-ACK-...-data-NACK-P */
  115. char I2C1_read(int slaveAddr, char memAddr, int byteCount, char* data)
  116. {
  117.     char error;
  118.  
  119.     if (byteCount <= 0)
  120.         return -1;                  /* no read was performed */
  121.  
  122.     /* send slave address and starting address */
  123.     I2C1_MSA_R = slaveAddr << 1;
  124.     I2C1_MDR_R = memAddr;
  125.     I2C1_MCS_R = 3;                 /* S-(saddr+w)-ACK-maddr-ACK */
  126.     error = I2C_wait_till_done();
  127.     if(error)
  128.         return error;
  129.  
  130.     /* to change bus from write to read, send restart with slave addr */
  131.     I2C1_MSA_R = (slaveAddr << 1) + 1;   /* restart: -R-(saddr+r)-ACK */
  132.  
  133.     if( byteCount == 1 )            /* if last byte, don't ack */
  134.         I2C1_MCS_R = 7;             /* -data-NACK-P */
  135.     else                            /* else ack */
  136.         I2C1_MCS_R = 0xB;           /* -data-ACK- */
  137.     error = I2C_wait_till_done();
  138.     if(error) return error;
  139.  
  140.     *data++ = I2C1_MDR_R;           /* store the data received */
  141.  
  142.     if( --byteCount == 0 ) {        /* if single byte read, done */
  143.         while( I2C1_MCS_R & 0x40 )
  144.             ;                       /* wait until bus is not busy */
  145.         return 0;                   /* no error */
  146.     }
  147.  
  148.     /* read the rest of the bytes */
  149.     while( byteCount > 1 ) {
  150.         I2C1_MCS_R = 9;              /* -data-ACK- */
  151.         error = I2C_wait_till_done();
  152.         if(error) return error;
  153.         byteCount--;
  154.         *data++ = I2C1_MDR_R;        /* store data received */
  155.     }
  156.  
  157.     I2C1_MCS_R = 5;                 /* -data-NACK-P */
  158.     error = I2C_wait_till_done();
  159.     *data = I2C1_MDR_R;             /* store data received */
  160.     while( I2C1_MCS_R & 0x40 )
  161.         ;                           /* wait until bus is not busy */
  162.  
  163.     return 0;                       /* no error */
  164. }


Prev.gif
Home.gif