#include <16F876a.h>
#include <ds1307.h>
#fuses NOWDT,XT, PUT, NOPROTECT, BROWNOUT ,NODEBUG ,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_A0,rcv=PIN_A1,bits=8)
#zero_ram
int DATE,MTH,YR,HR,MT,SECDS,DOW; //
void main() {
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
ds1307_init();
while(1){
ds1307_get_time(HR,MT,SECDS);
ds1307_get_date(DATE,MTH,YR,DOW);
printf("\rTime %2D:%02D:%02D",HR,MT,SECDS);
printf(" Date %2D/%02D/%02D",DATE,MTH,YR);
delay_ms(100);
if(!input(PIN_C0 ))
ds1307_set_date_time(28,1,8,2,11,50,0); // Time 11:50:00 Date 28/01/08
}
}
//////////////////////////////////////////////////////////////////////////////////
/// DS1307.C ///
/// Driver for Real Time Clock ///
/// ///
/// ds1307_init() - Enable oscillator without clearing the seconds register -///
/// used when PIC loses power and DS1307 run from 3V BAT ///
/// - Disable squarewave output ///
/// ///
/// ds1307_set_date_time(day,mth,year,dow,hour,min,sec) Set the date/time ///
/// ///
/// ds1307_get_date(day,mth,year,dow) Get the date ///
/// ///
/// ds1307_get_time(hr,min,sec) Get the time ///
/// ///
////////////////////////////////////////////////////////////////////////////////
#use delay(clock=4000000)
#define RTC_SDA PIN_C4
#define RTC_SCL PIN_C3
#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)
BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);
void ds1307_init(void)
{
BYTE seconds = 0;
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x00); // REG 0
i2c_start();
i2c_write(0xD1); // RD from RTC
seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307
i2c_stop();
seconds &= 0x7F;
delay_us(3);
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x00); // REG 0
i2c_write(bin2bcd(seconds)); // Start oscillator with current "seconds value
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x07); // Control Register
i2c_write(0x80); // Disable squarewave output pin
i2c_stop();
}
void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec)
{
sec &= 0x7F;
hr &= 0x3F;
i2c_start();
i2c_write(0xD0); // I2C write address
i2c_write(0x00); // Start at REG 0 - Seconds
i2c_write(bin2bcd(sec)); // REG 0
i2c_write(bin2bcd(min)); // REG 1
i2c_write(bin2bcd(hr)); // REG 2
i2c_write(bin2bcd(dow)); // REG 3
i2c_write(bin2bcd(day)); // REG 4
i2c_write(bin2bcd(mth)); // REG 5
i2c_write(bin2bcd(year)); // REG 6
i2c_write(0x80); // REG 7 - Disable squarewave output pin
i2c_stop();
}
void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x03); // Start at REG 3 - Day of week
i2c_start();
i2c_write(0xD1);
dow = bcd2bin(i2c_read() & 0x7f); // REG 3
day = bcd2bin(i2c_read() & 0x3f); // REG 4
mth = bcd2bin(i2c_read() & 0x1f); // REG 5
year = bcd2bin(i2c_read(0)); // REG 6
i2c_stop();
}
void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x00); // Start at REG 0 - Seconds
i2c_start();
i2c_write(0xD1);
sec = bcd2bin(i2c_read() & 0x7f);
min = bcd2bin(i2c_read() & 0x7f);
hr = bcd2bin(i2c_read(0) & 0x3f);
i2c_stop();
}
BYTE bin2bcd(BYTE binary_value)
{
BYTE temp;
BYTE retval;
temp = binary_value;
retval = 0;
while(1)
{
// Get the tens digit by doing multiple subtraction
// of 10 from the binary value.
if(temp >= 10)
{
temp -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += temp;
break;
}
}
return(retval);
}
// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
BYTE temp;
temp = bcd_value;
// Shifting upper digit right by 1 is same as multiplying by 8.
temp >>= 1;
// Isolate the bits for the upper digit.
temp &= 0x78;
// Now return: (Tens * 8) + (Tens * 2) + Ones
return(temp + (temp >> 2) + (bcd_value & 0x0f));
}
sadat007 said:Hi. elizabeth
I wish to start properly programming in C but until now I have quite good setup of BASIC compilers and also quite happy with them.
Sorry I could not help u in this..... may be some one else on this forum will do.
For the Proteus yes I have 7.2 but no DS1337. Remember, using DS1337 is very simple just search DS1337.exe on edaboard and you will find my program that will help u a lot in setting the DS1337
If you like I can put here some codes in mikroBasic regarding interrupt and DS1337 handling.
Note that DS1337 and DS1307 are same for date/time writing and reading.
Thanks
sadat007
sadat007 said:Hi,
Please do not ask for copyrighted software. it will be good to edit your post a little.
It is really hard for me to help you as I used mikroBasic, PIC18F4525 and DS1337. So here I am trying to explain you and you will have to implement by your self in CCS.
Please try my program DS1337.exe
Hope this will help u a lot.
Thanks
Sadat007
:arrow::arrow::arrow::!::?::?::idea::idea:
In 16F877 there is one external interrupt INT on RB0 (pin-33 of DIP)
The bit-6 (INTEDG) of OPTION_REG will decide
1 = Interrupt on rising edge of RB0/INT pin
0 = Interrupt on falling edge of RB0/INT pin
I think it should be set to Zero
The bit-7 (RBPU) of OPTION_REG will decide
1 = PORTB pull-ups are disabled
0 = PORTB pull-ups are enabled by individual port latch values
I recommend u to put zero here and connect one external 10k pullup resistor on RB0/INT pin.
Now in INTCON REGISTER
GIE (bit-7) =0 to disable all interrupts and 1= all enable it
INTE (bit-4) =0 to disable INT and 1= all enable it
INTF (bit-1) =1 means The RB0/INT external interrupt occurred (must be cleared in software)
and =0 means external interrupt did not occur. This bit should be check to verify that the INT occurred
and should be clear after all routines performed (that need to be performed).
/////////////////////////////////////////////
interrupt sub routine
check for which interrupt occurred in your case it can be INT
so check for INTF flag/bit as described above
so finally if the if INTF=1 then u can call a routine of reading and comparing
the time and if matched generate an alarm
Also that it may be required to clear the bit INTCON.INTF = 0 when all done
///////////////////////////////
Writing to DS1307
I2C_Start
I2C_WR($D0) 'I2C address 1101000 of DS1307 for writing mode Please recheck it
I2C_WR(pointer) 'normally pointer=0 which is the address of seconds
'following 3 lines may not be required
I2C_Repeated_Start
I2C_WR($D0) 'I2C address 1101000 of DS1307 for writing mode Please recheck it
I2C_WR(pointer) 'normally pointer=0 which is the address of seconds
I2C_WR(Seconds)
I2C_WR(Minutes)
I2C_WR(Hours)
I2C_WR(Day Of Week)
I2C_WR(DATE)
I2C_WR(Month)
I2C_WR(YEAR)
I2C_WR(10) '1Hz enabled 10 is in HEX
I2C_Stop
////////////////////////////////////
Reading DS1307
I2C_Start
I2C_Wr($D0) 'I2C address 1101000 of DS1307 for WRITING mode Please recheck it
I2C_Wr($00) 'normally pointer=0 which is the address of seconds
I2C_Repeated_Start
I2C_Wr($D1) 'I2C address of DS1307 for READING mode Please recheck it
Sec = I2C_Rd(1)
........
.........
...........
read one by one up to year
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?