PDA

View Full Version : DS1302 Problem, again :(



CuriousOne
- 13th January 2014, 16:36
Hello.

I'm fighting with bloody DS1302 and PICBASIC PRO, but have no luck.

I have DS1302 assembled on separate PCB with backup battery, and using Chris Savage's code on Basic Stamp, it runs just fine, time is OK, everything is OK. But, when I decided to use it with picbasic pro, it does not works.

I have PIC16F870 and the simple code is below, I've shorted it quite much, because DS1302 is already preset and no need for time programming:



include "MODEDEFS.BAS"
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 1
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 1500
DEFINE LCD_DATAUS 44
define OSC 4


' ** Declare the Variables **


B0 VAR BYTE
B1 VAR BYTE
B2 VAR BYTE


RST var PORTC.3
dq var PORTC.2
clk var PORTC.1

'------------------------- Read Commands For DS1302 -------------------------

readsec con $81 ' Read seconds from DS1302
readmin con $83 ' Read minutes from DS1302
readhour con $85 ' Read hours from DS1302
readdate con $87 ' Read date from DS1302
readyear con $8D ' Read year from DS1302
readmonth con $89 ' Read month from DS1302

'------------------------------ Time Variables ------------------------------

mem var byte ' Temporary data holder
outbyte var byte ' Second byte to ds1302
reg_adr var byte ' First byte to DS1302
date var byte ' Date variable
ss var byte ' Seconds variable
mm var byte ' Minutes varibale
hh var byte ' Hours variable
mo var byte ' Month variable
yr var byte ' Year variable

'------------------------ Initial Settings For Ports ------------------------

low rst ' Set reset pin low
low clk ' Set clock pin low

trisb = 0
trisa = 0

'----------------------- Set Initial Time Variables -------------------------


start:
reg_adr = readsec ' Read seconds
gosub w_in
ss = mem
reg_adr = readmin ' Read minutes
gosub w_in
mm = mem
reg_adr = readhour ' Read Hours
gosub w_in
hh = mem
reg_adr = readyear ' Read Year
gosub w_in
yr = mem
reg_adr = readdate ' Read Date
gosub w_in
date = mem
reg_adr = readmonth ' Read Month
gosub w_in
mo = mem
lcdout $fe,1,"TIME:",HEX2 hh,":",HEX2 mm,":",HEX2 ss
pause 500
goto start

'----------------------- Time Commands Subroutines --------------------------

w_in:
mem = reg_adr ' Set mem variable to reg_adr contents
high rst ' Activate the DS1302
shiftout dq,clk,0, [mem] ' Send control byte
shiftin dq,clk,1, [mem] ' Retrieve data in from the DS1302
low rst ' Deactivate DS1302
return

w_out:
mem = reg_adr ' Set mem variable to reg_adr contents
high rst ' Activate the DS1302
shiftout dq,clk,0, [mem] ' Send control byte
mem = outbyte ' Set mem variable to outbyte contents
shiftout dq,clk,0, [mem] ' Send data stored in mem variable to DS1302
low rst ' Deactivate DS1302
return


The screen always shows 00:00:00, but if I unconnect the data pin, it displays FF FF FF

What I'm doing wrong?

I've checked all treads regarding DS1302, should be OK with this code...

HenrikOlsson
- 13th January 2014, 18:49
Hi,
I've never used the DS1307 so this is purely speculations, thinking out loud kind of stuff. The DS1302 datasheet (http://datasheets.maximintegrated.com/en/ds/DS1302.pdf) says

A clock cycle is a sequence of a rising edge followed by a falling edge. For data inputs, data must be valid during the rising edge of the clock and data bits are output on the falling edge of clock.

For the SHIFTOUT you're using mode 0 (LSB first, clock idles low) which looks correct but the SHIFTIN is using mode 1 which is LSB first, clock idles low but data is read before sending clock. But since the DS1307 outputs data on the falling edge of the clock you want to read data after sending the clock. I think you should use mode 3 for the SHIFTIN.

Hmmmm, more reading.....it also says

Note that the first data bit to be transmitted occurs on the first falling edge after the last bit of the command byte is written.
Which seems to indicate that the LSB of the output byte is put on the I/O-pin on the falling edge of the 8th clock pulse generated by the SHIFTOUT - looking at the timing diagram shows this so perhaps mode 1 is correct after all. But, if that is the case then you might have trouble with both pins being driven at the same time. Do you have a resistor between the dq-pin on the PIC and the I/O pin on the DS1302? If not, perhaps you should try that, something like 1k or whatever.

Ah, like I said, just thinking out loud.....

/Henrik.

Jerson
- 14th January 2014, 04:36
I am not cent % sure since I have not used the DS1307 with PBP. However, at first glance, comparing with the C code I have, it seems you have the SHIFTOUT command configured to MODE= (0)LSBFIRST+CLOCK IDLES LOW. I believe this should be MODE=(1)MSBFIRST+CLOCK IDLES LOW for it to work correctly. Both SHIFTOUT and SHIFTIN should be set to MODE=1

Let us know if this works for you.

CuriousOne
- 14th January 2014, 05:35
Will try it later.

I also have DS1307, but I can't get it work, even with Basic Stamp, I2C sucks, so this is why I've resorted to old beloved SPI :)

I even have DS3231 board from ebay, but also can't get it to work.

In fact, I was not able to get ANY I2C device to work (eeprom, light sensor, humidity sensor, etc).

CuriousOne
- 14th January 2014, 09:12
I've tried to adapt the code from basic stamp, but it does not works:



include "MODEDEFS.BAS"
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 1
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 1500
DEFINE LCD_DATAUS 44

define OSC 4

DataIO VAR PORTC.2 ' DS1302.6
Clock VAR PORTC.1 ' DS1302.7
CS1302 VAR PORTC.3 ' DS1302.5

WrSecs CON $80 ' Write Seconds
RdSecs CON $81 ' Read Seconds
WrMins CON $82 ' Write Minutes
RdMins CON $83 ' Read Minutes
WrHrs CON $84 ' Write Hours
RdHrs CON $85 ' Read Hours
CWPr CON $8E ' Write Protect Register
WPr1 CON $80 ' Set Write Protect
WPr0 CON $00 ' Clear Write Protect
WrBurst CON $BE ' Write Burst Of Data
RdBurst CON $BF ' Read Burst Of Data
WrRam CON $C0 ' Write RAM Data
RdRam CON $C1 ' Read RAM Data
Hr24 CON 0 ' 24 Hour Mode
Hr12 CON 1 ' 12 Hour Mode


index VAR Byte ' Loop Counter
reg VAR Byte ' Read/Write Address
ioByte VAR Byte ' Data To/From DS1302
secs VAR Byte ' Seconds
mins VAR Byte ' Minutes
hrs VAR Byte ' Hours

date VAR Byte
month VAR Byte
day VAR byte ' Day
year VAR Byte ' Year

ampm VAR hrs.BIT5 ' AM/PM Flag Bit
clockMode VAR hrs.BIT7 ' 12/24 Hour Mode Bit
ampmFlag VAR Bit ' 0 = AM, 1 = PM
modeFlag VAR Bit ' 0 = 24, 1 = 12 (Hours)

work VAR Byte ' Work Data

MAINLOOP:
GOSUB GET_TIME
lcdout $fe,1,"T:",#SECS, " ", #MINS, " ", #HRS, " "
PAUSE 1000
GOTO MAINLOOP
END

Get_Time: ' DS1302 Burst Read
HIGH CS1302 ' Select DS1302
SHIFTOUT DataIO, Clock, LSBFIRST, [RdBurst]
SHIFTIN DataIO, Clock, LSBPRE, [secs, mins, hrs, date, month, day, year]
LOW CS1302 ' Deselect DS1302
RETURN


Displays 0s....

CuriousOne
- 14th January 2014, 09:25
Haha, found the reason, jumper wire was faulty !

CuriousOne
- 14th January 2014, 09:37
So code from the first post works properly, just checked.

Jerson
- 14th January 2014, 10:04
Aha - never underestimate the value of a visual inspection.

theFob
- 1st May 2014, 11:46
7328

Hi all,
Because of my specially attitude to picbasic, i want to share little xp.
I had to move from I2C to SPI RTC, i had lack of pins and this would save me one pin.
So i needed hardware driven SPI RTC. There is many true SPI chips, but i decide to use DS1302 with his serial interface.
Addition of one transistor solved the problem to unity SDI and SDO lines by CE line. That way the line remains accessible for other serial
devices. In my case this is FAT32 SD card.
The rest was trivial. I wrote 3 simple procedures to access the chip trough microchip SPI. Well, i had issues to reorder the bytes, because $81 is a 'gay' number (do not read literally ) but that is another topic :))
Regards

theFob
- 4th May 2014, 10:34
My apologies, the base emitter junction do not like reversed voltages. It's better to connect diode in series to the resistor.
You can left the speed up capacitor but in parallel of R-D. Be careful with this capacitor, use the smallest possible. The recovery time and currents depend of how deep is the transistor in saturation. Bigger base resistor (47k+) with no capacitor is an option too.