• Domingo 22 de Diciembre de 2024, 13:45

Autor Tema:  Problema con ADuC831 y DS1307  (Leído 1666 veces)

emanuil

  • Nuevo Miembro
  • *
  • Mensajes: 1
    • Ver Perfil
Problema con ADuC831 y DS1307
« en: Lunes 13 de Abril de 2009, 22:45 »
0
Hola todos,
Tengo problema de hacer la comunicacion entre ADuC831 y DS1307 usando I2C.
Encontre un fuente ejemplo, lo reubique para mis necesidades, pero no escriba en el RTC, se leen solo zeros.
Estoy usando Aspire - Version 1.5  IDE software ( write, edit, debug, compile ) en entorno
MetaLink 8051 Cross-Assembler.
Aca les doy codigo fuente, me gustaria si me digan donde estoy cometiendo el error.
Les agradezco de antemano su colaboracion.
..........................................
; Program DS1307.ASM
;
; This program responds to commands received over the serial
; port to set the date/time as well as RAM data on the DS1307
; using a ADuC831 as a controller
;
$MOD831                         ;use ADuC831 predefined symbols
;
; definitions

CR              EQU     0DH
LF              EQU     0AH
; MCON            EQU     0C6H ; mahnati za proba
; TA              EQU     0C7H ; mahnati za proba
; TRIG            BIT     P0.2 ; mahnati za proba
DS1307W         EQU     0D0H
DS1307R         EQU     0D1H
FLAGS           DATA    20H
LASTREAD        BIT     FLAGS.0
_12_24          BIT     FLAGS.1
PM_AM           BIT     FLAGS.2
OSC             BIT     FLAGS.3
SQW             BIT     FLAGS.4
ACK             BIT     FLAGS.5
BUS_FAULT       BIT     FLAGS.6
_2W_BUSY        BIT     FLAGS.7
BITCOUNT        DATA    21H
BYTECOUNT       DATA    22H
BYTE            DATA    23H
;____________________________________________________________________
                                ; DEFINE VARIABLES IN INTERNAL RAM

BITCNT          DATA    30h     ; bit counter for I2C routines / 110000 /
SLAVEADD        DATA    31h     ; slave address for I2C routines / 110001 /
INPUT           DATA    32h     ; data recieved from the slave / 110010 /
OUTPUT          DATA    33h     ; data to be transmitted to slave / 110011 /

NOACK           BIT     00h     ; I2C no acknowledge flag
ERR             BIT     00h     ; I2C error flag


;
;____________________________________________________________________
                                                  ; BEGINNING OF CODE
CSEG
ORG 0000h
AJMP START
;
;____________________________________________________________________
                                                           ; INT0 ISR
ORG 0003h
        INC     OUTPUT
        RETI

;

CSEG AT 30H
;*************************************************************
;*** RESET GOES HERE TO START PROGRAM                     ****
;*************************************************************
ORG 0060h
START:
                                ; configure the UART ADuC831

   MOV     SCON,#52h           ; configure UERT for 9600 baud
    MOV     TMOD,#20h           ; assumihg 11.0592 MHz crystal
    MOV     TH1,#-3             ;
    SETB    TR1

                                ; configure & enable interrupts
        SETB    EX0             ; enable INT0
        SETB    IT0             ; INT0 edge triggered
        SETB    EA              ; allow all the interrupts

                                ; initialise settings
        MOV     SLAVEADD,#88H   ; clear RW bit / 10001000 /
        MOV     I2CCON,#0A8h    ; sets SDATA & SCLOCK, and / 10101000 /
                                ; selects master mode
        MOV     OUTPUT,#0       ; TX 0 as default
        CLR     NOACK
        CLR     ERR

;-----------------------------------------------------------------------
; THIS IS THE MASTER CONTROLLER LOOP
;-----------------------------------------------------------------------
MASTER_CONTROLLER:

MOV BYTECOUNT,#10H      
FORM_FEED: MOV A,#LF            ; CLEAR SCREEN FOR MAIN MENU
LCALL WRITE_DATA
DJNZ BYTECOUNT,FORM_FEED
MOV DPTR, #TEXT0                ; PUT MAIN MENU ON SCREEN
LCALL WRITE_TEXT
MOV DPTR,#TEXT3
LCALL WRITE_TEXT
LCALL READ_DATA
CLR ACC.5                       ; CONVERT ACC TO UPPER CASE

CJNE A,#'A',NOTA                
LCALL SET_CLOCKM                ; CALL SET CLOCK FUNCTION
JMP MASTER_CONTROLLER           ; RETURN TO MAIN MENU

NOTA:   CJNE A,#'B',NOTB
LCALL SET_RAM                   ; CALL SET RAM FUNCTION AND
LCALL READ_RAM                  ; CALL READ RAM FUNCTION
JMP MASTER_CONTROLLER           ; RETURN TO MAIN MENU

NOTB:   CJNE A,#'C',NOTC
LCALL READ_CLOCK                ; CALL READ CLOCK FUNCTION
JMP MASTER_CONTROLLER           ; RETURN TO MAIN MENU

NOTC:   CJNE A,#'D',NOTD
LCALL READ_RAM                  ; CALL READ RAM FUNCTION
JMP MASTER_CONTROLLER           ; RETURN TO MAIN MENU

NOTD:   CJNE A,#'E',NOTE
CLR OSC                         ; CLR OSC FLAG - ON
LCALL OSC_CONTROL               ; CALL OSC CONTROL FUNCTION
JMP MASTER_CONTROLLER           ; RETURN TO MAIN MENU

NOTE:   CJNE A,#'F',NOTF
SETB OSC                        ; SET OSC FLAG - OFF
LCALL OSC_CONTROL               ; CALL OSC CONTROL FUNCTION
JMP MASTER_CONTROLLER           ; RETURN TO MAIN MENU

NOTF:   CJNE A,#'G',NOTG
CLR SQW                         ; CLR SQW FLAG - ON
LCALL SQW_CONTROL_1HZ           ; CALL SWQ CONTROL FUNCTION
JMP MASTER_CONTROLLER           ; RETURN TO MAIN MENU

NOTG:   CJNE A,#'H',NOTH
CLR SQW                         ; CLR SQW FLAG - ON
LCALL SQW_CONTROL_4KHZ          ; CALL SWQ CONTROL FUNCTION
JMP MASTER_CONTROLLER           ; RETURN TO MAIN MENU

NOTH:   CJNE A,#'I',NOTI
CLR SQW                         ; CLR SQW FLAG - ON
LCALL SQW_CONTROL_8KHZ          ; CALL SWQ CONTROL FUNCTION
JMP MASTER_CONTROLLER           ; RETURN TO MAIN MENU

NOTI:   CJNE A,#'J',NOTJ
CLR SQW                         ; CLR SQW FLAG - ON
LCALL SQW_CONTROL_32KHZ         ; CALL SWQ CONTROL FUNCTION
JMP MASTER_CONTROLLER           ; RETURN TO MAIN MENU

NOTJ:   CJNE A,#'K',NOTK
SETB SQW                        ; SET SQW FLAG - OFF
LCALL SQW_CONTROL_1HZ           ; CALL SWQ CONTROL FUNCTION
JMP MASTER_CONTROLLER

NOTK: CJNE A,#'L',NOTL
LCALL SET_RAM_UNQ
LCALL READ_RAM

NOTL:   JMP MASTER_CONTROLLER   ; RETURN TO MAIN MENU
;-----------------------------------------------------------------------
; THIS SUB SENDS THE START CONDITION
;-----------------------------------------------------------------------
SEND_START:                     ; Sends the start bit to initiate an I2C
                                ; communication
SETB    MDE                     ; enable SDATA pin as an output
        CLR     NOACK
        CLR     MDO             ; low O/P on SDATA
        CLR     MCO             ; start bit
        RET
;
;-----------------------------------------------------------------------
; THIS SUB SENDS THE STOP CONDITION
;-----------------------------------------------------------------------
SEND_STOP:                      ; Sends the stop bit to end an I2C
                                ; transmission
SETB    MDE                     ; to enable SDATA pin as an output
        CLR     MDO             ; get SDATA ready for stop
        SETB    MCO             ; set clock for stop
        SETB    MDO             ; this is the stop bit
        RET
;
;-----------------------------------------------------------------------
; THIS SUB SENDS ONE BYTE OF DATA TO THE DS1307
;-----------------------------------------------------------------------
SEND_BYTE:                      ; Send 8-bits in ACC to the slave

MOV     BITCNT,#8               ; 8 bits in a byte
        SETB    MDE             ; to enable SDATA pin as an output
        CLR     MCO             ; make sure that the clock line is low
       
SENDBIT:
        RLC     A               ; put data bit to be sent into carry
        MOV     MDO,C           ; put data bit on SDATA line
        SETB    MCO             ; clock to send bit
        CLR     MCO             ; clear clock
        DJNZ    BITCNT,SENDBIT  ; jump back and send all eight bits
        CLR     MDE             ; release data line for acknowledge
        SETB    MCO             ; send clock for acknowledge
        JNB     MDI,NEXT        ; this is a check for acknowledge
        SETB    NOACK           ; no acknowledge, set flag
       
NEXT:   CLR     MCO             ; clear clock
        RET
;
;-----------------------------------------------------------------------
; THIS SUB READS ONE BYTE OF DATA FROM THE DS1307
;-----------------------------------------------------------------------
READ_BYTE:                      ; receives one byte of data from an I2C
                                ; slave device. Returns it in A
MOV     BITCNT,#8               ; Set bit count.
        CLR     MDE             ; to enable SDATA pin as an input
        CLR     MCO             ; make sure the clock line is low
       
RCVBIT:
        SETB    MCO             ; clock to recieve bit
        CLR     MCO             ; clear clock
        MOV     C,MDI           ; read data bit into carry.
        RLC     A               ; Rotate bit into result byte.

        DJNZ    BITCNT,RCVBIT   ; Repeat until all bits received.
                                ; recieved byte is in the accumulator

        SETB    MDE             ; Data pin =Output for NACK
        SETB    MDO             ; Send NACK (always send NACK for
                                ; last byte in transmission)
        SETB    MCO             ; Send NACK clock.
        CLR     MCO
        RET
;
;----------------------------------------------------------------------- ;
; THIS SUB SETS THE CLOCK LINE HIGH / izkliuchena sub za rezultat /
;-----------------------------------------------------------------------
;SCL_HIGH:
;SETB SCL                       ; SET SCL HIGH
;JNB SCL,$                      ; LOOP UNTIL STRONG 1 ON SCL
;RET
;----------------------------------------------------------------------- ;
; THIS SUB DELAY THE BUS
;-----------------------------------------------------------------------
                                                              ; DELAY
; DELAY ROUTINE FOR THE ADuC812/ADuC816/ADuC824

DELAY:                          ; Delays by 100ms * A

; ADuC812 100ms based on 11.0592MHz Core Clock
; ADuC824 100ms based on 1.573MHz Core Clock

       MOV     R2,A             ; Acc holds delay variable
       
DLY0:  MOV     R3,#200          ; Set up delay loop0

DLY1:  MOV     R4,#229          ; Set up delay loop1
       DJNZ   R4,$              ; Dec R4 & Jump here until R4 is 0
                                ; wait here for 131*15.3us=2ms
       DJNZ   R3,DLY1           ; Dec R3 & Jump DLY1 until R3 is 0
                                ; Wait for 50*2ms
       DJNZ   R2,DLY0           ; Dec R2 & Jump DLY0 until R2 is 0
                                ; wait for ACC*100ms
       RET                      ; Return from subroutine
;
;-----------------------------------------------------------------------
; THIS SUB DELAYS 4 CYCLES
;-----------------------------------------------------------------------
DELAY_4:
NOP                             ; DELAY FOR BUS TIMING
NOP
NOP
NOP
RET
;-----------------------------------------------------------------------
; THIS SUB SETS THE CLOCK (MANUAL)
;-----------------------------------------------------------------------
SET_CLOCKM:

MOV R1,#2EH                     ; SET R1 TO SCRATCHPAD MEMORY FOR DATE/TIME
MOV DPTR, #GODINA               ; GET THE DATE/TIME INFORMATION FROM THE
LCALL WRITE_TEXT                ; USER. WRITE THE DATE/TIME TO SCRATCHPAD
LCALL READ_BCD                  ; MEMORY

MOV @R1,A
DEC R1
MOV DPTR, #MESEC
LCALL WRITE_TEXT
LCALL READ_BCD

MOV @R1,A
DEC R1
MOV DPTR, #DATATA
LCALL WRITE_TEXT
LCALL READ_BCD

MOV @R1,A
DEC R1
MOV DPTR, #DEN
LCALL WRITE_TEXT
LCALL READ_BCD
ANL A, #7

MOV @R1,A
DEC R1
MOV DPTR, #CHAS
LCALL WRITE_TEXT
LCALL READ_BCD

MOV @R1,A
DEC R1
MOV DPTR, #MINUTI
LCALL WRITE_TEXT
LCALL READ_BCD

MOV @R1,A
DEC R1
MOV DPTR, #SEKUNDI
LCALL WRITE_TEXT
LCALL READ_BCD

MOV @R1,A
MOV R1,#28H                      ; POINT TO BEGINNING OF CLOCK DATA IN
                                 ; SCRATCHPAD MEMORY
LCALL SEND_START                 ; SEND 2WIRE START CONDITION
MOV A,#DS1307W                   ; SEND DS1307 WRITE COMMAND
LCALL SEND_BYTE
MOV A,#00H                       ; SET DATA POINTER TO REGISTER 00H ON
LCALL SEND_BYTE                  ; THE DS1307
SEND_LOOP:
MOV A,@R1                        ; MOVE THE FIRST BYTE OF DATA TO ACC
LCALL SEND_BYTE                  ; SEND DATA ON 2WIRE BUT
INC R1
CJNE R1,#2FH,SEND_LOOP           ; LOOP UNTIL CLOCK DATA SENT TO DS1307
LCALL SEND_STOP                  ; SEND 2WIRE STOP CONDITION
RET
;-----------------------------------------------------------------------
; THIS SUB SETS THE DS1307 USER RAM TO THE VALUE IN 'BYTE'
;-----------------------------------------------------------------------
SET_RAM:

MOV R1,#08H                      ; POINTER TO BEGINNING OF DS1307 USER RAM
MOV DPTR, #TEXT5                 ; MESSAGE TO ENTER DATA BYTE
LCALL WRITE_TEXT                 ;
LCALL READ_BCD                   ; READ BYTE FROM KEYBOARD
MOV BYTE,A                       ; AND STORE IN 'BYTE'
LCALL SEND_START                 ; SEND 2WIRE START CONDITION
MOV A,#DS1307W                   ; LOAD DS1307 WRITE COMMAND
LCALL SEND_BYTE                  ; SEND WRITE COMMAND
MOV A,#08H                       ; SET DS1307 DATA POINTER TO BEGINNING
LCALL SEND_BYTE                  ; OF USER RAM - 08H
SEND_LOOP2:
MOV A,BYTE                       ; WRITE BYTE TO ENTIRE RAM SPACE
LCALL SEND_BYTE                  ; WHICH IS 08H TO 37H
INC R1
CJNE R1,#040H,SEND_LOOP2         ; LOOP UNTIL RAM FILLED
LCALL SEND_STOP                  ; SEND 2WIRE STOP CONTION
RET
;-----------------------------------------------------------------------
; THIS SUB SETS THE DS1307 USER RAM TO THE UNIQUE PATTERN
;-----------------------------------------------------------------------
SET_RAM_UNQ:

MOV R1,#08H                      ; POINTER TO BEGINNING OF DS1307 USER RAM
LCALL SEND_START                 ; SEND 2WIRE START CONDITION
MOV A,#DS1307W                   ; LOAD DS1307 WRITE COMMAND
LCALL SEND_BYTE                  ; SEND WRITE COMMAND
MOV A,#08H                       ; SET DS1307 DATA POINTER TO BEGINNING
LCALL SEND_BYTE                  ; OF USER RAM - 08H
SEND_LOOP3:
LCALL SEND_BYTE                  ; WHICH IS 08H TO 37H
INC R1
INC A
CJNE R1,#040H,SEND_LOOP3         ; LOOP UNTIL RAM FILLED
LCALL SEND_STOP                  ; SEND 2WIRE STOP CONTION
RET
;-----------------------------------------------------------------------
; THIS SUB READS THE DS1307 RAM AND WRITES IT TO THE SCRATCH PAD MEMORY
;-----------------------------------------------------------------------
READ_RAM:

MOV DPTR,#TEXT4                  ; SEND KEY PRESS MSG
LCALL WRITE_TEXT
MOV R1,#30H                      ; START OF RAM REGS IN SCRATCH PAD
MOV BYTECOUNT,#00H               ; COUNTER FOR 56 RAM BYTES
CLR LASTREAD                     ; FLAG TO CHECK FOR LAST READ
LCALL SEND_START                 ; SEND 2WIRE START CONDITION
MOV A,#DS1307W                   ; SEND DS1307 WRITE COMMAND
LCALL SEND_BYTE
MOV A,#08H                       ; SET POINTER TO REG 08H ON
                                 ; DS1307
LCALL SEND_BYTE
LCALL SEND_STOP                  ; SEND STOP CONDITION
LCALL SEND_START                 ; SEND START CONDITION
MOV A,#DS1307R                   ; SEND DS1307 READ COMMAND
LCALL SEND_BYTE

READ_LOOP2:
MOV A,BYTECOUNT                  ; CHECK TO SEE OF DOING LAST READ
CJNE A,#37H,NOT_LAST2  
SETB LASTREAD                    ; IF LAST READ SET LASTREAD FLAG

NOT_LAST2:
LCALL READ_BYTE                  ; READ A BYTE OF DATA
MOV @R1,A                        ; MOVE DATA INTO SCRATCHPAD MEMORY
INC R1                           ; INC POINTERS
INC BYTECOUNT
MOV A,BYTECOUNT
CJNE A,#38H,READ_LOOP2           ; LOOP FOR ENTIRE DS1307 RAM
LCALL SEND_STOP                  ; SEND 2WIRE STOP CONDITION
LCALL DISP_RAM                   ; DISPLAY DATA IN SCRATCHPAD MEMORY
JNB RI,$                         ; WAIT UNTIL A KEY IS PRESSED
CLR RI
RET
;-----------------------------------------------------------------------
; THIS SUB DISPLAYS THE RAM DATA SAVED IN SCRATCHPAD MEMORY
;-----------------------------------------------------------------------
DISP_RAM:

MOV R1,#30H                      ; START OF RAM IN SCRATCHPAD
                                 ; MEMORY
MOV BITCOUNT,#00H
MOV DPTR,#TEXT6                  ;DISPLAY TABLE HEADING
LCALL WRITE_TEXT

DISP_ADDR:
LCALL DISP_LOC                   ; DISPLAY VALUE OF CURRENT RAM LOCATION

DIS_LOOP:
MOV A,@R1                        ; DISPLAY RAM DATA SAVED IN SCRATCHPAD
LCALL WRITE_BCD                  ; CONVERT TO BCD FORMAT AND DISPLAY
INC R1
INC BITCOUNT
MOV A,#20H                       ; SPACE BETWEEN DATA BYTES
LCALL WRITE_DATA
MOV A,BITCOUNT
CJNE A,#08H,DIS_LOOP             ; LINE FEED AFTER 8 BYTES OF DATA
MOV BITCOUNT,#00H
MOV DPTR,#TEXT3                  ; 'CR,LF'
LCALL WRITE_TEXT
CJNE R1,#68H,DISP_ADDR           ; DISPLAY DATA FOR 56 BYTES OF RAM
RET
;----------------------------------------------------------------------- ;
; THIS SUB WRITES THE RAM LOCATION OF THE DATA
;-----------------------------------------------------------------------
DISP_LOC:

MOV A,R1                         ; DISPLAY THE HEX VALUE FOR THE DATA
ADD A,#-28H                      ; IN THE DS1307 RAM SPACE
LCALL WRITE_BCD                  ; CONVERTS SCRATCHPAD ADDRESS
MOV A,#20H                       ; INTO DS1307 RAM ADDRESS
LCALL WRITE_DATA
MOV A,#20H
LCALL WRITE_DATA
MOV A,#20H
LCALL WRITE_DATA
RET
;-----------------------------------------------------------------------
; THIS SUB READS THE CLOCK AND WRITES IT TO THE SCRATCH PAD MEMORY
;-----------------------------------------------------------------------
READ_CLOCK:

MOV DPTR,#TEXT4                  ; KEY PRESS MSG
LCALL WRITE_TEXT

READ_AGAIN:
MOV R1,#28H                      ; START OF CLOCK REG IN SCRATCHPAD
MOV BYTECOUNT,#00H               ; COUNTER UP TO 8 BYTES FOR CLOCK
CLR LASTREAD                     ; FLAG TO CHECK FOR LAST READ
; LCALL SEND_START                 ; SEND START CONDITION
; MOV A,#DS1307W                   ; SET POINTER TO REG 00H ON DS1307
; LCALL SEND_BYTE
; MOV A,#00H
; LCALL SEND_BYTE
; LCALL SEND_STOP                  ; SEND STOP CONDITION
LCALL SEND_START                 ; SEND START CONDITION
MOV A,#DS1307R                   ; SEND READ COMMAND TO DS1307
LCALL SEND_BYTE

READ_LOOP:
MOV A,BYTECOUNT                  ; CHECK TO SEE OF DOING LAST READ
CJNE A,#07H,NOT_LAST
SETB LASTREAD                    ; SET LASTREAD FLAG

NOT_LAST:
LCALL READ_BYTE                  ; READ A BYTE OF DATA
MOV @R1,A                        ; MOVE DATA IN SCRATCHPAD MEMORY
MOV A,BYTECOUNT                  ; CHECK TO SEE IF READING SECONDS REG
CJNE A,#00H,NOT_FIRST
CLR OSC                          ; CLR OSC FLAG
MOV A,@R1                        ; MOVE SECONDS REG INTO ACC
JNB ACC.7,NO_OSC                 ; JUMP IF BIT 7 OF IS A 0
SETB OSC                         ; SET OSC FLAG, BIT 7 IS A 1
CLR ACC.7                        ; CLEAR BIT 7 FOR DISPLAY
                                 ; PURPOSES
MOV @R1,A                        ; MOVE DATA BACK TO SCRATCHPAD

NO_OSC:

NOT_FIRST:
INC R1                           ; INC COUNTERS
INC BYTECOUNT
MOV A,BYTECOUNT
CJNE A,#08H,READ_LOOP            ; LOOP FOR ENTIRE CLOCK REGISTERS
LCALL SEND_STOP                  ; SEND 2WIRE STOP CONDITION
LCALL DISP_CLOCK                 ; DISPLAY DATE/TIME FROM SCRATCHPAD
JNB RI,READ_AGAIN                ; READ AND DISPLAY UNTIL A KEY IS PRESSED
CLR RI
RET
;-----------------------------------------------------------------------
; THIS SUB DISPLAYS THE DATE AND TIME SAVED IN SCRATCHPAD MEMORY
;-----------------------------------------------------------------------
DISP_CLOCK:

MOV DPTR,#TEXT1                  ; DATE:
LCALL WRITE_TEXT

MOV R1,#2DH                      ; MONTH
MOV A,@R1
LCALL WRITE_BCD

MOV A,#'/'
LCALL WRITE_DATA

MOV R1,#2CH                      ; DATE
MOV A,@R1
LCALL WRITE_BCD

MOV A,#'/'
LCALL WRITE_DATA

MOV R1,#2EH                      ; YEAR
MOV A,@R1
LCALL WRITE_BCD

MOV A,#09H                       ; TAB
LCALL WRITE_DATA

MOV DPTR,#TEXT2                  ; TIME:
LCALL WRITE_TEXT

MOV R1,#2AH                      ; HOURS
MOV A,@R1
LCALL WRITE_BCD

MOV A,#3AH                       ; COLON
LCALL WRITE_DATA

MOV R1,#29H                      ; MINUTES
MOV A,@R1
LCALL WRITE_BCD

MOV A,#3AH                       ; COLON
LCALL WRITE_DATA

MOV R1,#28H                      ; SECONDS
MOV A,@R1

LCALL WRITE_BCD
RET
;-----------------------------------------------------------------------
; THIS SUB SETS THE OSCILLATOR ACCORDING TO THE OSC BIT
;-----------------------------------------------------------------------
OSC_CONTROL:

LCALL SEND_START                 ; SEND START CONDITION
MOV A,#DS1307W                   ; SET POINTER TO REG 00H ON DS1307
LCALL SEND_BYTE
MOV A,#00H
LCALL SEND_BYTE
SETB LASTREAD                    ; SET LAST READ FOR SINGLE READ
LCALL SEND_STOP                  ; SEND STOP CONDITION
LCALL SEND_START                 ; SEND START CONDITION
MOV A,#DS1307R                   ; SEND READ COMMAND TO DS1307
LCALL SEND_BYTE
LCALL READ_BYTE                  ; READ SECONDS REGISTER
CLR ACC.7                        ; TURN OSC ON
JNB OSC,OSC_SET
SETB ACC.7                       ; TURN OSC OFF IF OSC BIT IS SET IN

OSC_SET:                         ; SECONDS REGISTER
PUSH ACC                         ; SAVE SECONDS DATA ON STACK
LCALL SEND_STOP                  ; SEND STOP CONDITION
LCALL SEND_START                 ; SEND START CONDITION
MOV A,#DS1307W                   ; SET POINTER TO REG 00H ON DS1307
LCALL SEND_BYTE
MOV A,#00H
LCALL SEND_BYTE
POP ACC                          ; SEND SECONDS REGISTER TO CONTROL
LCALL SEND_BYTE                  ; OSCILLATOR ON DS1307
LCALL SEND_STOP
RET
;-----------------------------------------------------------------------
; THIS SUB CONTROLS THE SQW OUTPUT 1HZ
;-----------------------------------------------------------------------
SQW_CONTROL_1HZ:

LCALL SEND_START                 ; SEND START CONDITION
MOV A,#DS1307W                   ; SET POINTER TO REG 07H ON DS1307
LCALL SEND_BYTE
MOV A,#07H
LCALL SEND_BYTE
MOV A,#90H                       ; SQW/OUT ON AT 1HZ
JNB SQW,SQW_SET                  ; JUMP IF SQW BIT IS ACTIVE
MOV A,#80H                       ; TURN SQW/OUT OFF - OFF HIGH

SQW_SET:
LCALL SEND_BYTE
LCALL SEND_STOP
RET
;-----------------------------------------------------------------------
; THIS SUB CONTROLS THE SQW OUTPUT 4KHZ
;-----------------------------------------------------------------------
SQW_CONTROL_4KHZ:

LCALL SEND_START                 ; SEND START CONDITION
MOV A,#DS1307W                   ; SET POINTER TO REG 07H ON DS1307
LCALL SEND_BYTE
MOV A,#07H
LCALL SEND_BYTE
MOV A,#91H                       ; SQW/OUT ON AT 1HZ
JNB SQW,SQW_SET1                 ; JUMP IF SQW BIT IS ACTIVE
MOV A,#80H                       ; TURN SQW/OUT OFF - OFF HIGH

SQW_SET1:
LCALL SEND_BYTE
LCALL SEND_STOP
RET
;-----------------------------------------------------------------------
; THIS SUB CONTROLS THE SQW OUTPUT 8KHZ
;-----------------------------------------------------------------------
SQW_CONTROL_8KHZ:

LCALL SEND_START                 ; SEND START CONDITION
MOV A,#DS1307W                   ; SET POINTER TO REG 07H ON DS1307
LCALL SEND_BYTE
MOV A,#07H
LCALL SEND_BYTE
MOV A,#92H                       ; SQW/OUT ON AT 1HZ
JNB SQW,SQW_SET2                 ; JUMP IF SQW BIT IS ACTIVE
MOV A,#80H                       ; TURN SQW/OUT OFF - OFF HIGH

SQW_SET2:
LCALL SEND_BYTE
LCALL SEND_STOP
RET
;-----------------------------------------------------------------------
; THIS SUB CONTROLS THE SQW OUTPUT 32KHZ
;-----------------------------------------------------------------------
SQW_CONTROL_32KHZ:

LCALL SEND_START                 ; SEND START CONDITION
MOV A,#DS1307W                   ; SET POINTER TO REG 07H ON DS1307
LCALL SEND_BYTE
MOV A,#07H
LCALL SEND_BYTE
MOV A,#93H                       ; SQW/OUT ON AT 1HZ
JNB SQW,SQW_SET3                 ; JUMP IF SQW BIT IS ACTIVE
MOV A,#80H                       ; TURN SQW/OUT OFF - OFF HIGH

SQW_SET3:
LCALL SEND_BYTE
LCALL SEND_STOP
RET
;-----------------------------------------------------------------------
; THIS SUB IS A SCOPE TRIGGER BIT - izkliucheno za proba
;-----------------------------------------------------------------------
; TRIGGER:

; CLR TRIG
; SETB TRIG
; LCALL DELAY_4
; CLR TRIG
; RET
;-----------------------------------------------------------------------
; THIS SUB READS DATA FROM THE SCREEN AND CONVERTS IT TO BCD FORM
; DATA SHOULD BE HEX DIGITS: 1,2,3...9,A,B,C,D,E,F
;-----------------------------------------------------------------------
READ_BCD:

MOV R0,#0                        ; CLEAR R0
BCD_LOOP:
LCALL READ_DATA                  ; READ BYTE FROM KEYBOARD
CJNE A, #0DH, BCD                ; CHECK FOR CR
MOV A,R0                         ; MOVE R0 TO ACC AND RETURN
RET

BCD:
ADD A,#-30H                      ; BEGIN TO CONVERT TO ACTUAL VALUE
JNB ACC.4,DIGIT                  ; JUMP IF NOT A-F
ADD A,#-07H                      ; IF A-F SUBTRACT 7

DIGIT:
ANL A,#0FH                       ; ENSURE BITS 4-7 ARE CLEARED
ANL 0,#0FH                       ; ENSURE BITS 4-7 ARE CLEARED
XCH A,R0                         ; EXCHANGE R0 AND ACC
SWAP A                           ; NIBBLE SWAP ACC
ORL A,R0                         ; INSERT BITS 0-3 OF R0 INTO ACC
MOV R0,A                         ; MOVE ACC INTO R0
SJMP BCD_LOOP                    ; LOOP UNTIL CR ENCOUNTERED
;-----------------------------------------------------------------------
; THIS SUB WRITES THE BYTE TO THE SCREEN
;-----------------------------------------------------------------------
WRITE_BCD:

PUSH ACC                         ; SAVE ACC ON STACK
SWAP A                           ; NIBBLE SWAP ACC
ANL A,#0FH                       ; CLEAR BITS 4-7 OF ACC
ADD A,#07H                       ; ADD 7 TO ACC TO CONVERT TO ASCII HEX
JNB ACC.4,LESSNINE               ; CHECK TO SEE IF LESS THAN NINE 0-8
CJNE A,#10H,NOTNINE              ; JUMP IS GREATER THAN NINE A-F

LESSNINE:
ADD A,#-07H                      ; SUBTRACT 7 FOR 0-9

NOTNINE:
ADD A,#30H                       ; ADD 30 TO CONVERT TO ASCII EQUIVALENT
LCALL WRITE_DATA                 ; WRITE BYTE TO SCREEN
POP ACC                          ; RECALL ACC FROM STACK
ANL A,#0FH                       ; PERFORM CONVERSION ON OTHER HALF OF BYTE
ADD A,#07H
JNB ACC.4,NINE2
CJNE A,#10H,NOTNINE2

NINE2:
ADD A,#-07H

NOTNINE2:
ADD A,#30H
LCALL WRITE_DATA
RET
;-----------------------------------------------------------------------
READ_DATA:

JNB RI,READ_DATA                 ; LOOP WHILE RI BIT IS LOW
CLR RI                           ;    
MOV A,SBUF                       ; GET DATA BYTE FROM SERIAL BUFFER
RET
;-----------------------------------------------------------------------
WRITE_DATA:

JNB TI,WRITE_DATA                ; LOOP WHILE TI BIT IS LOW
CLR TI                           ;
MOV SBUF,A                       ; SEND DATA BYTE TO SERIAL
; BUFFER
RET
;-----------------------------------------------------------------------
WRITE_TEXT:

PUSH ACC                         ; SAVE ACC BYTE ON STACK

WT1:
CLR A                            ; CLEAR ACC
MOVC A,@A+DPTR                   ; MOVE FIRST BYTE OF STRING
                                 ; TO ACC
INC DPTR                         ; INC DATA POINTER
CJNE A,#0,WT2                    ; CHECK FOR STRING
                                 ; TERMINATOR - 0
POP ACC                            ; RESTORE ACC
RET                               ; RETURN WHEN STRING IS SENT

WT2:
LCALL WRITE_DATA ; SEND BYTE OF STRING OVER SERIAL PORT
SJMP WT1
;-----------------------------------------------------------------------
; TEXT STRINGS USED FOR USER INTERFACE OVER SERIAL PORT
;-----------------------------------------------------------------------
GODINA:
DB CR,LF,'GODINA (0 - 99) : ',0

MESEC:
DB CR,LF,'MESEC (1 - 12) : ',0

DATATA:
DB CR,LF,'DATA OT MESECA : ',0

DEN:
DB CR,LF,'DEN OT SEDMICATA : ',0

CHAS:
DB CR,LF,'CHAS (0 - 24) : ',0

MINUTI:
DB CR,LF,'MINUTI (0 - 59) : ',0

SEKUNDI:
DB CR,LF,'SEKUNDI (0 - 59) : ',0

TRIER:
DB CR,LF,'NATISNI NIAKOI BUTON ZA DA ZAPISHESH TEZI DANNI ',CR,LF,0

TEXT0:
DB CR,LF,'******** DALLAS SEMICONDUCTOR ********* '
DB CR,LF,'******** DS1307 TEST PROGRAMM ********* ',CR,LF
DB CR,LF,'*MOLIA IZBERETE OPCIA ZA DA PRODALZITE* '
DB CR,LF,'--------------------------------------- '
DB CR,LF,'A. SET TIME(MANUAL) B. SET RAM '
DB CR,LF,'C. READ DATE/TIME D. READ RAM '
DB CR,LF,'E. OSC ON F. OSC OFF '
DB CR,LF
DB CR,LF,'G. SQW/OUT ON-1HZ H. SQW/OUT ON-4KHZ'
DB CR,LF,'I. SQW/OUT ON-8KHZ J. SQW/OUT ON-32KHZ'
DB CR,LF
DB CR,LF,'K. SQW/OUT OFF'
DB CR,LF,'L. WRITE RAM UNIQUE PATTERN '
DB CR,LF,'ESC. TO QUIT ',0

TEXT1:
DB CR,'DATE: ',0

TEXT2:
DB 'TIME: ',0

TEXT3:
DB CR,LF,0

TEXT4:
DB CR,LF,'natisni niakoi klavish za vrashtane'
DB CR,LF,0

TEXT5:
DB CR,LF,'ENTER THE BYTE VALUE WHICH WILL FILL THE RAM'
DB CR,LF,0

TEXT6:
DB CR,LF,'RAM   RAM'
DB CR,LF,'ADDR  DATA'
DB CR,LF,'-----------------------------'
DB CR,LF,0

;******************************************
;**** END OF PROGRAM ************
;******************************************
END