ENGLISH 简体中文 日本語 한국어  

    로그인 | 회원가입 


   
 
키워드나 부품번호를 입력해주세요    




애플리케이션 노트 2361

Interfacing an SPI-Interface RTC with a PIC Microcontroller

Abstract: This application note provides an example schematic and software for using the DS1305 real-time clock (RTC) with a PIC microcontroller. The DS1305 is connected to the PIC using the SPI interface. A serial RS-232 port is used for data input and output.

Pin Configuration

Description

The DS1305 real-time clock (RTC) can be interfaced with a microcontroller (µC) using a 3-wire or an SPI™ interface. This application note shows how to connect a DS1305 to a PIC16F628µC. The DS1306 could also be used in this application.

The circuit uses a serial interface for communications. A terminal program with user control of the RS232 DTR control line is required. DTR is used to reset the µC and start code execution. A DS232 is used to perform TTL/RS232 level translation.

A schematic of the circuit is shown in Figures 1 and 2. The software is shown in Figure 3.

Figure 1. PIC16F628 interface.
For Larger Image

Figure 1. PIC16F628 interface.

Figure 2. DS1305 daughter card.
For Larger Image

Figure 2. DS1305 daughter card.

Figure 3. Code for Demo

#include <P16F628.inc>
list p=16F628
__config H'3F2A'
; this config gives us LVP and enables /MCLR
errorlevel -302 ; don't print message for operands that are not in bank 0
; define the baud rate for the hardware uart
#define BAUD_VALUE 0x15 ; 0x15 sets the baud rate to 57600 with a 20.0MHz
crystal
#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 ; this is 0x0C for the 16F84
save_w equ 0x38
save_status equ 0x39
SET_BANK0 MACRO
bcf STATUS, RP0
bcf STATUS, RP1
ENDM
SET_BANK1 MACRO
bsf STATUS, RP0
bcf STATUS, RP1
ENDM
org 0x00
RESET:
goto START
;-----------------------------------------
;--------------- start ---------------
;-----------------------------------------
org 0x0A
START:
; turn off the comparator for porta
SET_BANK0
movlw 0x07
movwf CMCON
; turn off the voltage reference module
SET_BANK1
movlw 0x00
movwf VRCON
SET_BANK0
clrf PORTA ; initialize PORTA
movlw 0x08 ; RA3 read (high-z)
SET_BANK1
movwf TRISA ; set pins for input or output
bsf OPTION_REG, 7 ; turn weak pull-ups on all inputs
SET_BANK0
movlw 0x07 ; Initialize CMCON
movwf CMCON
call uart_init
CheckForCommands:
movlw banner-1 ; move label address into W register
call write ; print string starting at address of label
call uart_getchar ; returns character in W
call uart_putchar ; echo
movwf TMP
bcf TMP,5 ; convert to upper case
movf TMP,W ; put back in W
xorlw 'S' ; write to RTC
btfss STATUS,Z
goto not_ss
call set_clock ; set the clock using data from user
goto CheckForCommands
not_ss:
movf TMP,W ; retrieve character
xorlw 'R' ; read from RTC
btfss STATUS,Z
goto not_rr
call read_clock ; display time and date via serial port
goto CheckForCommands
not_rr:
goto CheckForCommands
;-----------------------------------------
;--- uart routines ---
;-----------------------------------------
;---- send a byte through the serial port ----
uart_putchar:
charwait1:
btfss PIR1, TXIF
goto charwait1
movwf TXREG
return
;---- get a byte from the serial port ----
uart_getchar:
charwait2:
btfss PIR1, RCIF ; is data avalible?
goto charwait2 ; if not then wait
movfw RCREG
return
;----- initialize the serial port -----
uart_init:
SET_BANK1
movlw BAUD_VALUE ; set the baud rate
movwf SPBRG ; mov baudreg into SPBRG, set baud rate
bcf TXSTA, SYNC ; clear SYNC bit, asynchronous mode
bsf TXSTA, BRGH ; BRGH=1, high speed SP mode.
bsf TXSTA, TXEN ; enable transmission
bcf PIE1, RCIE ; disable serial port interrupt
SET_BANK0
bsf RCSTA, SPEN ; set SPEN bit, serial port enable
bsf RCSTA, CREN ; set CREN bit, serial port receive enable
return ; return
;----------------------------------------
;-- text strings for user interface --
;----------------------------------------
banner:
dt "\n\rDS1305 SPI DEMO\n\rR)ead time S)et time\n\r",0h
year:
dt "\n\rYear (0-99): ",0h
month:
dt "Month (1-12): ",0h
dow:
dt "Day of Week (1-7): ",0h
date:
dt "Date (1-28,29,30,31): ",0h
hour:
dt "Hour (0-23): ",0h
minute:
dt "Minute (0-59): ",0h
second:
dt "Second (0-59): ",0h
;-----------------------------------------
;-- character conversion routines --
;-----------------------------------------
;--------- ascii to bcd ----------
readbcd:
clrf TMP ; clear temp reg
gobcd:
call uart_getchar ; returns character in W
call uart_putchar ; echo to screen
xorlw 0dh ; if cr, Z will be set
btfss STATUS,Z ; skip if clear
goto bcd ; go to bcd if Z=0
movf TMP,W ; done, move final value to W
return ; and return
bcd:
xorlw 0dh ; restore value
addlw -30h ; subtract ascii offset
btfsc W,4 ; jump if not A-F
addlw -7 ; if A-F, subtract 7
digit:
andlw 0x0f ; clear upper nibble
bcf TMP,4 ; clear upper nibble of temp reg
bcf TMP,5
bcf TMP,6
bcf TMP,7
movwf SCRATCH ; save W
movf TMP,W ; copy TMP to W
movwf TMP2 ; save TMP
movf SCRATCH,W ; restore W
movwf TMP ; TMP now has org W value
movf TMP2,W ; W now has org TMP value
swapf TMP2,W ; swap nibbles
iorwf TMP,W ; insert bits 0-3 of TMP to W
movwf TMP ; move W into temp reg
goto gobcd ; continue until CR is encountered
;-- convert bcd to ascii --
;-- entry: W=bcd value exit: W=last ascii --
writebcd:
movwf TMP ; save W
swapf TMP,W ; swap nibbles
andlw 0x0f ; clear bits 4-7
addlw 0x06 ; add 6
btfss STATUS,DC ; if a-f, DC=1
goto lessnine ; if DC=0, < 9, so goto lessnine
addlw 0x31 ; add 31h to make ascii
goto digit1 ; skip to output
lessnine:
addlw 0x2a ; add offset for 0-9 to make ascii
digit1:
call uart_putchar ; print char
movf TMP,W ; restore W
andlw 0x0f ; clear bits 4-7
addlw 0x06 ; add 6
btfss STATUS,DC ; if a-f, DC=1
goto lessnine2 ; if DC=0, < 9, so goto lessnine
addlw 0x31 ; add 31h to make ascii
goto digit2 ; skip to output
lessnine2:
addlw 0x2a ; add offset for 0-9 to make ascii
digit2:
call uart_putchar ; print char
return
;---------------------------------------------
;-- display RTC data --
;---------------------------------------------
read_clock:
call RTC_brst_rd ; get the data from the RTC
read_regs:
movf YRS,W
call writebcd
movlw '/'
call uart_putchar
movf MON,W
call writebcd
movlw '/'
call uart_putchar
movf DAYS,W
call writebcd
movlw ' '
call uart_putchar
movf DOW,W
call writebcd
movlw ' '
call uart_putchar
movf HRS,W
call writebcd
movlw ':'
call uart_putchar
movf MINS,W
call writebcd
movlw ':'
call uart_putchar
movf SECS,W
call writebcd
movlw 0x0d ; cr
call uart_putchar
return
;---------------------------------------------
;-- write to the RTC with user-entered data --
;---------------------------------------------
set_clock:
movlw year-1 ; prompt user for data (year)
call write
call readbcd ; get the data
movwf YRS ; save it
movlw month-1 ; prompt user for data (month)
call write
call readbcd
movwf MON
movlw date-1 ; prompt user for data (month)
call write
call readbcd
movwf DAYS
movlw dow-1 ; prompt user for data (month)
call write
call readbcd
movwf DOW
movlw hour-1 ; prompt user for data (month)
call write
call readbcd
movwf HRS
movlw minute-1 ; prompt user for data (month)
call write
call readbcd
movwf MINS
movlw second-1 ; prompt user for data (month)
call write
call readbcd
movwf SECS
call RTC_brst_wr ; now write data to RTC
return
;-----------------------------------------
;-- RTC routines --
;-----------------------------------------
RTC_brst_rd:
bsf SPI_CLK ; assert SCLK for CPOL=1
bsf SPI_CE ; assert CE
movlw 0h ; seconds register read address
call write_RTC ; send the address
call read_RTC ; read the seconds data
movwf SECS ; save it
call read_RTC ; and so on
movwf MINS
call read_RTC
movwf HRS
call read_RTC
movwf DOW
call read_RTC
movwf DAYS
call read_RTC
movwf MON
call read_RTC
movwf YRS
bcf SPI_CE ; de-assert CE
return
RTC_brst_wr:
bsf SPI_CLK ; assert SCLK for CPOL=1
bsf SPI_CE ; assert CE
movlw 08fh ; control register write address
call write_RTC
movlw 0 ; clear write protect
call write_RTC
bcf SPI_CE ; de-assert CE
bsf SPI_CLK ; assert SCLK for CPOL=1
bsf SPI_CE ; assert CE
movlw 08fh ; control register write address
call write_RTC
movlw 0 ; enable osc, disable interrupts
call write_RTC
bcf SPI_CE ; de-assert CE
bsf SPI_CLK ; assert SCLK for CPOL=1
bsf SPI_CE ; assert CE
movlw 80h ; send seconds register write address
call write_RTC
movf SECS, W
call write_RTC
movf MINS, W
call write_RTC
movf HRS, W
call write_RTC
movf DOW, W
call write_RTC
movf DAYS, W
call write_RTC
movf MON, W
call write_RTC
movf YRS, W
call write_RTC
bcf SPI_CE ; de-assert CE
return
;---- 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
;-----------------------------------------
;-- pclsub used for indirect addressing --
;-----------------------------------------
pclsub:
incf SCRATCH,F ; advance table pointer
movf SCRATCH,W ; move table pointer to W
movwf PCL ; jump to address pointed by PCLATH,W
;----------------------------------------
;-- write a string to USART --
;----------------------------------------
write:
movwf SCRATCH ; FSR = string address
GoWrite:
call pclsub ; advance pointer and read pointed byte
addlw 0h ; if contents are zero, Z will be set
btfsc STATUS,Z ; skip if clear
return ; current character is null: end of string
call uart_putchar ; print one character
goto GoWrite ; loop
END


관련 부품  APP 2361: Aug 25, 2003
DS1305 직렬 경보 실시간 클록 전체 데이터 시트
(PDF, 496kB)
무료 샘플
DS1306 직렬 경보 실시간 클록 전체 데이터 시트
(PDF, 388kB)
무료 샘플
DS1390 트리클 충전기가 내장된 저전압 SPI/3-Wire RTC 전체 데이터 시트
(PDF, 388kB)
무료 샘플
DS1391 트리클 충전기가 내장된 저전압 SPI/3-Wire RTC 전체 데이터 시트
(PDF, 388kB)
무료 샘플

자동 업데이트
관심 분야의 애플리케이션 노트가 나올 때 자동으로 업데이트를 원하십니까? 그렇다면 EE-Mail™을 신청하십시오.


We Want Your Feedback!



의견을 보내주세요!
위 내용이 도움이 되셨나요?
여러분의 의견을 기다립니다 — Maxim은 보내주신 정정이나 제안사항을 반영하고 있습니다. 이 페이지를 평가하고 의견을 보내주십시오.

 

다운로드, PDF 형식다운로드, PDF 형식 (75kB)
 AN2361, AN 2361, APP2361, Appnote2361, Appnote 2361

        •         •         •     개인정보보호 정책     •     법적 고지

    Copyright © 2009 by Maxim Integrated Products