Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
The address map for the DS1307 RTC and RAM registers. The RTC registers are located in address
locations 00h to 07h. The RAM registers are located in address locations 08h to 3Fh. During a multibyte access,
when the address pointer reaches 3Fh, the end of RAM space, it wraps around to location 00h, the beginning of
the clock space.
Then I don't understand your problem....
When a DS1307 is first initialised, we send the time to it... Once this is done we then can read back the real time whenever we need... There is no need to stop / start the oscillator...
Set up a time array Sec, Min, Hour, Day, Date, Mon,Year..... And just write the whole array to and from the chip..
You will also need a binary ~ BCD routine and the BCD ~ binary routine as the DS1307 stores the information in BCD format!
C:void bcdBin(char* array) { char x; unsigned char tmp; for(x=0;x<8;x++) { tmp = *array >> 4; tmp *= 10; tmp = tmp + (*array & 0xf); *array++ = tmp; } } void binBcd(char* array) { char x; unsigned char tmp; for(x=0;x<8;x++) { tmp = *array / 10; tmp = tmp << 4; tmp = tmp + (*array % 10); *array++ = tmp; } } void WriteClock(char *array) { char x; for(x=0;x<8;x++) WriteRTC(x,array[x]); } void ReadClock(char *array) { char x; for(x=0;x<8;x++) array[x] = ReadRTC(x); }
From this you should get the idea!!!
8 x 8 memory.Think!.... 56 bytes + 8 registers..... That's an even 64 bytes... It makes perfect sense to me!!
This is going to be hard work..... Just copy the code in tutorial 6... Everything is in there..8 x 8 memory.
making no sense to me!
I read every program cycle ( 3 times a second )
why?
After that connecting the Ds1307 with PIC16f877 with pull up's what to do?
I mean we have to write days times in chip?
#include <pic.h> // pic specific identifiers
#include <stdio.h> // New include file..
#define _XTAL_FREQ 4000000 // Xtal speed
__CONFIG(0x3D18); // Config bits
#define LCD_PORT PORTA // LCD configuration
#define LCD_TRIS TRISA
#define LCD_RS RA4
#define LCD_RW RA6
#define LCD_E RA7
#define I2C_PORT PORTB // I2C port configuration
#define I2C_TRIS TRISB
#define SDAI RB7
#define SCLI RB6
#define SDA TRISB7 // in C we can control the input / output
#define SCL TRISB6 // by one simple command.
#define ErrFlag 0x0 // errors for
#define StartFlag 0x1 // those who wish to use them
#define One 0x2
#define Zero 0x3
#define EEPROM 0xA0 // standard eeprom address fro writing
#define ADC 0x90
#define CHIP_Read 0x01 // and reading
// Required prototypes
void LCD_init(void), LCD_cmd(unsigned char ch), initTimer(void);
void LCD_printC(const char *str), LCD_printR(char *str);
void LCD_goto(char line, char column), LCD_clr(void), DelayMs(int dly);
void LCD_cur(unsigned char ch), pulse_E(void), LCD_hex(int value);
void LCD_char(unsigned char ch), LCD_charD(unsigned char ch);
void I2C_Sendnack(void), I2C_ack(void), I2C_Stop(void), clock(void);
void I2C_Start(void), I2C_Write(unsigned char ch);
void interrupt isr(void);
void read_Mem(void), write_Mem(void), clear_Mem(void), setTime(void);
char I2C_nack(), E_Write(int addr, unsigned char* ch, unsigned char len);
unsigned char I2C_Read(void), E_Read(int addr, char* ch, char len);
int getkey(void), getADC(void);
unsigned char HEX_Table[] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
0x37, 0x38, 0x39, 0x41, 0x42, 0x43,
0x44, 0x45, 0x46};
unsigned char WRITE , run = 1, stop = 1;; // could be ADC or Eeprom
char time_var, time_cnt, timer;
unsigned int e_addr = 0;
unsigned int timer0;
char LcdBuffer[17]; // a screen buffer
unsigned char time[8] = {1,2,5,10,20,50,100,200};
char I2CBuffer[64] ;
// The SDA and SCL pins are ALWAYS set at 0 we use tristated pins to
// control the control.. while SDA and SCL are inputs the external pullup
// resistors give a high conditon whilst when SDA or SCL are outputs
// the control lines are pulled low.
void main(void) // program entry
{
unsigned char key, ch; // key pressed
unsigned char select = 0;
OPTION = 0x88; // timer pre-scaler
CMCON = 0x7; // Comparitors off
LCD_TRIS = 0b00000000; // Led port as outputs
I2C_TRIS = 0b11111111; // I2C port
OPTION = 0b10000101;
__delay_ms(150);
RA6 = 0; // RW low
RB6 = 0;
RB7 = 0;
I2C_PORT = 0;
initTimer();
LCD_init(); // Initalise screen
LCD_printC(" Pic Tutorial.\n Data logger."); // "\n" = newline
while(!getkey());
LCD_clr();
LCD_goto(2,0);
LCD_printC("Menu + - Set");
getADC();
while(1) // endless Loop
{
key = getkey();
LCD_goto(1,0);
switch (select)
{
case 0:
LCD_printC("Write Memory? ");
break;
case 1:
LCD_printC("Read Memory? ");
break;
case 2:
LCD_printC("Set sample time?");
break;
case 3:
LCD_printC("Clear Memory? ");
}
if(key == 2) select++;
if(key == 3) select--;
if(key == 1 || key==4)
{
if(select == 0) write_Mem();
if(select == 1) read_Mem();
if(select == 2) setTime();
if(select == 3) clear_Mem();
}
select &= 3;
}
}
void initTimer()
{
TMR0 = -126;
INTCON = 0b10100000;
timer = 13; //
time_var = time[eeprom_read(0)];
time_cnt = time_var;
run = 0;
stop = 1;
}
void clear_Mem()
{
unsigned int index;
unsigned char ch = 0;
int key;
LCD_goto(1,0);
LCD_printC("Are you sure ");
LCD_goto(2,0);
LCD_printC("No! Yes ");
key = 0;
for(index = 0;index<16; index++)
I2CBuffer[index] = 0;
while(!key)
key = getkey();
if(key==4)
{
WRITE = EEPROM;
LCD_goto(1,0);
LCD_printC("Clearing.... ");
for(index = 0; index < 0x4000; index += 64)
{
E_Write(index,I2CBuffer,64);
DelayMs(5);
}
LCD_goto(1,0);
LCD_printC("Memory cleared ");
DelayMs(1000);
e_addr = 0;
LCD_goto(2,0);
LCD_printC("Menu + - Set");
}
}
void write_Mem()
{
unsigned int index=0;
int key;
LCD_goto(1,0);
LCD_printC("Writing. ");
WRITE = EEPROM;
run = 0;
while(1)
{
getADC();
if(run && !stop)
{
WRITE = EEPROM;
E_Write(index,I2CBuffer,4);
index+=4;
run = 0;
}
LCD_goto(1,11);
sprintf(LcdBuffer,"%d", index);
LCD_printR(LcdBuffer);
LCD_goto(2,0);
sprintf(LcdBuffer,"%3d %3d %3d %3d ", I2CBuffer[1],I2CBuffer[2],I2CBuffer[3],I2CBuffer[0]);
LCD_printR(LcdBuffer);
key = getkey();
if(key == 4)
{
GIE = 0;
stop = 0;
LCD_goto(2,0);
LCD_printC("Menu + - Set");
e_addr = index;
return;
}
if(key==2)
{
stop = 0;
}
if(key==3)
{
stop = 1;
}
}
}
void setTime()
{
unsigned int index;
int key;
LCD_goto(1,0);
LCD_printC("Sample. ");
while(1)
{
LCD_goto(1,9);
sprintf(LcdBuffer,"%d",index);
LCD_printR(LcdBuffer);
key = getkey();
if(key==1 || key == 4)
{
eeprom_write(0,index);
initTimer();
return;
}
if(key == 2) index++;
if(key == 3) index--;
index &= 7;
}
}
void read_Mem()
{
unsigned int index = 0;
int key;
LCD_goto(1,0);
LCD_printC("Reading. ");
WRITE = EEPROM;
while(1)
{
E_Read(index,I2CBuffer,4);
LCD_goto(1,11);
sprintf(LcdBuffer,"%5d", index);
LCD_printR(LcdBuffer);
LCD_goto(2,0);
sprintf(LcdBuffer,"%3d %3d %3d %3d ", I2CBuffer[0],I2CBuffer[1],I2CBuffer[2],I2CBuffer[3]);
LCD_printR(LcdBuffer);
key = getkey();
if(key == 4 || key == 1)
{
LCD_goto(2,0);
LCD_printC("Menu + - Set");
return;
}
if(key==2 && index < (e_addr -4) ) index += 4;
if(key==3 && index > 4) index -= 4;
}
}
int getADC()
{
unsigned char ch;
WRITE = ADC;
ch = 4;
E_Write(0,&ch,1);
E_Read(0,I2CBuffer,4);
}
void interrupt isr()
{
TMR0 = -113;
timer--;
if(timer-- == 0)
{
timer = 13;
if(time_cnt-- == 0)
{
time_cnt = time_var;
run = 1;
}
}
T0IF = 0;
}
// Write to eeprom this returns a 0 if it fails or a 1 if all gooes well
// For byte eeproms and RTC devices.. comment out the Hi address byte
// and the I2C_nack() that follows it in both these functions.
// As you're aware by now there are three kinds of eeprom reads / writes
// we need to combine the three.. Here is how I manage it
// Using the variable "Len" we can adjust, inside the function, which write / read
// we require..
// If len = 0.. We can assume no length so a '0' terminated string is assumed..
// If Len = 1.. We can assume a single (random) read..
// if Len > 1.. we can assume a squential write / read..
char E_Write(int addr, unsigned char* ch, char len)
{
I2C_Start(); // Send a start condition
I2C_Write(WRITE); // chip write address
if(!I2C_nack()) return 0; // wait for ack
if(WRITE == 0xA0)
{
I2C_Write((unsigned char)( addr >> 8 & 0xff));// Not used if out if single byte address
if(!I2C_nack()) return 0; // wait for ack
}
if(!(WRITE==0x90))
{
I2C_Write((unsigned char) addr & 0xff); // low address (ADC not used)
if(!I2C_nack()) return 0; // wait for ack
}
if(len == 1)
{
I2C_Write(*ch);
if(!I2C_nack()) return 0;
}
else if(len > 1)
{
while(len--)
{
I2C_Write(*ch++); // Write values to Eeprom
if(!I2C_nack()) return 0;
}
}
else
{
while(*ch != 0)
{
I2C_Write(*ch++); // Write values to Eeprom
if(!I2C_nack()) return 0;
}
I2C_Write(0); // Write values to Eeprom
if(!I2C_nack()) return 0;
}
I2C_Stop(); // Send a stop.
return 1; // All went well
}
// Returns a 1 for error and 0 for OK.
// The function takes an address and a pointer to a character
unsigned char E_Read(int addr, unsigned char *ch, char len)
{
unsigned char byte;
I2C_Start();
I2C_Write(WRITE);
if(!I2C_nack()) return 1; // Whoops!! problems
if(WRITE == 0xA0)
{
I2C_Write((unsigned char)( addr >> 8 & 0xff));// Not used if out if single byte address
if(!I2C_nack()) return 1;
}
if(!(WRITE == 0x90))
{
I2C_Write((unsigned char) addr & 0xff); // not use with ADC
if(!I2C_nack()) return 1;
}
I2C_Start();
I2C_Write(WRITE + CHIP_Read); //
if(!I2C_nack()) return 1;
if(len == 1) // Read a single char.
{
*ch = I2C_Read();
}
else if(len > 1) // Read a sequential data steam
{
while(len-- > 1)
{
*ch++ = I2C_Read(); // read character
I2C_ack(); // Send ack
}
*ch = I2C_Read();
}
else // Read s NULL string
{
do{
*ch = I2C_Read();
I2C_ack();
}while(*ch++ != 0);
*ch = I2C_Read();
}
I2C_Sendnack(); // send nack
I2C_Stop(); // send stop
return 0;
}
void I2C_Start() // start combo
{
SDA = 1;
SCL = 1;
SDA = 0; // bring SDA low while SCL is high
SCL = 0;
}
void I2C_Stop() // stop combo
{
SCL = 0;
SDA = 0;
SCL = 1;
SDA = 1; // bring SDA high while SCL is high
}
unsigned char I2C_Read()
{
char index;
unsigned char byte = 0; // initialize in byte
for(index = 0x80; index > 0 ;index>>=1) // using index as a mask
{ // cycles through bit 7 to bit 0
if(SDAI) byte += index; // read in the SDA line
clock();
}
return byte; // 8 bits in...
}
void I2C_Write(unsigned char ch)
{
char index;
for(index = 0x80; index > 0 ;index>>=1) // using index as mask
{
if(ch & index) // bit high or low
SDA = 1;
else
SDA = 0;
clock();
}
}
void I2C_ack() // generate an ack
{
SDA = 0;
clock();
SDA = 1;
}
void I2C_Sendnack() // generate a not ack
{
SDA = 1;
clock();
}
char I2C_nack() // recive a not ack
{
unsigned char timeout = 255;
SDA = 1;
SCL = 1;
while(SDAI) // wait till SDA goes low
{
if(timeout-- == 0) return 0; // whoops!! no ack recieved
}
SCL = 0;
return 1;
}
void clock() // Might work without the nop
{
SCL=1;
asm("nop");
SCL=0;
}
int getkey() // read keypad
{
int key = 0;
if(!RB0) key = 1;
if(!RB1) key = 2;
if(!RB2) key = 3;
if(!RB3) key = 4;
if(key)
DelayMs(400);
return key;
}
void DelayMs(int dly)
{
while(dly--)
__delay_ms(1);
}
// In C we can use Pointers, Pointers are advanced programming
// and can tie you in knots. The simplest pointer to use is the
// array pointer using "rom char" allows the pointer to
// point to constant character in code section.
void LCD_printC(const char * str) // This passes the start a ROM character array
{ // by default the pointer points to data section
while(*str != 0) // while the character pointed to isn't 0
{
if(*str == 0x0A)
LCD_goto(2,0); // if a new line goto a newline
else
LCD_char(*str);
str++; // print out the character, then increment
}
} // the pointer down the array
void LCD_printR(char * str) // This passes the start of a RAM character array
{ // by default the pointer points to data section
while(*str != 0) // while the character pointed to isn't 0
LCD_char(*str++); // print out the character, then increment
} // the pointer down the array
void LCD_init()
{
LCD_PORT = 2; // I decided to write the first command
LCD_RS = 0; // manually, as the busy flag can't be read
pulse_E(); // on the first instruction
__delay_ms(50);
LCD_PORT = 2;
LCD_RS = 0;
pulse_E();
__delay_ms(50); // busy should be available now..
//LCD_cmd(0x20); // 4 bit
LCD_cmd(0x28); // display shift
LCD_cmd(0x6); // character mode
LCD_cmd(0xc); // display on / off and cursor
LCD_clr(); // clear display
}
void LCD_hex(int value)
{
char data;
data = value >> 4 & 0xf;
data = HEX_Table[data]; // send upper nibble
LCD_char(data);
data = value & 0xf; // send lower nibble
data = HEX_Table[data];
LCD_char(data);
}
void LCD_goto(char line, char column) // combines line and lineW
{
unsigned char data = 0x80; // default to 1
if(line == 2)data = 0xc0; // change to 2
data += column; // add in column
LCD_cmd(data);
}
void LCD_clr()
{
LCD_cmd(1); // Clr screen
}
void LCD_cur(char on)
{
unsigned char cur = 0xc; // cursor off
if(on) cur = 0xd; // cursor on
LCD_cmd(cur);
}
void LCD_cmd(unsigned char ch)
{
LCD_PORT = ch >> 4 & 0xf;
LCD_RS = 0;
pulse_E();
LCD_PORT = ch & 0xf;
LCD_RS = 0;
pulse_E();
__delay_ms(5);
}
void LCD_charD(unsigned char ch)
{
ch+=0x30;
LCD_char(ch);
}
void LCD_char(unsigned char ch)
{
LCD_PORT = ch >> 4 & 0xf;
LCD_RS = 1;
pulse_E();
LCD_PORT = ch & 0xf;
LCD_RS = 1;
pulse_E();
__delay_ms(5);
}
void pulse_E()
{
LCD_E = 1;
__delay_us(1);
LCD_E = 0;
}
hahaha....If you want the hardware I2C routines just ask!!!
???? Not sure I follow...hahaha....
You think the answer is at the bottom of a bottle of Jack Daniels?
Bottle of Jack with some truth serum (sodium pentothol) -- in it? I invite everyone on this forum to come and drink with me! Nothing to worry about unless you are an paedophile.Hehe, the answer I usually find at the bottom of a bottle of Jack is "never again", I move onto the Bowmore and all is fine again![]()
Hi Tech C? What did you shell out USD 3K for it did you? I thought the FREE version did not handle the 16F series PICs. MikroC is a good buy for USD 249. I was tempted to purchase Hi Tech many years back on eBay... Too rich for me. Although I did pay AUD 1,500 for circuit maker 2000, and a couple of grand for QuarkXPress... But back in those days I had money. Now I am as poor as an ****-house rat.Hello,
I will use 7 segment LED display..
only min and hours.
so, how to start in Hi tech c i have done i2C based project in BLDC ESC motor.