• AVR Freaks

AnsweredHot!Interfacing DS1302 with dsPIC33FJ128GP802

Page: 12 > Showing page 1 of 2
Author
Esmat
New Member
  • Total Posts : 29
  • Reward points : 0
  • Joined: 2009/06/14 09:41:13
  • Location: 0
  • Status: offline
2019/01/15 19:55:16 (permalink)
0

Interfacing DS1302 with dsPIC33FJ128GP802

I am not able to write/read data into/from the RTC DS1302. So I wrote a code just to write and read one single byte.The code is adopted from the many codes that are published in this forum. They all agree on that: to write a byte you pulse the clock to high; and to read a byte you pulse the clock from high to low. I believe this is what I did in my code.  Yet, the answer I always get is 0. I am attaching the files I coded with the post. It is appreciated if someone could hint to why I am not able to program the RTC correctly. Thank you. 
#1
AMPS
Super Member
  • Total Posts : 392
  • Reward points : 0
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/15 20:00:34 (permalink)
0
Is it possible to share logical analyzer output of SDA and SCL line. Also send schematic diagram  how you have connected

Amps
*.*.*.*.*.*.*.*.*.*.*.*.*
#2
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/15 20:18:11 (permalink) ☼ Best Answerby Esmat 2019/01/17 12:07:11
0
Nowhere in this code do you set the CE or SCLK pins to output mode.
 

Nearly there...
#3
Esmat
New Member
  • Total Posts : 29
  • Reward points : 0
  • Joined: 2009/06/14 09:41:13
  • Location: 0
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/17 12:16:42 (permalink)
0
qhb, Thank you for your reply. I have defined SCLK and CE in the DS1302.h file. Then in the file DS1302.c in the functions readOneByte() and writeOneByte()  CE are set on then off. Also in the functions rbyte_3w() and wbyte_3w() SCKL are turned on and off as required by datasheet. Would you please explain more what your remark mean? Thank you for your time.
#4
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/17 12:23:24 (permalink)
0
In a PIC, all pins power up in input mode.
Any pin that you want to act as an output must be switched to output mode via the matching TRIS register. That is YOUR job as a programmer. You are not doing it in this code.

Nearly there...
#5
Esmat
New Member
  • Total Posts : 29
  • Reward points : 0
  • Joined: 2009/06/14 09:41:13
  • Location: 0
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/17 14:47:52 (permalink)
0
qgb, Thanks for the reply. In the file DS1302.c I set TRIS to 0 for the output mode and set TRIS to 1 in the output mode. Is it what you meant?
#6
du00000001
Just Some Member
  • Total Posts : 2703
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/17 14:57:46 (permalink)
0
@ Esmat
Set TRIS to 0 for the SCLK and CE signals permanently! (controlling them via the value of LAT)
For the data line you are right (beyond the typo):
  • Set TRIS to 0 when intending to write (transmit).
  • Set TRIS to 1 when intending to read (receive).

PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
#7
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/17 15:01:26 (permalink)
0
In DS1302.c, "TRIS" is defined as follows
#define TRIS    TRISBbits.TRISB8

That is manipulating one bit of one of the TRIS registers. There is a TRIS register for each port.
TRISA, TRISB, and so on, and each bit in each register controls the direction of one pin.
It is a bit confusing that the code author used the name TRIS here. They are just switching the direction of the data pin, because the code uses it to both read and write.
Nothing in that code controls the direction of the CE or CLK pins. If you do nothing, then they will be inputs, so you can't control them.
Setting TRIS registers is an absolutely fundamental part of programming a PIC. Read that part of the datasheet again.
 
 

Nearly there...
#8
Esmat
New Member
  • Total Posts : 29
  • Reward points : 0
  • Joined: 2009/06/14 09:41:13
  • Location: 0
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/17 16:29:54 (permalink)
0
du00000001 & qhb Thank you so much for your time. I modified my code as follows: In DS1302.h file I have defined
#define TRIS_CLK TRISBbits.TRISB7
#define TRIS_IO TRISBbits.TRISB8
#define TRIS_CE TRISBbits.TRISB9
#define SCLK LATBbits.LATB7
#define IO LATBbits.LATB8
#define IN PORTBbits.RB8
#define CE LATBbits.LATB9
and in DS1302.c I added these lines:
TRIS_CLK = 0 ;
TRIS_CE = 0 ;
I ran the program and, sadly, I am still reading 0. I do appreciate your time.
 
#9
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/17 16:37:15 (permalink)
0
Esmat
.and in DS1302.c I added these lines:
TRIS_CLK = 0 ;
TRIS_CE = 0 ;

WHERE did you add them?
Do you have a scope or logic analyser to observe what the signals are doing?
 

Nearly there...
#10
Esmat
New Member
  • Total Posts : 29
  • Reward points : 0
  • Joined: 2009/06/14 09:41:13
  • Location: 0
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/17 17:22:22 (permalink)
0
This is the entire .c fie
#include "D:\Microchip\DS1302\DS1302.h"
_FBS(BWRP_WRPROTECT_OFF & BSS_NO_BOOT_CODE & RBS_NO_BOOT_RAM);
_FSS(SWRP_WRPROTECT_OFF & SSS_NO_SEC_CODE & RSS_NO_SEC_RAM );
_FGS(GWRP_OFF & GSS_OFF);
_FOSCSEL(FNOSC_FRC & IESO_ON);
_FOSC(POSCMD_NONE & OSCIOFNC_OFF & IOL1WAY_OFF & FCKSM_CSECMD);
_FWDT(WDTPOST_PS32768 & WDTPRE_PR128 & WINDIS_OFF & FWDTEN_OFF);
_FPOR(FPWRT_PWR128 & ALTI2C_OFF);
_FICD(ICS_PGD3 & JTAGEN_OFF);
/* */
/* Test DS1302 */
/* */
int main (void)
{
char ClkWr = 0x82 ;
char ClkRd = 0x83 ;
char ClkData = 0x0F ;
char data, Data[2]="" ;
ADPCFG = 0xFFFF ;// configure all analog pins as digital
TRIS_CLK = 0 ;
TRIS_CE = 0 ;
writeData(0x8e,0x00) ;// control register disable write protect
writeData(0x90,0x5c) ;// trickle charger initial setup
writeData(ClkWr,ClkData) ;
readData( ClkRd,&data) ;
Data[0]=data ;
while (1) ;
}
 
#11
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/17 18:27:04 (permalink)
0
Just looking at your low level code, your "write" routine looks a bit wrong, in that it leaves the clock liine high afterwards.
Rather than:
    for(i = 0; i < 8; ++i)
    {
        SCLK = 0            ;
        __delay_us(2)        ;//Delay 2us
           IO = W_Byte & 0x01    ;
        SCLK = 1            ;//set port pin high to write data
        __delay_us(2)        ;//Delay 2us
        W_Byte >>= 1        ;
    }

Try:
    for(i = 0; i < 8; ++i)
    {
        IO = W_Byte & 0x01    ;
        __delay_us(1)        ;//Delay 1us
        SCLK = 1            ;//raise clock to latch data
        __delay_us(1)        ;//Delay 1us
        SCLK = 0            ;
        W_Byte >>= 1        ;
    }

 
And your read routine looks very inefficient, and samples the data when clock is low, when you should do it when clock is high.
Rather than:
    for(i = 0; i < 8; i++)
    {
        SCLK     = 1            ;
        __delay_us(2)        ;//Delay 2us
        SCLK     = 0            ;//set port pin low to read data
        __delay_us(2)        ;//Delay 2us
        tmp        = IN        ;
        tmp   <<= 7            ;
        *data  >>= 1        ;
        *data   |= tmp        ;
    }

Try:
    for(i = 0; i < 8; i++)
    {
        SCLK     = 1            ;raise clock
        __delay_us(1)        ;//Delay 1us (CLK high, waiting for IN to settle)
        *data  >>= 1        ;shift right. MSB will now be zero
        if (IN)
            *data |= 0x80;    //set MSB if data pin is high
        SCLK     = 0            ;//drop clock
        __delay_us(1)        ;//Delay 1us (CLK low)
    }


Nearly there...
#12
Esmat
New Member
  • Total Posts : 29
  • Reward points : 0
  • Joined: 2009/06/14 09:41:13
  • Location: 0
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/17 20:37:12 (permalink)
0
This is my new code after implementing your suggestions. 
/* ------ write one byte to the device ------- */
void writeOneByte(char W_Byte)
{
char i ;
TRIS_IO = 0 ;// Set TRIS_IO as output
for(i = 0; i < 8; ++i)
{
IO = W_Byte & 0x01 ;
__delay_us(1) ;//Delay 2us
SCLK = 1 ;//set port pin high to write data
__delay_us(1) ;//Delay 2us
SCLK = 0 ;
W_Byte >>= 1 ;
}
}
/* ------- read one byte from the device -------- */
void readOneByte(char *data)
{
// Data is written in by the RTC at the falling edge of SCLK.
// To read data, pulse the clock and read IO.
char i, tmp ;
TRIS_IO = 1 ;// Set TRIS_IO as inpu
*data = 0x00 ;
for(i = 0; i < 8; i++)
{
SCLK = 1 ;
__delay_us(1) ;//Delay 2us
*data >>= 1 ;
if(IN)
*data |= 0x80 ;
SCLK = 0 ;//set port pin low to read data
__delay_us(1) ;//Delay 2us
}
}
/* --- write one byte using values entered by user --- */
void writeData(char ClkAdd, char ClkData)
{
/* Get Clock Address & Data */
CE = 1 ;
writeOneByte(ClkAdd) ;
writeOneByte(ClkData) ;
CE = 0 ;
}
void readData(char ClkAdd, char *data)
{
CE = 1 ;
writeOneByte(ClkAdd) ;
readOneByte(data) ;
CE = 0;
}
 
 
the code still reads 0. I am very grateful for your time.
#13
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/17 20:39:35 (permalink)
0
You never answered if you have access to a scope or logic analyser.

Nearly there...
#14
Esmat
New Member
  • Total Posts : 29
  • Reward points : 0
  • Joined: 2009/06/14 09:41:13
  • Location: 0
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/18 12:03:12 (permalink)
0
qhb, I am grateful beyond all bounds. I could not go to sleep and I walk up at 2 Am but I finally got it to work. I have to do 2 modifications: the first is that I modified the for loop in the readOneByte() from
for(i = 0; i < 8; i++)
{
SCLK = 1 ;
__delay_us(1) ;//Delay 2us
*data >>= 1 ;
if(IN)
*data |= 0x80 ;
SCLK = 0 ;//set port pin low to read data
__delay_us(1) ;//Delay 2us
}
 
to
 
for(i = 0; i < 8; i++)
{
*data >>= 1 ;
SCLK = 1 ;
__delay_us(1) ;//Delay 2us
if(IN)
*data |= 0x80 ;
SCLK = 0 ;//set port pin low to read data
__delay_us(1) ;//Delay 2us

that is I moved the *data >>= 1 ; to the top of the for loop. I don't know why this should make a difference but this is the way it works. The second modification is that I converted all char variables to unsigned char. The reason is that if we have a byte that has 1 in MS bit(7th bit) and we shift it to the right, it will trail the replaced by 1. So even though the hardware is working correctly the output data will not be correct.
The oscilloscope I have is the digital type.
I need to move forward and see if I can enter time data and reed them back. Thank you so much for your time.
#15
du00000001
Just Some Member
  • Total Posts : 2703
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/18 12:37:12 (permalink)
4 (1)
I don't think moving the shift operation had any effect - the key was certainly the change from signed to unsigned.

PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
#16
Esmat
New Member
  • Total Posts : 29
  • Reward points : 0
  • Joined: 2009/06/14 09:41:13
  • Location: 0
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/18 19:08:51 (permalink)
0
du00000001, I agree with you that moving the shift operation should not have any effect. So I went back and put where it was, but I got 0 outputs again. Move it up did the trick. I have no explanation.
#17
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/18 22:44:19 (permalink)
0
It must just mean you need a bit more delay right there.
Try putting another 1us delay before the SCLK=1 instead of the shift.
 
 

Nearly there...
#18
du00000001
Just Some Member
  • Total Posts : 2703
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/19 01:48:47 (permalink)
0
Oh! Is there some minimum delay between asserting CE and the start of SCLK activity?
Or between subsequent bytes?
(I didn't check with the ds.)
post edited by du00000001 - 2019/01/19 01:50:38

PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
#19
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Interfacing DS1302 with dsPIC33FJ128GP802 2019/01/19 02:29:32 (permalink)
0
du00000001
Oh! Is there some minimum delay between asserting CE and the start of SCLK activity?

Yes, parameter "Tcc" is 1us between CE rising and the first clock rise, if Vcc = 5V, it increases to 4us at Vcc=2V

Nearly there...
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2019 APG vNext Commercial Version 4.5