RTC DS1307 on EduARM4 Trainer Board
Figure:DS1307 Connectons
Note
- Short 1 & 2 and 3 & 4 of J6 on the EduARM4 Trainer Board
Source Code
-
/*
-
* 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 */
-
}
Recent Comments