Wilksey
Joined: 14 Aug 2011 Posts: 36 Location: Somerset, UK
|
CCS C 4.120 + PIC18F26K22 + DS1307 |
Posted: Fri Aug 19, 2011 5:41 pm |
|
|
Hi Gurus!
I have an issue, I tried to use the DS1307 driver here, and it wont get past the ds1307_init() call.
What am I doing wrong?! I am using internal oscillator btw, SDA and SCL both pulled up to +5V with 10k pullups. Please ignore the comments, this is just purely for testing!
main.h
Code: |
#include <18F26K22.h>
#device adc=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPLLEN //4X HW PLL disabled, 4X PLL enabled in software
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES IESO //Internal External Switch Over mode disabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES MCLR //Master Clear pin used for I/O
#FUSES NOSTVREN //Stack full/underflow will not cause reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(clock=8MHz)
#use rs232(baud=38400,parity=N, UART1, bits=8,stream=ILIGHT_PC)
#use rs232(baud=38400,parity=N, UART2, bits=8,stream=ILIGHT_TFU)
#define ts_1_val1 = 0x00
#define ts_1_val2 = 0x01
#define ts_1_val3 = 0x02
#define ts_1_val4 = 0x03
#define ts_1_val5 = 0x04
#define ts_1_val6 = 0x05
#include "DS1307.C"
void ds1307_init(void);
void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec);
|
main.c
Code: |
#include <main.h>
void main()
{
char recbyt = 0;
BYTE hr = 0;
BYTE min = 0;
BYTE sec = 0;
setup_timer_0(T0_OFF);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_timer_4(T4_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
setup_ccp3(CCP_OFF);
setup_ccp4(CCP_OFF);
setup_ccp5(CCP_OFF);
setup_dac(DAC_OFF);
setup_adc(ADC_OFF | NO_ANALOGS);
ds1307_init(); //Hangs here!
while(1)
{
//Never gets here.
//ds1307_get_time(hr, min, sec);
//fprintf(ILIGHT_PC, "Hour: %i, Min: %i, Seconds: %i\r\n", hr, min, sec);
delay_ms(1000);
fprintf(ILIGHT_PC, "Test123\r\n");
}
}
|
ds1307.c
Code: |
////////////////////////////////////////////////////////////////////////////////
/// 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 ///
/// ///
////////////////////////////////////////////////////////////////////////////////
#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));
}
|
Any help appreciated, I'm sure I'm missing something simple, just can't see what!
Wilksey |
|