I2CREAD/WRITE takes care of that for you.
I2CREAD/WRITE takes care of that for you.
Dave
Always wear safety glasses while programming.
@Dave thanks a million for that reply, it has sent me hurtling off to understand I2Cread and I2Cwrite.
Can anyone confirm the use of a DS1302 with I2Cread/WRITE or should I rather be using the SHIFTIN/OUT displayed in most of the forum threads regarding the DS1302.
I really would appreciate some help regarding the DS1302 and a kickstart of sorts.
Kind regards
Dennis
I suspect you use serial (SHIFTOUT) with the 1302.
I know you use I2C with the 1307.
From CocaColaKid:
I have used an assembler routine with the 1302 (in a basic program) and it works:Code:'-------------------------- Clock Variables --------------------------------- rst var portb.2 ' DS1302 Reset Pin clk var portb.1 ' DS1302 Clock Pin dq var portb.0 ' DS1302 Data Pin '----------------------- Write Commands For DS1302 -------------------------- writectrl con $8E ' Control byte writeram con $80 ' Write to RAM writeprotect con $00 ' Write-protect DS1302 writesec con $80 ' Write seconds writemin con $82 ' Write minutes writehour con $84 ' Write hour writedate con $86 ' Write date writemonth con $88 ' Write month writeyear con $8C ' Write year '------------------------- 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 ------------------------- if portb.4 = 1 then START ' Set inital clock start up if jumper is present reg_adr = writectrl ' Set to control byte outbyte = writeprotect ' Set turn off protection gosub w_out ' Send both bytes reg_adr = writesec ' Set to write seconds register outbyte = $00 ' Set to write 00 to seconds register gosub w_out reg_adr = writemin outbyte = $30 gosub w_out reg_adr = writehour outbyte = $00 gosub w_out reg_adr = writedate outbyte = $01 gosub w_out reg_adr = writemonth outbyte = $01 gosub w_out reg_adr = writeyear outbyte = $00 gosub w_out reg_adr = writectrl outbyte = writeprotect gosub w_out 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
Cheers, Art.Code:#define SPI_CLK PORTA,1 ; spi bus clock line #define SPI_MOSI PORTA,2 ; spi master out data #define SPI_MISO PORTA,3 ; spi slave input data #define SPI_CE PORTA,4 ; chip enable for SPI device SCRATCH equ 0x40 ; 1 by general purpose scratchpad TMP equ 0x41 ; temp register TMP2 equ 0x42 ; temp register COUNT equ 0x43 ;YRS equ 0x44 ;MON equ 0x45 ;DOW equ 0x46 ;DAYS equ 0x47 ;HRS equ 0x48 ;MINS equ 0x49 ;SECS equ 0x4a ;user_bits equ 0x2C ; ;save_w equ 0x38 ;save_status equ 0x39 ;---- Read RTC into W (assume address already sent) ---- ;---- assumes CE is asserted ---- read_RTC: movlw 08h ;Send 8 bits movwf COUNT SPI_read_loop: rlf TMP, 1 bcf SPI_CLK ; clock data out bcf TMP, 0 ; assume data out is low btfsc SPI_MISO bsf TMP, 0 ; if data out=1, set bit bsf SPI_CLK decfsz COUNT, 1 goto SPI_read_loop movf TMP, W return ;--- Write the byte in W to RTC --- ;---- assumes CE is asserted ---- write_RTC: movwf TMP ;Save the data ; ;--- Do a SPI bus write of byte in 'TMP' --- ; SPI_write: movlw 08h ;Send 8 bits movwf COUNT SPI_w_loop: bcf SPI_CLK bcf SPI_MOSI ; assume data out is low btfsc TMP, 7 bsf SPI_MOSI ; if data out=1, set bit SPI_w_cont: rlf TMP, 1 bsf SPI_CLK ; clock it in decfsz COUNT, 1 goto SPI_w_loop return
Last edited by Art; - 21st February 2010 at 21:06.
@ Art
Thanks a million for the reply.
I had already checked out code by Cocacolakid as well as Sayzer and quite a few others, as well as Melanie's example MN1307.txt, with little or no success.
The code from Cocacolakid uses the shiftin/out method not so ?
This is the reason why I asked about the TRIS statement.
Check the first few lines of Cocolakid's code:
What should the TRIS statement be ? Or is this handled by the SHIFTIN/OUT statement ?Code:'-------------------------- Clock Variables --------------------------------- rst var portb.2 ' DS1302 Reset Pin clk var portb.1 ' DS1302 Clock Pin dq var portb.0 ' DS1302 Data Pin
Later on in his code there is :
The forum is scattered with many examples for DS1302 and DS1307 and various timers, clocks elapsed timers, olympic clocks and there are even examples for the various LABX boards,even some methods to use a PIC as a timer with accuracy much like that of a DS1302/7 depending on the crystal you choose.Code:'------------------------ Initial Settings For Ports ------------------------ low rst ' Set reset pin low low clk ' Set clock pin low trisb = 0 trisa = 0
With the wealth of information here it starts becoming rather difficult to figure out which clock chip is a good selection and why.
From what I can see (and I may well be wrong),
if you're using the DS1302 then you should use a shiftin/out method and
if you're using a DS1307 you should use the I2C method.
I am trying to build a very simple alarm clock which triggers on a matching date and time. It will also be used as a datalogger for logging the time and duration of power failures for my generator since we have many power failures in our area at some really odd times.
Your info has been most useful in starting to figure out some parts of this puzzle.
Any more info you or anyone else would also be most welcome.
Kind regards
Dennis
Last edited by Dennis; - 21st February 2010 at 22:06.
@Art
I decided to give Cocacolakid's code a whirl,sadly time stand still :-( display is stuck at 00:00:80
I think it's because of the if statement here:
So after removing it since I have no jumper there and re-programming the PIC.Code:if portb.4 = 1 then START ' Set initial clock start up if jumper is present
The display shows:
00:30:00 and time stands still :-(
Here's the code I am using :
I have attached my circuit diagram too ...perhaps that's where the mess-up is ?Code:' 'using pic18f4520 ' 'Ocsillator selections here OSCCON = $70 'Int CLK 8MHz OSCTUNE.6 = 1 'PLL 4x ADCON1= %00001111 '$0F = disable A/D converter cmcon = 7 INTCON2.7 = 0 'switch pull-ups ON 'END of oscillator selections 'timer/oscillator defines DEFINE OSC 32 '4x 8MHz 'END of timer/oscillator defines 'Port IO directions and presets for port pins begin here 'TRISX = %76543210 << tris bit order numbering 'TRISA = %11111111 'All pins are outputs 'Define port pins as inputs and outputs ... 'example only - TRISB = %00001111 ;Make 'B4-B7 outputs, B0-B3 inputs TRISA = %00000000 'assigned to LCD TRISB = %11111111 'for 4x4 keypad all input TRISC = %10000000 TRISD = %00000000 TRISE.0 = 0 TRISE.1 = 0 TRISE.2 = 0 'End of Port IO directions and presets for port pins begin here 'LCD defines begin here DEFINE LCD_BITS 4 'defines the number of data interface lines (4 or 8) DEFINE LCD_DREG PORTD 'defines the port where data lines are connected to DEFINE LCD_DBIT 4 'defines the position of data lines for 4-bit interface (0 or 4) DEFINE LCD_RSREG PORTD 'defines the port where RS line is connected to DEFINE LCD_RSBIT 2 'defines the pin where RS line is connected to DEFINE LCD_EREG PORTD 'defines the port where E line is connected to DEFINE LCD_EBIT 3 'defines the pin where E line is connected 'DEFINE LCD_RWREG 0 'defines the port where R/W line is connected to (set to 0 if not used) 'DEFINE LCD_RWBIT 0 'defines the pin where R/W line is connected to (set to 0 if not used) DEFINE LCD_COMMANDUS 2000 'defines the delay after LCDOUT statement DEFINE LCD_DATAUS 200 'delay in micro seconds 'END of LCD DEFINES 'includes begin here INCLUDE "modedefs.bas" include "c:\pbp\samples\keypad.bas" 'end of includes DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0 DEFINE HSER_SPBRG 207 ' 2400 Baud @ 32MHz, 0.17% DEFINE HSER_CLROERR 1 ' Clear overflow automatically '-------------------------- Clock Variables --------------------------------- clk var portC.3 ' DS1302 Clock Pin dq var portC.4 ' DS1302 Data Pin rst var portD.1 ' DS1302 Reset Pin '----------------------- Write Commands For DS1302 -------------------------- writectrl con $8E ' Control byte writeram con $80 ' Write to RAM writeprotect con $00 ' Write-protect DS1302 writesec con $80 ' Write seconds writemin con $82 ' Write minutes writehour con $84 ' Write hour writedate con $86 ' Write date writemonth con $88 ' Write month writeyear con $8C ' Write year '------------------------- 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 '----------------------- Set Initial Time Variables ------------------------- 'if portb.4 = 1 then START ' Set inital clock start up if jumper is present reg_adr = writectrl ' Set to control byte outbyte = writeprotect ' Set turn off protection gosub w_out ' Send both bytes reg_adr = writesec ' Set to write seconds register outbyte = $00 ' Set to write 00 to seconds register gosub w_out reg_adr = writemin outbyte = $30 gosub w_out reg_adr = writehour outbyte = $00 gosub w_out reg_adr = writedate outbyte = $01 gosub w_out reg_adr = writemonth outbyte = $01 gosub w_out reg_adr = writeyear outbyte = $00 gosub w_out reg_adr = writectrl outbyte = writeprotect gosub w_out 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
Will try asm code as well and feedback
Also going to source a DS1307 and DS1337C tomorrow and later this week, will post an update asap.
Kind regards
Dennis
Dennis,
I'm using a DS1307, well one of MicroElektronica's RTC modules for the EasyPIC5 board and have the following example displaying time and date on a 16 x 2 LCD. I've only included the code for the RTC as there are loads of examples for hooking up an LCD.
I've had this running for some time in testing, and seems quite stable. One thing that needs developing further is a means of entering the date and time via push buttons or some other means, but at least you should be able to see the basic operationCode:SDA var PORTC.1 ' RTC data SCL var PORTC.0 ' RTC clock TRISC= %00000011 DB0 var byte[8] CMCON = %00000111 ' Comparators = off gosub write_1307 read_1307: ' Read time Secs,Mins,Hours,Day,Date,Month,Year,Control I2CREAD SDA,SCL,$D1,$00,[STR DB0\8] ' Read 8 bytes from DS1307 lcdout $fe,1,"Time=",hex2 DB0[2],":",hex2 DB0[1],":",hex2 DB0[0] 'bit 0=sec, bit 1=min, bit 2=hrs lcdout $fe,$c0,"Date=",hex2 DB0[4],":",hex2 DB0[5],":",hex2 db0[6] 'bit 4=day, bit 5=month, bit 6=year goto read_1307 end Write_1307: ' Set time & date to 19:00:00 14th Feb 201 I2CWRITE SDA,SCL,$D0,$00,[$00,$00,$19,$7,$14,$2,$10,$90] ' Write to DS1307 pause 10 RETURN ' Sec Min Hr Day D M Y Control
Bookmarks