Pic18f2420 to DS1377 RTC  - Page 1
Forum section: electronics / general

author: kolbep
author_rank: Frequent Contributor
timestamp: March 17, 2015, 08:28:12 pm
content: Hi All.This one has been plaguing me for 2 evenings now.I have a Pic18F2420, and a DS1377 RTC.The DS1377 is running fine (its default is to have sqw output at the Crystal frequency (which is 32.768Khz. I confirmed that this output is spot on with a frequency counter.I have connected it to my PIC micro, and can scope data on the I2C Clock and data lines, (Analogue scope, so just catch a blip of it, but I can see that it is a clocked signal).But I cannot get the RTC to change its SQW output to be anything other than the default.I have even tried to make the bar EOSC register high, to shutdown the oscillator, but nothing, nada.I have even tried it on 2 different breadboards, as well as a prototyping board, with the same results. It is like the RTC chip is ignoring me.Please can you check over my code, and see if anything obvious stands out. I have set the PIC18f2420 Oscconbits for the oscillator to run direct off the builtin 8mhz oscillator.Thanking you all in advance ...Code:/** File: BigClock1.c* Author: Peter** Created on 15 March 2015, 18:29*/// PIC18F2420 Configuration Bit Settings// 'C' source line config statements#include <p18F2420.h>// CONFIG1H#pragma config OSC = INTIO67 // Oscillator Selection bits (Internal oscillator block, port function on RA6 and RA7)#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)// CONFIG2L#pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)#pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)#pragma config BORV = 3 // Brown Out Reset Voltage bits (Minimum setting)// CONFIG2H#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)// CONFIG3H#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)#pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)// CONFIG4L#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)#pragma config LVP = ON // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))// CONFIG5L#pragma config CP0 = OFF // Code Protection bit (Block 0 (000800-001FFFh) not code-protected)#pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) not code-protected)// CONFIG5H#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)// CONFIG6L#pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) not write-protected)#pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) not write-protected)// CONFIG6H#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)// CONFIG7L#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)// CONFIG7H#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)#include <stdio.h>#include <stdlib.h>#include <p18f2420.h>#include <timers.h>#include <delays.h>#include <i2c.h>#include "xlcd.h"void DelayFor18TCY( void ){Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();}void DelayPORXLCD (void){Delay1KTCYx(60); // Delay of 15msreturn;}void DelayXLCD (void){Delay1KTCYx(20); // Delay of 5msreturn;}void ds1307_write(unsigned char reg, unsigned char data){unsigned char stat;IdleI2C(); /* wait for an idle bus */StartI2C(); /* send START bit */while (SSPCON2bits.SEN); /* wait till START is sent */WriteI2C(0xd0); /* DS1377 WriteI2C address */AckI2C(); /* Slave ACK */WriteI2C(reg); /* Slave register address */AckI2C();WriteI2C(data); /* data */AckI2C();RestartI2C();while (SSPCON2bits.PEN); /* wait till STOP is sent */}void ds1307_read(unsigned char reg, unsigned char *data){unsigned char i;IdleI2C();StartI2C();while (SSPCON2bits.SEN);WriteI2C(0xd1);AckI2C();WriteI2C(0x00);AckI2C();StartI2C();while (SSPCON2bits.SEN);WriteI2C(0xd1);AckI2C();*data = ReadI2C();StopI2C();while (SSPCON2bits.PEN);}void ds1307_init(void){ds1307_write(0xE0, 0xFF); //SETTING BIT 7 (BAR EOSC) SHOULD TURNOFF}void main(void) {OSCCONbits.IRCF0=1; //8MhzOSCCONbits.IRCF1=1;OSCCONbits.IRCF2=1;ADCON1 = 0x0f;LATA=0x00;LATB=0x00;LATC=0x00;TRISA = 0x00;TRISB = 0x00;TRISC = 0xFF; //Port C is inDelay10KTCYx(20);while( BusyXLCD() );OpenXLCD( FOUR_BIT & LINES_5X7);WriteCmdXLCD( BLINK_OFF & CURSOR_OFF);WriteCmdXLCD( SHIFT_DISP_LEFT );putrsXLCD("DISPLAY IS ON");OpenI2C(MASTER, SLEW_OFF); /* I2C Master */SSPADD = 0x13; /* 100khz @ 8MHz */ds1307_init();while(1);}

author: dannyf
author_rank: Super Contributor
timestamp: March 17, 2015, 09:01:29 pm
content: The usual suspects:1) make sure that your i2c modules are set up correct;2) make sure that the slave address is right and consistent with your i2c routine's notation. For example, some routines use the 8-bit notion for slave address, 0b11010000, under such an approach, would be 0xd0; vs. 0x48 under the 7-bit notion.3) I like the way you broke up the write/read functions but I am pretty sure that your read function has the incorrect timing. The typical approach to read from a given address is to first initiate a write approach to that address. Just before you actually write to that address - so you move the current data pointer to the desired address, you stop and restart the i2c transmission in read mode.4) I don't know what AckI2C() does but masters typically don't acknowledge a transmission - it does Non-ack at the end of a transmission.5) your code actually didn't attempt to change SQWE bit.

author: kolbep
author_rank: Frequent Contributor
timestamp: March 17, 2015, 09:12:15 pm
content: Thanks for the reply.I am using somebody else's routine, and they did have it working.I will have to look into the i2c libraries to see how they have address formatted,,,Originally I was trying to change the square wave output frequency, but then I thought I must just try to shut the rtc oscillator down, to check comms, which is on the unit function I set all the bits of 0x0e to 1, just because if the 7th bit is high, then it's oscillator should stop, which it wasnt .I will check again tomorrow cos it is late here now, and I am replying on my cell...

author: dannyf
author_rank: Super Contributor
timestamp: March 17, 2015, 10:16:09 pm
content: Here is what I have, working on realy ds1307:Code://send byte to ch on ds1307void ds1307_write(unsigned char ch, unsigned char byte_t) {i2c_start();//send the start conditioni2c_write(DS1307_I2C_ID | I2C_CMD_WRITE);//send the device idi2c_write(ch);//send the channeli2c_write(byte_t);//send the datai2c_stop();}//read from ds1307unsigned char ds1307_read(unsigned char ch) {unsigned char dat;i2c_start();//start conditioni2c_write(DS1307_I2C_ID | I2C_CMD_WRITE);//second the idi2c_write(ch);//send the channeli2c_restart();//restarti2c_write(DS1307_I2C_ID | I2C_CMD_READ);//send the read commanddat=i2c_read(I2C_NOACK);//read from ds1307, no acknowledgementi2c_stop();return dat;}You may not have the same routines but it should give you a gist of what needs to be done.

author: SL4P
author_rank: Super Contributor
timestamp: March 17, 2015, 10:23:25 pm
content: also, a general coding comment...while (anything);... is fine, but you should always consider the break condition mayneveroccur...adding a loop counter or other mechanism may save you from hard resets or some other construct to pull the program out of an infinite loop.cheers

author: Wilksey
author_rank: Super Contributor
timestamp: March 17, 2015, 10:26:25 pm
content: Do you have the pull-ups on the I2C lines?

author: dannyf
author_rank: Super Contributor
timestamp: March 17, 2015, 10:39:44 pm
content: I put it through the simulator and here is what your code did.So ds1307_init() sent the right i2c address (0xd0), and then wrote 0xbf to 0x70, when you wanted to send 0xff to 0xe0.

author: dannyf
author_rank: Super Contributor
timestamp: March 17, 2015, 11:22:16 pm
content: I can confirm for you that commenting out the acki2c() in the write routine allowed the 0xff to be sent to 0xe0.The original code is not correct.

author: kolbep
author_rank: Frequent Contributor
timestamp: March 18, 2015, 05:27:53 am
content: I do have pullups on there.Thanks for the simulation of the code. What software did you use for that?I will try later on (removing the ACK's) and see.P

author: kolbep
author_rank: Frequent Contributor
timestamp: March 18, 2015, 05:47:02 am
content: Ok,I got rid of their code (well, just did not call it).What I did now in my main() was the following :Code:OpenI2C(MASTER, SLEW_OFF); /* I2C Master */SSPADD = 0x13; /* 100khz @ 8MHz */StartI2C();while (SSPCON2bits.SEN);IdleI2C();WriteI2C(0xd0);IdleI2C();WriteI2C(0x0E);IdleI2C();WriteI2C(0xFF);StopI2C();while (SSPCON2bits.PEN);And that worked. I thought I would never be so happy at watching my scope trace dissapear. For a second there, I actually checked my scope leads to make sure they were still in place.If I change the output to that register to 0x00, now it is flashing the LED at 1HZ! Hooray.Now to start asking the RTC Questions..P

author: kolbep
author_rank: Frequent Contributor
timestamp: March 18, 2015, 06:08:06 am
content: and here is a pic of the Work in progress...