Actions

EmSys

Difference between revisions of "DS1307 Programming"

From EdWiki

m (RTC DS1307 Programming Examples)
m (Tasks)
 
(11 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
__NOTOC__
 
__NOTOC__
== RTC DS1307 Programming Examples ==
+
== RTC DS1307 on EduARM4 Trainer Board ==
  
 
[[image:ds1307_tm4c_connections.png|center]]
 
[[image:ds1307_tm4c_connections.png|center]]
 
 
<div style="text-align: center;">'''Figure''':DS1307 Connectons</div>
 
<div style="text-align: center;">'''Figure''':DS1307 Connectons</div>
=== Setting the Time of DS1307 in TI ARM Tiva ===
 
  
 +
=== Note ===
 +
* <big>Short 1 & 2 and 3 & 4  of J6</big> on the [[EmSys:EduARM4 Board | EduARM4 Trainer Board]]
 +
 +
== Source Code ==
 +
<syntaxhighlight lang="c" line start="1">
 +
/*
 +
* I2C to DS1307 single byte writes
 +
 +
* This program communicates with the DS1307 Real-time Clock via I2C.
 +
*
 +
* The DS1307 has a total of 64 bytes of RAM space with addresses 00–3FH.
 +
* The first seven locations, 00–06, are set aside for RTC values of Time and Date.
 +
* The next byte is used for the control register. It is located at address 0x07.
 +
* That leaves 56 bytes, from addresses 0x08 to 0x3F, available for general-purpose data storage.
 +
* That means the entire 64 bytes of RAM are accessible directly for read or write
 +
*
 +
*/
 +
 +
/* DS1307 parameters:  fmax = 100 kHz
 +
*                    I2C1SCL PA6
 +
*                    I2C1SDA PA7
 +
*
 +
*/
 +
 +
#include <stdint.h>
 +
#include "inc/tm4c123gh6pm.h"
 +
 +
#define MAX_BUF_SIZE                56
 +
 +
#define SLAVE_ADDR 0x68            /* 1100 1000 */
 +
#define I2C_START_ADDR              0x08
 +
 +
void I2C1_init(void);
 +
char I2C1_byteWrite(int slaveAddr, char memAddr, char data);
 +
char I2C1_read(int slaveAddr, char memAddr, int byteCount, char* data);
 +
 +
char readBuf[MAX_BUF_SIZE];
 +
 +
int main(void)
 +
{
 +
    char err, i;
 +
 +
    char writeBuf;
 +
 +
    writeBuf = I2C_START_ADDR;
 +
    I2C1_init();
 +
 +
    /* write 56 bytes with single byte writes */
 +
    for( i = 0; i < MAX_BUF_SIZE; i++) {
 +
        err = I2C1_byteWrite(SLAVE_ADDR, writeBuf++, i);
 +
        if(err) break;
 +
    }
 +
 +
    if( err ) {
 +
        ;                      /* Handle error condition */
 +
    } else {
 +
        /* uses burst read to read 56 bytes of data */
 +
        err = I2C1_read(SLAVE_ADDR, I2C_START_ADDR, MAX_BUF_SIZE, readBuf);
 +
    }
 +
 +
    for(;;) {
 +
        ;
 +
    }
 +
}
 +
 +
/* initialize I2C1 as master and the port pins */
 +
void I2C1_init(void)
 +
{
 +
    SYSCTL_RCGCI2C_R |= 0x02;      /* enable clock to I2C1 */
 +
    SYSCTL_RCGCGPIO_R |= 0x01;      /* enable clock to GPIOA */
 +
 +
    /* PORTA 7, 6 for I2C1 */
 +
    GPIO_PORTA_AFSEL_R |= 0xC0;    /* PORTA 7, 6 for I2C1 */
 +
    GPIO_PORTA_PCTL_R &= ~0xFF000000; /* PORTA 7, 6 for I2C1 */
 +
    GPIO_PORTA_PCTL_R |= 0x33000000;
 +
    GPIO_PORTA_DEN_R |= 0xC0;      /* PORTA 7, 6 as digital pins */
 +
    GPIO_PORTA_ODR_R |= 0x80;      /* PORTA 7 as open drain */
 +
 +
    I2C1_MCR_R = 0x10;              /* master mode */
 +
    I2C1_MTPR_R = 7;                /* 100 kHz @ 16 MHz */
 +
}
 +
 +
 +
/* Wait until I2C master is not busy and return error code */
 +
/* If there is no error, return 0 */
 +
static int I2C_wait_till_done(void)
 +
{
 +
    while(I2C1_MCS_R & 1)
 +
        ;                          /* wait until I2C master is not busy */
 +
    return I2C1_MCS_R & 0xE;        /* return I2C error code */
 +
}
 +
 +
/* Write one byte only */
 +
/* byte write: S-(saddr+w)-ACK-maddr-ACK-data-ACK-P */
 +
char I2C1_byteWrite(int slaveAddr, char memAddr, char data)
 +
{
 +
    char error;
 +
 +
    /* send slave address and starting address */
 +
    I2C1_MSA_R = slaveAddr << 1;
 +
    I2C1_MDR_R = memAddr;
 +
    I2C1_MCS_R = 3;                /* S-(saddr+w)-ACK-maddr-ACK */
 +
 +
    error = I2C_wait_till_done();  /* wait until write is complete */
 +
    if(error) return error;
 +
 +
    /* send data */
 +
    I2C1_MDR_R = data;
 +
    I2C1_MCS_R = 5;                /* -data-ACK-P */
 +
    error = I2C_wait_till_done();  /* wait until write is complete */
 +
    while( I2C1_MCS_R & 0x40 )
 +
        ;                          /* wait until bus is not busy */
 +
    error = I2C1_MCS_R & 0xE;
 +
    if(error) return error;
 +
 +
    return 0;                      /* no error */
 +
}
 +
 +
/* Read memory */
 +
/* read: S-(saddr+w)-ACK-maddr-ACK-R-(saddr+r)-ACK-data-ACK-data-ACK-...-data-NACK-P */
 +
char I2C1_read(int slaveAddr, char memAddr, int byteCount, char* data)
 +
{
 +
    char error;
 +
 +
    if (byteCount <= 0)
 +
        return -1;                  /* no read was performed */
 +
 +
    /* send slave address and starting address */
 +
    I2C1_MSA_R = slaveAddr << 1;
 +
    I2C1_MDR_R = memAddr;
 +
    I2C1_MCS_R = 3;                /* S-(saddr+w)-ACK-maddr-ACK */
 +
    error = I2C_wait_till_done();
 +
    if(error)
 +
        return error;
 +
 +
    /* to change bus from write to read, send restart with slave addr */
 +
    I2C1_MSA_R = (slaveAddr << 1) + 1;  /* restart: -R-(saddr+r)-ACK */
 +
 +
    if( byteCount == 1 )            /* if last byte, don't ack */
 +
        I2C1_MCS_R = 7;            /* -data-NACK-P */
 +
    else                            /* else ack */
 +
        I2C1_MCS_R = 0xB;          /* -data-ACK- */
 +
    error = I2C_wait_till_done();
 +
    if(error) return error;
 +
 +
    *data++ = I2C1_MDR_R;          /* store the data received */
 +
 +
    if( --byteCount == 0 ) {        /* if single byte read, done */
 +
        while( I2C1_MCS_R & 0x40 )
 +
            ;                      /* wait until bus is not busy */
 +
        return 0;                  /* no error */
 +
    }
 +
 +
    /* read the rest of the bytes */
 +
    while( byteCount > 1 ) {
 +
        I2C1_MCS_R = 9;              /* -data-ACK- */
 +
        error = I2C_wait_till_done();
 +
        if(error) return error;
 +
        byteCount--;
 +
        *data++ = I2C1_MDR_R;        /* store data received */
 +
    }
 +
 +
    I2C1_MCS_R = 5;                /* -data-NACK-P */
 +
    error = I2C_wait_till_done();
 +
    *data = I2C1_MDR_R;            /* store data received */
 +
    while( I2C1_MCS_R & 0x40 )
 +
        ;                          /* wait until bus is not busy */
 +
 +
    return 0;                      /* no error */
 +
}
 +
 +
</syntaxhighlight>
  
  
 +
<!--
 
[[File:prev.gif|left|link=EmSys:DS1307 RTC Interfacing and Programming]]  
 
[[File:prev.gif|left|link=EmSys:DS1307 RTC Interfacing and Programming]]  
<!--[[File:next.gif|right|link=EmSys:DS1307_RTC_Interfacing_and_Programming]] -->
+
[[File:next.gif|right|link=EmSys:DS1307_RTC_Interfacing_and_Programming]]  
 
[[File:home.gif|center|link={{SERVER}}/edwiki/Main_Page]]
 
[[File:home.gif|center|link={{SERVER}}/edwiki/Main_Page]]
 +
-->

Latest revision as of 08:56, 3 March 2020

RTC DS1307 on EduARM4 Trainer Board

Ds1307 tm4c connections.png
Figure:DS1307 Connectons

Note

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 MAX_BUF_SIZE                56
  24.  
  25. #define SLAVE_ADDR 0x68             /* 1100 1000 */
  26. #define I2C_START_ADDR              0x08
  27.  
  28. void I2C1_init(void);
  29. char I2C1_byteWrite(int slaveAddr, char memAddr, char data);
  30. char I2C1_read(int slaveAddr, char memAddr, int byteCount, char* data);
  31.  
  32. char readBuf[MAX_BUF_SIZE];
  33.  
  34. int main(void)
  35. {
  36.     char err, i;
  37.  
  38.     char writeBuf;
  39.  
  40.     writeBuf = I2C_START_ADDR;
  41.     I2C1_init();
  42.  
  43.     /* write 56 bytes with single byte writes */
  44.     for( i = 0; i < MAX_BUF_SIZE; i++) {
  45.         err = I2C1_byteWrite(SLAVE_ADDR, writeBuf++, i);
  46.         if(err) break;
  47.     }
  48.  
  49.     if( err ) {
  50.         ;                       /* Handle error condition */
  51.     } else {
  52.         /* uses burst read to read 56 bytes of data */
  53.         err = I2C1_read(SLAVE_ADDR, I2C_START_ADDR, MAX_BUF_SIZE, readBuf);
  54.     }
  55.  
  56.     for(;;) {
  57.         ;
  58.     }
  59. }
  60.  
  61. /* initialize I2C1 as master and the port pins */
  62. void I2C1_init(void)
  63. {
  64.     SYSCTL_RCGCI2C_R |= 0x02;       /* enable clock to I2C1 */
  65.     SYSCTL_RCGCGPIO_R |= 0x01;      /* enable clock to GPIOA */
  66.  
  67.     /* PORTA 7, 6 for I2C1 */
  68.     GPIO_PORTA_AFSEL_R |= 0xC0;     /* PORTA 7, 6 for I2C1 */
  69.     GPIO_PORTA_PCTL_R &= ~0xFF000000; /* PORTA 7, 6 for I2C1 */
  70.     GPIO_PORTA_PCTL_R |= 0x33000000;
  71.     GPIO_PORTA_DEN_R |= 0xC0;       /* PORTA 7, 6 as digital pins */
  72.     GPIO_PORTA_ODR_R |= 0x80;       /* PORTA 7 as open drain */
  73.  
  74.     I2C1_MCR_R = 0x10;              /* master mode */
  75.     I2C1_MTPR_R = 7;                /* 100 kHz @ 16 MHz */
  76. }
  77.  
  78.  
  79. /* Wait until I2C master is not busy and return error code */
  80. /* If there is no error, return 0 */
  81. static int I2C_wait_till_done(void)
  82. {
  83.     while(I2C1_MCS_R & 1)
  84.         ;                           /* wait until I2C master is not busy */
  85.     return I2C1_MCS_R & 0xE;        /* return I2C error code */
  86. }
  87.  
  88. /* Write one byte only */
  89. /* byte write: S-(saddr+w)-ACK-maddr-ACK-data-ACK-P */
  90. char I2C1_byteWrite(int slaveAddr, char memAddr, char data)
  91. {
  92.     char error;
  93.  
  94.     /* send slave address and starting address */
  95.     I2C1_MSA_R = slaveAddr << 1;
  96.     I2C1_MDR_R = memAddr;
  97.     I2C1_MCS_R = 3;                 /* S-(saddr+w)-ACK-maddr-ACK */
  98.  
  99.     error = I2C_wait_till_done();   /* wait until write is complete */
  100.     if(error) return error;
  101.  
  102.     /* send data */
  103.     I2C1_MDR_R = data;
  104.     I2C1_MCS_R = 5;                 /* -data-ACK-P */
  105.     error = I2C_wait_till_done();   /* wait until write is complete */
  106.     while( I2C1_MCS_R & 0x40 )
  107.         ;                           /* wait until bus is not busy */
  108.     error = I2C1_MCS_R & 0xE;
  109.     if(error) return error;
  110.  
  111.     return 0;                       /* no error */
  112. }
  113.  
  114. /* Read memory */
  115. /* read: S-(saddr+w)-ACK-maddr-ACK-R-(saddr+r)-ACK-data-ACK-data-ACK-...-data-NACK-P */
  116. char I2C1_read(int slaveAddr, char memAddr, int byteCount, char* data)
  117. {
  118.     char error;
  119.  
  120.     if (byteCount <= 0)
  121.         return -1;                  /* no read was performed */
  122.  
  123.     /* send slave address and starting address */
  124.     I2C1_MSA_R = slaveAddr << 1;
  125.     I2C1_MDR_R = memAddr;
  126.     I2C1_MCS_R = 3;                 /* S-(saddr+w)-ACK-maddr-ACK */
  127.     error = I2C_wait_till_done();
  128.     if(error)
  129.         return error;
  130.  
  131.     /* to change bus from write to read, send restart with slave addr */
  132.     I2C1_MSA_R = (slaveAddr << 1) + 1;   /* restart: -R-(saddr+r)-ACK */
  133.  
  134.     if( byteCount == 1 )            /* if last byte, don't ack */
  135.         I2C1_MCS_R = 7;             /* -data-NACK-P */
  136.     else                            /* else ack */
  137.         I2C1_MCS_R = 0xB;           /* -data-ACK- */
  138.     error = I2C_wait_till_done();
  139.     if(error) return error;
  140.  
  141.     *data++ = I2C1_MDR_R;           /* store the data received */
  142.  
  143.     if( --byteCount == 0 ) {        /* if single byte read, done */
  144.         while( I2C1_MCS_R & 0x40 )
  145.             ;                       /* wait until bus is not busy */
  146.         return 0;                   /* no error */
  147.     }
  148.  
  149.     /* read the rest of the bytes */
  150.     while( byteCount > 1 ) {
  151.         I2C1_MCS_R = 9;              /* -data-ACK- */
  152.         error = I2C_wait_till_done();
  153.         if(error) return error;
  154.         byteCount--;
  155.         *data++ = I2C1_MDR_R;        /* store data received */
  156.     }
  157.  
  158.     I2C1_MCS_R = 5;                 /* -data-NACK-P */
  159.     error = I2C_wait_till_done();
  160.     *data = I2C1_MDR_R;             /* store data received */
  161.     while( I2C1_MCS_R & 0x40 )
  162.         ;                           /* wait until bus is not busy */
  163.  
  164.     return 0;                       /* no error */
  165. }