Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

DS1302 with PIC16f877 program

Status
Not open for further replies.

RasCreationKing

New Member
Greetings to everyone!

I am new to the forum and I've been reading some interesting stuff on the message board.

I need help, I am designing a real time clock using PIC16F877 and DS1302. I write the software using MPLAB assembler language. I am having a problem of setting time,date and day using assembler. The LCD display do not display anything. Can anyone help with an example code in assembler on how to set date, and time for DS1302 using PIC16f877.

Your help is greatly appreciated.

Yours Truly
Ras Creation King
 
to start with, you need to understand what your problem is. from reading your posting, it really sounds like your problem is with the LCD but it's hard to tell.

You should follow a simple debugging process. isolate components and test them. try just init'ing the LCD and writing data to it. debug that. then test the 1302. debug that. then put them all together. debug that.

there have been numerous threads on LCD debugging and 1302 debugging. try chasing those down first.
 
Thanks for the upful response!

I have initialised the LCD and it works. What I did is, I programmed my name to be displayed on the LCD which works fine. I then clear the screen after 20seconds name display for display of time and date but could not display.

Could you please tell me how to test DS1302(debugging) alone without microcontroller.I also read DS1302 Dallas datasheet on how to access the memory registers for setting time,date,year etc, but I could not understands on how to load settings(time,date etc) with PIC into DS1302.

Your help is very appreciated.

Yours Truly
Ras Creation King
 
there are tons of examples for this device. use google. search here as well.

by the way, there is a high bit in one of the words that disables the device. I think it is in seconds register. You have to clear that bit to get it to work.
 
RasCreationKing said:
Greetings to everyone!

I am new to the forum and I've been reading some interesting stuff on the message board.

I need help, I am designing a real time clock using PIC16F877 and DS1302. I write the software using MPLAB assembler language. I am having a problem of setting time,date and day using assembler. The LCD display do not display anything. Can anyone help with an example code in assembler on how to set date, and time for DS1302 using PIC16f877.

Your help is greatly appreciated.

Yours Truly
Ras Creation King

If you use DS1307, i will post my source code I done 1 year before.

I've done it, I used 16F877A and DS1307, display year, data, time on LCD 16x2.
 
Greetings beloved.

Thanks for every help that I get from this forum.

Could you please send me/post for me the code that you used for DS1307. I think the difference will not be that big with DS1302 that I am using. I think I will also learn a lot from your code on how this devices works. below is the program code that I am currently using but is not working, so I will appreciate any help.......
;Moeketsane TP
;20211902
;BCD Clock using PIC 16f877 AND DS1302 Real time clock.
;The software is written to write my surname and student number, then writes time and date on LCD display


LIST P=16F877
#INCLUDE<P16F877.INC>

SDA EQU 0X06
SCL EQU 0X06
;CONSTANT VARS=0CH 00010010

DAT_VAL EQU 0X0C
NUM_VAL EQU 0X0D
ADR_HI EQU 0X0E
ADR_VAL EQU 0X0E
DEV_ADR EQU 0X10 ; A2,A1,A0
_N EQU 0X11
O_BYTE EQU 0X12
I_BYTE EQU 0X13
LOOP1 EQU 0X14
LOOP2 EQU 0X15
RASTA EQU 0X21
CLOCK EQU 0X22

TELLER1 EQU 30H ;create a counter named teller1
TELLER EQU 21H ;CREATE A COUNTER FILE NAMED TELLER
FLASH EQU 22H ;CREATE A GPR NAMED FLASH



ORG 0X00
GOTO PICINIT

PICINIT BCF STATUS,RP1
MOVLW 0X06 ;DISABLE COMPERATERS
MOVWF ADCON1 ;MAKE SURE PORTA IS DIGITAL OUTPUT
BSF STATUS,RP0 ;MOVE TO BANK 1
CLRF TRISA ;MAKE PORTA OUTPUTS
CLRF TRISB ;MAKE PORTB OUTPUTS
MOVLW B'00000111' ;MOVE BINARY VALUE TO W REGISTER
MOVWF OPTION_REG ;PRESET COUNTER T0 256
BCF STATUS,RP0 ;MOVE BACK TO BANK 0
CLRF PORTA ;CLEAR PORTA
CLRF PORTB ;CLEAR PORTB
GOTO LCDINIT ;GOTO LCD CONFIGURATION SUBROUTINE





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;LCD CONFIGURATION;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

LCDINIT CALL LONGDELAY ;CALL DELAY FIRST
MOVLW 03H ;DIPLAY ON FIRST LINE
MOVWF PORTB
CALL ENABLE ;CLOCK DATA FROM PORTB TO THE LCD
CALL LONGDELAY


MOVLW 04H
MOVWF PORTB ;CHANGE TO 4 BIT FIRST FOUR BITS
CALL ENABLE ;CLOCK DATA
CALL LONGDELAY

MOVLW 04H
MOVWF PORTB ;CHANGE TO 4 BIT SECOND FOUR BITS
CALL ENABLE ;CLOCK DATA
CALL LONGDELAY

MOVLW 08H
MOVWF PORTB ;2 LINE MODE, 5X7 DOT FORMAT
CALL ENABLE ;CLOCK DATA
CALL LONGDELAY


MOVLW 0H ;CURSO ON, NOT UNDERLINED AND BLINK OFF
MOVWF PORTB
CALL ENABLE ;CLOCK DATA
CALL LONGDELAY

MOVLW 0CH
MOVWF PORTB ;CLOCK DATA
CALL ENABLE
CALL LONGDELAY

MOVLW 0H ;INCREMENT DISPLAY
MOVWF PORTB
CALL ENABLE ;CLOCK DATA
CALL LONGDELAY
MOVLW 6H
MOVWF PORTB
CALL ENABLE
CALL LONGDELAY
GOTO WRITE ;GOTO WRITE SUBRUOTINE TO WRITE DATA



LONGDELAY CALL SHORTDELAY
MOVLW 0X30
MOVWF TELLER

TH1 DECFSZ TELLER,F
GOTO TH1
RETLW 0

;MOVLW 0FFH ;DELAY
;MOVWF TELLER1 ;MOVE VALUE FFH TO TELLER1
;CALLBACK DECFSZ TELLER1,1 ;DECREMENT TELLER1 UNTIL IT IS 0
;GOTO CALLBACK
;RETLW 0
SHORTDELAY MOVLW 0X22
MOVWF TELLER1

TH DECFSZ TELLER1,F
GOTO TH

RETLW 0

ENABLE BSF PORTA,2 ;SET ENABLE BIT
NOP
RETLW 0




;;;;;;;;;;;;;;;;;THIS SUROUTINE IS TO MOVE THE FOUR UPPER BITS (03H) TO PORTB WHEN WRITING NUMBERS;;;;;;;;;;;;;;;;;;;;;;;;

NUMBER_CHART MOVLW 2H
MOVWF PORTA
MOVLW 3H
MOVWF PORTB
CALL ENABLE
RETLW 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SUBROUTINE FOR WRITING OUT NUMBERS;;;;;;;;;;;;;;;;;;;;;;;;;
STUDNUM
ADDWF PCL,F ;ADD WORKING REGISTER TO PROGRAM COUNTER
RETLW '0' ;RETURN WITH 0 TO W REGISTER
RETLW '2' ;WRITE OUT NUMBER '2'
RETLW '0' ;WRITE OUT NUMBER '0'
RETLW '2' ;WRITE OUT NUMBER '2'
RETLW '1' ;WRITE OUT NUMBER '1'
RETLW '1' ;WRITE OUT NUMBER '1'
RETLW '9' ;WRITE OUT NUMBER '9'
RETLW '0' ;WRITE OUT NUMBER '0'
RETLW '2' ;WRITE OUT NUMBER '2'




;;;;;;;;;;;;;;;;;;;;;;;;;;THIS SUBROUTINE IS TO MOVE FROM THE TOP LINE TO THE BOTTOM LINE;;;;;;;;;;;;;;;;;;;;;;;;;;;;

LINE_2 CLRF PORTA ;CLEAR RS LINE TO ALLOW COMMANDS

MOVLW 0CH ;WRITE OUT 0CH WICH ALLOWS THE COUSER TO MOVE TO THE BOTTOM LINE
MOVWF PORTB
CALL ENABLE
CALL LONGDELAY
MOVLW 00H
MOVWF PORTB
CALL ENABLE
CALL LONGDELAY
RETLW 0



;;;;;;;;;;;;;;;;;;;;;;THIS SUBROUTINE IS TO WRITE OUT THE UPPER FOUR (04H) BITS FOR LETTERS A-O;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

UPPER_BITS MOVLW 2H
MOVWF PORTA
MOVLW 4H
MOVWF PORTB
CALL ENABLE
RETLW 0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;START TO WRITE CHARECTERS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


WRITE BSF PORTA,1 ;SET RS LINE
CALL UPPER_BITS
MOVLW 'M' ;M
MOVWF PORTB
CALL ENABLE
CALL LONGDELAY

BSF PORTA,1 ;SET RS LINE
CALL UPPER_BITS
MOVLW 'O' ;O
MOVWF PORTB
CALL ENABLE
CALL LONGDELAY

BSF PORTA,1 ;SET RS LINE
CALL UPPER_BITS
MOVLW 'E' ;E
MOVWF PORTB
CALL ENABLE
CALL LONGDELAY
;MOVLW 0H
;MOVWF PORTB
CALL ENABLE
CALL LONGDELAY


BSF PORTA,1 ;SET RS LINE
CALL UPPER_BITS
MOVLW 'K' ;E
MOVWF PORTB
CALL ENABLE
CALL LONGDELAY


BSF PORTA,1 ;SET RS LINE
CALL UPPER_BITS
MOVLW 'E' ;K
MOVWF PORTB
CALL ENABLE
CALL LONGDELAY


BSF PORTA,1 ;SET RS LINE
CALL UPPER_BITS
MOVLW 'T' ;E
MOVWF PORTB
CALL ENABLE
CALL LONGDELAY


BSF PORTA,1 ;SET RS LINE
CALL UPPER_BITS
MOVLW 'S' ;T
MOVWF PORTB
CALL ENABLE
CALL LONGDELAY


BSF PORTA,1 ;SET RS LINE
CALL UPPER_BITS
MOVLW 'A' ;S
MOVWF PORTB
CALL ENABLE
CALL LONGDELAY


BSF PORTA,1 ;SET RS LINE
CALL UPPER_BITS
MOVLW 'N' ;A
MOVWF PORTB
CALL ENABLE
CALL LONGDELAY


BSF PORTA,1 ;SET RS LINE
CALL UPPER_BITS
MOVLW 'E' ;N
MOVWF PORTB
CALL ENABLE
CALL LONGDELAY

;BSF PORTA,3
BSF PORTA,1 ;SET RS LINE
CALL UPPER_BITS
MOVLW 'E' ;E
MOVWF PORTB
CALL ENABLE
CALL LONGDELAY
;BCF PORTA,3


CALL LINE_2 ;MOVE FROM LINE 1 TO LINE 2
CLRF FLASH ;CLEAR TEMPORARY STORAGE FILE
MOVLW D'8' ;MOVE VALUE 8 IN TELLER TO ALLOW THE NUMBER SUBROUTIN TO BE REAPEATED 8 TIMES
MOVWF TELLER



NUMBER BSF PORTA,1 ;SET RS LINE
CALL UPPER_BITS ;CALL FIRST FOUR BITS
INCF FLASH,F ;INCREMENT TEMPORARY STORAGE FILE
MOVF FLASH,W ;MOVE FLASH TO W REGISTER
CALL STUDNUM ;CALL NUMBER TABLE
MOVWF PORTB ;MOVE DATA TO PORTB
CALL ENABLE ;CLOCK DATA TO LCD
CALL LONGDELAY ;CALL DEALAY
DECFSZ TELLER,F ;DECREMENT TELLER UNTIL 0

MOVLW 0X00
MOVWF DEV_ADR

SECONDS MOVLW 0X00
MOVWF RASTA
MOVLW 0X00
MOVWF DAT_VAL
CALL RANDOM_WRITE
MOVLW 0X30
CALL DELAY_N_MS

MINUTES MOVLW 0X01
MOVWF RASTA
MOVLW 0X00
MOVWF DAT_VAL
CALL RANDOM_WRITE
MOVLW 0X30
CALL DELAY_N_MS

HOURS MOVLW 0X02
MOVWF RASTA
MOVLW B'01000010'
MOVWF DAT_VAL
CALL RANDOM_WRITE
CALL DELAY_N_MS

;*************************************************************************
; THE FOLLOWING SUBROUTINE SET THE DATE IN FORMAT:DD/MM/YY
;*************************************************************************

DAYS MOVLW 0X03 ;ADDRESS FOR SETTING DAYS
MOVWF RASTA
MOVLW B'00000111'
MOVWF DAT_VAL
CALL RANDOM_WRITE
MOVLW 0X30
CALL DELAY_N_MS

MONTH MOVLW 0X04 ;ADDRESS FOR SETTING DATE
MOVWF RASTA
MOVLW 0X05
MOVWF RASTA ;ADDRESS FOR SETTING MONTH
MOVLW 0X02
MOVWF DAT_VAL ;SET MONTH INTO FEBRUARY
CALL RANDOM_WRITE
MOVLW 0X30
CALL DELAY_N_MS

YEAR MOVLW 0X06
MOVWF RASTA
MOVLW B'01000110'
MOVWF DAT_VAL
CALL RANDOM_WRITE
MOVLW 0X30
CALL DELAY_N_MS
CALL RANDOM_READ

DONE GOTO DONE

RANDOM_WRITE BCF STATUS,5 ;WRITE DAT_VAL TO 16 BIT ADDRESS
RLF DEV_ADR,W ;SEND THE ADDRESS BYTE
IORLW 0A0H
MOVWF O_BYTE
CALL OUT_BYTE
CALL NACK

MOVF ADR_HI,W
MOVWF O_BYTE
CALL OUT_BYTE
CALL NACK
MOVF DAT_VAL,W
MOVWF O_BYTE
CALL OUT_BYTE
CALL NACK
CALL STOP
RETURN
;************************************************************************
RANDOM_READ; THIS SUBROUTINE READS DATA AT SPECIFIED LOCATION AND RETURN
; THE RESULTS IN W.
;************************************************************************

CALL START
BCF STATUS,5
RLF DEV_ADR,W
IORLW 0A0H
MOVWF O_BYTE
CALL OUT_BYTE
CALL NACK
MOVF RASTA
MOVWF O_BYTE
CALL OUT_BYTE
CALL NACK
MOVF RASTA
MOVWF O_BYTE
CALL OUT_BYTE
CALL NACK

CALL START
BCF STATUS,5
RLF DEV_ADR,W
IORLW 0A1H ;R/W SET TO 1 FOR READ OPERATION
MOVWF O_BYTE
CALL OUT_BYTE
CALL NACK
CALL IN_BYTE
CALL NACK
CALL STOP
MOVF I_BYTE,W
RETURN
;********************************************************************

IN_BYTE CLRF I_BYTE
MOVLW D'8'
MOVWF _N
CALL HIGH_SDA

IN_BIT CALL HIGH_SCL
BTFSS PORTB,SDA
GOTO IN_ZERO
GOTO IN_ONE

IN_ZERO BCF STATUS,5
RLF I_BYTE,F
GOTO CONT_IN

IN_ONE BCF STATUS,5
RLF I_BYTE,F
INCF I_BYTE,F
GOTO CONT_IN

CONT_IN CALL LOW_SCL
DECFSZ _N,F
GOTO IN_BIT
RETURN

OUT_BYTE MOVLW D'8'
MOVWF _N

OUT_BIT BCF STATUS,5
RLF O_BYTE,F
BTFSS STATUS,5
GOTO OUT_ZERO
GOTO OUT_ONE

OUT_ZERO CALL LOW_SDA
CALL CLOCK
CALL HIGH_SDA
GOTO OUT_CONT
RETURN

OUT_ONE CALL HIGH_SDA
CALL CLOCK
GOTO OUT_CONT
RETURN

OUT_CONT DECFSZ _N,F
GOTO OUT_BYTE

NACK CALL HIGH_SDA
CALL CLOCK
RETURN

ACK CALL LOW_SDA
CALL HIGH_SDA
CALL HIGH_SCL
CALL LOW_SDA
CALL LOW_SCL
RETURN

START CALL LOW_SCL
CALL HIGH_SDA
CALL HIGH_SCL
CALL LOW_SDA
CALL LOW_SCL

STOP CALL LOW_SCL
CALL LOW_SDA
CALL HIGH_SCL
CALL HIGH_SDA
CALL LOW_SDA
RETURN

BINGHI CALL HIGH_SCL
CALL LOW_SCL
RETURN

HIGH_SDA BSF STATUS,7
BSF TRISB,SDA
BCF STATUS,RP0
RETURN

LOW_SDA BCF PORTB,SDA
BSF STATUS,7
BCF TRISB,SDA
BCF STATUS,7
CALL DELAY_SHORT
RETURN

HIGH_SCL BSF STATUS,7
BSF TRISB,SCL
BCF STATUS,7
CALL DELAY_SHORT
RETURN

LOW_SCL BCF PORTB,SCL
BSF STATUS,7
BCF TRISB,SCL
BCF STATUS,7
CALL DELAY_SHORT
RETURN

DELAY_SHORT MOVLW D'10'
MOVWF LOOP2

DELAY_SHORT1 NOP
DECFSZ LOOP2,F
GOTO DELAY_SHORT1
RETURN

DELAY_LONG MOVLW D'50'
DELAY_N_MS MOVWF LOOP1
OUTTER MOVLW D'110'
MOVWF LOOP2

INNER NOP
NOP
NOP
NOP
NOP
NOP
NOP
DECFSZ LOOP2,F
GOTO OUTTER
RETURN

END




LOOP GOTO LOOP ;MAKE ENDLESS LOOP WHEN WRITING IS COMPLETE



Thanks for everyone's help and support

Ras Creation King
 
Hi Ras,
Can anyone help with an example code in assembler on how to set date, and time for DS1302 using PIC16f877.

I have these routines, which may be of help to you. I have also included my read routines, and the set time follows. I haven't visited this source in quite some time, but it was working. It is, however, cut and pasted from a project, so you may have to create some variables, but I think the complete routines are here. Let me know if they work for you.

Regards,
Robert

Code:
CONV_ASCII_RTN			; ASCII conversion routine 
	SWAPF	BUFFER1,W	; w now contains buffer1, with nibbles inverted
	ANDLW	0FH		; AND buffer1 with 1111 to get NIBBLE in lower bits
	ADDLW	30H		; add 30h (b'110000') to make ASCII
	MOVWF	HiNibble	; save HiNibble 
	MOVF	BUFFER1,W	; move buffer1 back to W to get the high byte
	ANDLW	0FH		;  AND buffer1 with 1111 to get NIBBLE in lower bits 
	ADDLW	30H		; add 30h (b'110000') to make ASCII
	MOVWF	LoNibble	; save LoNibble 
	RETURN

READ_SEC			; DS1302 read seconds register
	BSF	IO_RST		; take IO reset high to initiate transfer
	MOVLW 	81H		; binary is 10000001 read seconds command 
	MOVWF 	BUFFER1		; store it in the buffer
	CALL 	SHIFT_OUT	; and send to DS 1320
	CALL 	SHIFT_IN	; read a bite from DS1320
	BCF 	IO_RST		; IO_RST low
	RETURN

READ_MIN			; DS1302 read minutes register
	BSF	IO_RST		; take IO reset high to initiate transfer
	MOVLW 	83H		; binary is 10000011 read minutes command 
	MOVWF 	BUFFER1		; store it in the buffer
	CALL 	SHIFT_OUT	; and send to DS 1320
	CALL 	SHIFT_IN	; read a bite from DS1320
	BCF 	IO_RST		; IO_RST low
	RETURN

READ_HOUR			; DS1302 read hour register 
	BSF	IO_RST
	MOVLW 	85H
	MOVWF 	BUFFER1
	CALL 	SHIFT_OUT
	CALL 	SHIFT_IN
	BCF 	IO_RST		; IO_RST low
	RETURN

READ_DAY			; DS1302 read day register 
	BSF	IO_RST
	MOVLW 	87H
	MOVWF 	BUFFER1
	CALL 	SHIFT_OUT
	CALL 	SHIFT_IN
	BCF 	IO_RST		; IO_RST low
	RETURN

READ_MONTH			; DS1302 read month register 
	BSF	IO_RST
	MOVLW 	89H
	MOVWF 	BUFFER1
	CALL 	SHIFT_OUT
	CALL 	SHIFT_IN
	BCF 	IO_RST		; IO_RST low
	RETURN

READ_YEAR			; DS1302 read year register 
	BSF	IO_RST
	MOVLW 	8DH
	MOVWF 	BUFFER1
	CALL 	SHIFT_OUT
	CALL 	SHIFT_IN
	BCF 	IO_RST
	RETURN



DS1302_INIT_RTN
SET_SEC					; Set seconds on DS1302
	BSF 	IO_RST			; take IO reset high to init transfer

	MOVLW 	8EH			; Write protect off bin 10001110
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT
	
	MOVLW 	00H			; Write protect on
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT

	BCF 	IO_RST			; toggle IO reset
	NOP
	BSF 	IO_RST			; IO_RST high

	MOVLW 	80H			; Select second register
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT

; 	this needs to have a set_time var moved into W, rather than literal: ie 55h.
;	MOVLW 	55H			; This is the value seconds will be set at.
	MOVF	CLOCK_SEC, W		; ***! UPDATED !***
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT
	BCF 	IO_RST			; IO_RST low
	RETURN

SET_MIN					;  Set minutes on DS1302
	BSF 	IO_RST			; take IO reset high to init transfer

	MOVLW 	8EH			; Write protect off
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT
	
	MOVLW 	00H			; Write protect on
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT

	BCF 	IO_RST			; toggle IO reset
	NOP
	BSF 	IO_RST

	MOVLW 	82H			; b'10000010' is write minutes command
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT

;	MOVLW 	59H			; This is the value minutes will be set at.
	MOVF	CLOCK_MIN, W		; ***! UPDATED !***
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT
	BCF 	IO_RST			; IO_RST low
	RETURN

SET_HOUR				; Set hours on DS1302
	BSF 	IO_RST			; take IO reset high to init transfer

	MOVLW 	8EH			; Write protect off
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT
	
	MOVLW 	00H			; Write protect on
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT

	BCF 	IO_RST			; toggle IO reset
	NOP
	BSF 	IO_RST

	MOVLW 	84H			; b'10000100' is write hour command.
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT

;	MOVLW 	22h			; This is the value that will be set in hours. 23H
	MOVF	CLOCK_HRS, W		; ***! UPDATED !***
; working here	the time is set before entering the routine, so look for all calls to set_hour!

	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT
	BCF 	IO_RST
	RETURN

SET_DAY					; Set days on DS1302
	BSF 	IO_RST			; take IO reset high to init transfer

	MOVLW 	8EH			; Write protect off
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT
	
	MOVLW 	00H
	MOVWF 	BUFFER1
	CALL 	SHIFT_OUT

	BCF 	IO_RST			; toggle IO reset
	NOP
	BSF 	IO_RST

	MOVLW 	86H			; b'10000110' is write date command.
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT

	MOVLW 	31H			; This is the value that is set.
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT
	BCF 	IO_RST
	RETURN

SET_MONTH				;  Set months on DS1302
	BSF 	IO_RST			; take IO reset high to init transfer

	MOVLW 	8EH			; Write protect off
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT
	
	MOVLW 	00H
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT

	BCF 	IO_RST			; toggle IO reset
	NOP
	BSF 	IO_RST

	MOVLW 	88H			; '10001000' is write month command.
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT

	MOVLW 	12H			;  This is the value that is set.
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT
	BCF 	IO_RST
	RETURN

SET_YEAR				; Set years on DS1302
	BSF 	IO_RST			; take IO reset high to init transfer

	MOVLW 	8EH			; Write protect off
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT
	
	MOVLW 	00H
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT

	BCF 	IO_RST			; toggle IO reset
	NOP
	BSF 	IO_RST

	MOVLW 	8CH			; b'10001100' is write year command.
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT

	MOVLW 	01H			; This is the value that is set.
	MOVWF 	BUFFER1			; send to ds 1320
	CALL 	SHIFT_OUT
	BCF 	IO_RST
	RETURN

SHIFT_IN				; Read a byte from the DS1302 and store it in BUFFER1
	BSF 	STATUS,RP0		; bank 1
	MOVLW 	B'00000100'		; make b2 an input
	MOVWF 	TRISA
	BCF 	STATUS,RP0		; bank 0

	MOVLW 	.8
	MOVWF 	LOOP_CNT1		; initialize loop counter for 8 bits of data
	CLRF 	BUFFER1			; clear the buffer
	BCF 	IO_CLK
SH_2	BSF 	IO_CLK
	BCF 	STATUS,C
	BTFSC 	IO_DATA
	BSF 	STATUS,C
	BCF 	IO_CLK
	RRF 	BUFFER1, F			; rotate the buffer
	DECFSZ 	LOOP_CNT1, F
	GOTO 	SH_2

	BSF 	STATUS,RP0
	MOVLW 	B'00000000'
	MOVWF 	TRISA
	BCF 	STATUS,RP0

	RETURN

SHIFT_OUT			; DS1302 serial out routine
	MOVWF 	BUFFER1
	MOVLW 	.8
	MOVWF 	LOOP_CNT1
	BCF 	IO_CLK
SH_1	
	BTFSC 	BUFFER1,0			
	BSF 	IO_DATA
	BTFSS 	BUFFER1,0
	BCF 	IO_DATA
	BSF 	IO_CLK
	RRF 	BUFFER1,1
	BCF 	IO_CLK
	DECFSZ 	LOOP_CNT1, F
	GOTO 	SH_1
	RETURN
 
Give thanks Beloved!

I will simulate the software today and test the breadboarding. I hope it will work fine and I will tell you of the outcome.

Thanks again for all your efforts, I really appreciates it.

Peace and Love

Ras Creation King
 
Hi BeeBop,

I studied your software and I hope it will work. One more thing, I don't see where you initialised LCD. If there is, just let me know. I will also try to incorporate it with LCD initialisation that I used in my previous program. I will let you know the outcom as soon as possible....Give thanks.

Peace and Love
Ras Creation King
 
Hi Ras,
I don't see where you initialised LCD.
That's because I haven't included any LCD source in this clip. At that time I was using a serial LCD, so it's likely my routines wouldn't work for your project.
What I was doing was storing the time in variables when I read it, and I was using those to compare, and display the time. I will give you the routine to read the clock, but it isn't very good in that I have used more variables than necessary, so it is not very efficient. This is old assembly as I now would use 0x0F rather than 0Fh as is used in these routines.
The routines come from a rather large application, and I'm not sure I ever finished the thing before I started using C to develop.
Hope it is still useful for you.

Regards,
Robert

Code:
;;;**********************************************************************************************************
;;; Subroutine Name:	Readtime	
;;; Description:	Read the clock and store the time in vars.
;;;
;;; Requires:		Three vars for each part of time - hours, minutes, seconds,
;;; 			day, month, year.
;;; Returns:		An ascii char in each of the Hi/Low vars.
;;; Locations Affected:	W and all the variables used.  
;;;**********************************************************************************************************
Readtime		; ***! LOOKS LIKE THIS COULD USE WORKING HERE SOON! !***
			; If I got rid of all the high low ascii vars, could also get rid of
			; call convert to ascii and below in each!
	CALL	READ_HOUR
;	readTime	rd_hrs
	MOVF	BUFFER1, W		; load the raw data
	MOVWF	BCD_HOURS 		; STORE THE RAW VALUE
	CALL	CONV_ASCII_RTN		;  BCD to ASCII 
	MOVF	HiNibble, W		;  NIBBLE 
	MOVWF	HOURS_H			; Store the high byte
	MOVF	LoNibble, W		;  NIBBLE
	MOVWF	HOURS_L			; Store the low byte


	CALL	READ_MIN
;	readTime	rd_min
	MOVF	BUFFER1, W		; load the raw data
	MOVWF	BCD_MINUTES 		; STORE THE RAW VALUE
	CALL	CONV_ASCII_RTN		;  BCD to ASCII 
	MOVF	HiNibble,W		;  NIBBLE 
	MOVWF	MINUTES_H		; Store the high byte
	MOVF	LoNibble,W		;  NIBBLE
	MOVWF	MINUTES_L		; Store the low byte


	CALL	READ_SEC
;	readTime	rd_sec
	MOVF	BUFFER1, W		; load the raw data
	MOVWF	BCD_SECONDS 		; STORE THE RAW VALUE
	CALL	CONV_ASCII_RTN		;  BCD to ASCII 
	MOVF	HiNibble,W		;  NIBBLE 
	MOVWF	SECONDS_H		; Store the high byte
	MOVF	LoNibble,W		;  NIBBLE
	MOVWF	SECONDS_L		; Store the low byte


	CALL	READ_DAY
;	readTime	rd_day
	MOVF	BUFFER1, W		; load the raw data
	MOVWF	BCD_DAYS		; 
	CALL	CONV_ASCII_RTN		;  BCD to ASCII 
	MOVF	HiNibble,W		;  NIBBLE 
	MOVWF	DAYS_H			; Store the high byte
	MOVF	LoNibble,W		;  NIBBLE
	MOVWF	DAYS_L			; Store the low byte

	CALL	READ_MONTH
;	readTime	rd_mth
	MOVF	BUFFER1, W		; load the raw data	
	MOVWF	BCD_MONTH		; 
	CALL	CONV_ASCII_RTN		;  BCD to ASCII 
	MOVF	HiNibble,W		;  NIBBLE 
	MOVWF	MONTHS_H		; Store the high byte
	MOVF	LoNibble,W		;  NIBBLE
	MOVWF	MONTHS_L		; Store the low byte


	CALL	READ_YEAR
;	readTime	rd_yr
	MOVF	BUFFER1, W		; load the raw data
	MOVWF	BCD_YEAR		; 
	CALL	CONV_ASCII_RTN		;  BCD to ASCII 
	MOVF	HiNibble,W		;  NIBBLE 
	MOVWF	YEARS_H		; Store the high byte
	MOVF	LoNibble,W		;  NIBBLE
	MOVWF	YEARS_L		; Store the low byte


	RETURN
 
Hi BeeBop,

Thanks for your quickest responses. I really appreciate all your efforts. I will try my best to incorporate your software with the LCD output as I want. I hope retrieving data(time, date, etc) from variables and display it on LCD would not be troublesome. I am using SDA and SCL of PIC 16f877 to communicate with DS1302. I will just set up and Oscilloscope on this pins to see if communiction does happen, what do you suggest?

Thanks again for everything

Ras Creation King
 
Hi Ras,
Those routines are pretty 'rough,' and really should only be a starting point for you. Like I said, they were done long ago, and now I can see so many weak spots! I'll try and point out what those are, and give you some other info, which may be helpful.
I am using SDA and SCL of PIC 16f877 to communicate with DS1302.

Those routines use any pins; it is a 'bit-banged' interface, and you set up the pins like this:
Code:
	#DEFINE		IO_RST	PORTA,0		; SERIAL DATA
	#DEFINE		IO_CLK	PORTA,1		; SERIAL CLOCK
	#DEFINE		IO_DATA	PORTA,2		; DATA IN/OUT
I did it here, on PORTA, pins 0, 1 and 2. You can use any three pins, but you must set up the tris bits:
Code:
;set up the ports    

INIT_RTN
	CLRWDT
    	BANK1			; switch to bank one
    	MOVLW	B'00000111'	; Port A all digital 
    	MOVWF	ADCON1

   	MOVLW	B'00000000'	; B'00000000' 0X17 00010000
    	MOVWF	TRISA		; Port A is output 
    	MOVLW	B'00001111' 
     	MOVWF	TRISC		; PortC  is input/output
    	MOVLW	B'00000000'  
	MOVWF	TRISB		; PORTB is output
    	MOVWF   TRISD       	; PORTD is output
    	MOVWF   TRISE       	; PORTE is output
    	BANK0			; switch back to bank zero

You say your LCD is working, so this shouldn't be a problem:
I hope retrieving data(time, date, etc) from variables and display it on LCD would not be troublesome.
You do, however, need to declare some variables.
All of the routines which read the clock use a temporary file which is named buffer1, so you will need that.
You will also notice lines like this:
Code:
;	MOVLW 	22h		; This is the value that will be set in hours. 
	MOVF	CLOCK_HRS, W	; ***! UPDATED !***
The top line is commented out. That was what I used at first, just to get it working. In this example, the hours are set to 22, and would initialize the clock every time to 22. Later, I used the value stored in CLOCK_HOURS to update it. The value in CLOCK_HOURS could be manipulated by another routine which used button presses to set the time.

You will notice in the 'Readtime' routine that each of seconds, minutes, etc is read, and the value returned in Buffer1. That value is then stored in variables such as BCD_HOURS, as a packed BCD byte. It also requires two variables, HiNibble and LoNibble, which are used to get an ascii value, and store the time as ascii, in variables like HOURS_H and HOURS_L. I'm sure it could all be done much more elegantly, with a lot fewer variables, but that will be your job. :)

I declared my variables like this:
Code:
;	The folowing are to store time 

	CBLOCK	0x32
	HOURS_H			; VARIABLE 32h 
	HOURS_L			; VARIABLE 33h 
	MINUTES_H		; VARIABLE 34h 
	MINUTES_L		; VARIABLE 35h 
	SECONDS_H		; VARIABLE 36h 
	SECONDS_L		; VARIABLE 37h 
	DAYS_H		  	; VARIABLE 38h 
	DAYS_L			; VARIABLE 39h 
	MONTHS_H		; VARIABLE 3Ah 
	MONTHS_L		; VARIABLE 3Bh 
	YEARS_H			; VARIABLE 3Ch 
	YEARS_L			; VARIABLE 3Dh 
...

	BCD_HOURS	; VARIABLE 45h change to BCD_SECONDS  
	BCD_MINUTES	; VARIABLE 46h change to BCD_MINUTES   
	BCD_SECONDS	; VARIABLE 47h COUNT_HOURS
	BCD_DAYS	; VARIABLE 48h COUNT_DAYS
	BCD_MONTH	; VARIABLE 49h COUNT_MONTH
	BCD_YEAR	; VARIABLE 4Ah   4Ah COUNT_YEAR

	ENDC			;***! 0x4A !***
in the comment colume, I keep track of what locations are being used, and this is cut and pasted, so there are a few missing, be aware.

Also, later I began using constants like these:
Code:
;			*************** DECLARE CONSTANTS ********************
;			*************** DS1302 CONSTANTS ********************

	#define	rd_sec	81h
	#define	rd_min	83h
	#define	rd_hrs	85h
	#define	rd_day	87h
	#define	rd_mth	89h
	#define	rd_yr	8Dh

	#define	wt_sec	80h
	#define	wt_min	82h
	#define	wt_hrs	84h
	#define	wt_day	86h
	#define	wt_mth	88h
	#define	wt_yr	8Ch

	#define	loctCmd	8Ch
	#define	initCmd	8Ch
	#define	clrCmd	8Ch

	#define	HiConst	b'00000010'
	#define	LoConst	b'00001001'
	#define twntThr	b'00100011'

By the way, next time you post some code use the code tags, like this, but without the _ [_code] and [_/code] and your assembly will be much easier to read.

Best wishes,
Robert
 
Hi Robert,

Thanks for your quickest responses. I really learn a lot from you. Beloved, I like the way you explain things as I now understands things that were my big problems like how to access registers of DS1302 to set time,date,etc.thanks for your help, But now I think I am getting lost. since my programm code had errors, I tried to assemble your code and simulate it to see what happens but unfortunately nothing. Could you please send me the code with LCD initialising and hope is working because now I think my code that I happen to include to your code might also have errors. I am really in need of your help as I must submit this project nextweek wednesday(I need it working). I have copleted all paper work(user manual, Technical manual and Design manual and Schematic layout). I know you have a lot of works to do, Please send me the code and I will do the rest.

Thanks again for your support,guidance and inspirations

Yours truly,
Ras Creation King
 
Hi Ras,
I think you had best go over to Nigel's tutorials for that LCD. The one I used is serial - it is connected by one wire to the pic. Here:
PIC programmer software, and PIC Tutorials at:
http://www.winpicprog.co.uk
Look at tutorial 3.
If you give it a try and run into problems, you can get some help, but I think you need to do some coding which works with your hardware - I don't even know how your LCD is hooked up. It seems to be using 4bit mode.
But, just in case you don't believe me, here are my LCD routines:
Best wishes,
Robert
Code:
;*********************************************************************************************************
;* LCD SUBROUTINEs

;;;**********************************************************************************************************
;;; Subroutine Name:	LOCATE_0_0
;;; Description:	Sends a command to serial LCD,
;;;			calling for coordinates corresponding 
;;;			to ROW 0, COL 0.
;;; Requires:		Nothing.
;;;			
;;;			
;;; Returns:		Nothing.
;;; Locations Affected:	W is destroyed.  
;;;**********************************************************************************************************

LOCATE_0_0
	MOVLW	0A1H				; LOCATE command    loctCmd   0,0  
	CALL	SENDCHAR				; send to micro TX_PROC
	MOVLW	00H				; ROW 0(x location of display) (X axis is from 0 to 20.)
	CALL	SENDCHAR				; send location to micro TX_PROC
	MOVLW	00H				; COL 0(y location of display) ( Y axis is from 0 to 3)
	CALL	SENDCHAR				; send location to micro TX_PROC
	RETURN

LOCATE_0_1
	MOVLW	0A1H				; locate 0,0 command loctCmd
	CALL	SENDCHAR				; send command to micro TX_PROC
	MOVLW	00H				; row 0 command
	CALL	SENDCHAR				; send command to micro TX_PROC
	MOVLW	01H				; colume 1 command
	CALL	SENDCHAR				; send command to micro TX_PROC
	RETURN

CLEAR
	MOVLW	0xA3				; clrCmd
	CALL	SENDCHAR				; TX_PROC
	MOVLW	01H
	CALL	SENDCHAR				; TX_PROC
	RETURN

CURSOR_OFF
	MOVLW	0A3H				; cursor off command is 0xA30C, SEND 0xA3
	CALL	SENDCHAR				; SEND cursor off command TX_PROC
	MOVLW	0CH				; second part of cmd is 0x0C
	CALL	SENDCHAR				; so send it TX_PROC
	RETURN

CURSOR_ON
	MOVLW	0A3H				; cursor off command is 0xA30C, SEND 0xA3 ***! ??? !***
	CALL	SENDCHAR				; SEND cursor off command TX_PROC
	MOVLW	0CH				; second part of cmd is 0x0C
	CALL	SENDCHAR				; so send it TX_PROC
	RETURN

LCD_INIT
	MOVLW	0xA0				; LCD initialization command is  0A0H initCmd
	CALL	SENDCHAR			; send the command TX_PROC
	MOVLW	.200				; DELAY aroud 600US
	CALL	DELAY_US			; wait for lcd
	RETURN

LCD_STRING
	MOVLW	0A2H				; String command (PRINT) is 0xA2
	CALL	SENDCHAR				; send string command to micro TX_PROC
	RETURN

PRINT
	MOVLW	0A2H				; string command (print)
	CALL	SENDCHAR				; send command to micro TX_PROC
	RETURN

END_STR	CLRF	FETCH_SEQ			; clear the variable FETCH_SEQ
	MOVLW	00H				; End of string COMMAND
	CALL	SENDCHAR				; send command to micro TX_PROC
	RETURN


;;;*****************************************************************************************************
;;; Subroutine Name:	COLON	
;;; Description:	Print  a colon.
;;;			
;;; Requires:		sub- SENDCHAR.
;;; Returns:		A colon on the LCD.
;;; Locations Affected:	.  
;;;*****************************************************************************************************
COLON
	MOVLW	03AH			; COLON COMMAND
	CALL	SENDCHAR		;  TX_PROC
		
	RETURN


;;;*****************************************************************************************************
;;; Subroutine Name:	SPACE	
;;; Description:	Print  a blank space.
;;;			
;;; Requires:		sub- SENDCHAR.
;;; Returns:		A space on the LCD.
;;; Locations Affected:	.  
;;;*****************************************************************************************************

_SPACE
	MOVLW	20h			; 0C7H
	CALL	SENDCHAR		; SENDCMD TX_PROC
		
	RETURN



;;; *********************************************************************************************************
;;; Subroutine Name:	SENDCHAR	
;;; Description:	SENDCHAR outputs a byte to the serial LCD.
;;;			
;;; Requires:		the char, in ASCII format, to be stored in W, before calling it..
;;; Calls:		DELAY_ONE.
;;; Uses variables	BUFFER1, LOOP_CNT.
;;; Locations Affected:	IO_TX pin, STATUS, BUFFER1.  
;;; *********************************************************************************************************


SENDCHAR			; SERIAL OUT
	MOVWF	BUFFER1		; Send W reg to file BUFFER1
				; From tx procedure
	MOVLW	.8				; Because 8BIT transmission,
	MOVWF	LOOP_CNT			; so count to 8
	BCF	IO_TX				; send low on lcd bus
	CALL	DELAY_ONE			; wait 52 usec

SEND_1	CLRWDT					; Clear the watchdog
	RRF	BUFFER1, F				; rotate variable BUFFER1 to the right
	BTFSS	STATUS,CF			; CF EQU .0 = STATUS
	BCF	IO_TX				; IO_TX = PORTB,0 - first pin of B is lcd bus
	BTFSC	STATUS,CF			; 
	BSF	IO_TX				; set lcd bus high
	CALL	DELAY_ONE			; 
	DECFSZ	LOOP_CNT, F			; decriment the loop counter
	GOTO	SEND_1				; while there is still data o transmit, go back to SEND_1
	BSF	IO_TX				; lcd bus high
	CALL	DELAY_ONE			; 

	RETURN	

	
;**************************************************************************************************************
;* DELAY SUBROUTINEs

;;;**********************************************************************************************************
;;; Subroutine Name:	DELAY_ONE
;;; Description:	Timer delay for serial LCD,
;;;			4800-> 208US Delay(64) , 192000->52US Delay (14)
;;; Requires:		DELAY_US, DL_0.
;;;			
;;; Returns:		Nothing.
;;; Locations Affected:	W is destroyed.  
;;;**********************************************************************************************************

DELAY_ONE					; 
	MOVLW	.14				; 19200 Baud Rate
	;MOVLW	.64				; 4800 Baud Rate

DELAY_US
	MOVWF	DELAY_TIMER
DL_0	DECFSZ	DELAY_TIMER, F
	GOTO	DL_0
	RETURN

DELAY_MS
	MOVWF	LOOP_CNT
	CLRF	LOOP_CNT1
DE_1	DECFSZ	LOOP_CNT1, F
	GOTO	DE_1
	DECFSZ	LOOP_CNT, F
	GOTO 	DE_1

	RETURN
 
Hi Robert,

Maximum respect. I give thanks for all your help. I am working on the device and I will tell you the outcomes as soon as I finished. I hope this time things will go the right way. Thanks!

Ras Creation King
 
Ooops! I nearly forgot, I connected the LCD in 8 bit mode to the PIC. I use PORT B as outputs for the LCD Data.
Thanks for the link...

Ras Creation King
 
Please help with multiplex seven segment

I have also write date , month , year, hour,min,sec, day with seven segment display ,at89c51,ds 12887. but some problem the rtc cant send acurate time , some time it send after one month 1min delay or fast. so i want to divert with ds1302 and pic 16f72. iam new with pic, can u send me full asm code for multiplex seven segment display set button etc.

I am waiting for ur reply
 
Would you like fries with that order?


Like I have said, this is old code, and at that time I was using a serial LCD. The routines to read and set the clock will probably work for you, but you may have to make some minor changes.

If you want some help with your project, then start out with what you want to do. Try writing the code your self, and if you have some problems, you can get some help getting things to work.

Here are some links to get you started with 7 segment displays:

http://www.google.com/search?q=7-segment+using+PIC
This is what you should have done first.

The first hit is Nigel's tutorial for using 7 segment displays (something you might know if you spent enough time looking on this board:



Here are some others:
**broken link removed**

http://microengineeringlabs.com/resources/articles/ledart.htm
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top