Real time clock SPI con PIC16F628

DS1305 è un Real Time Clock con porta I2C. Ecco come utilizzarlo con un PIC16F628 e come monitorarlo attraverso una connessione seriale RS232.

REAL TIME CLOCK SPI CON PIC16F628

Lo schema di figura 1 mostra la connessione tra il modulo RTC ed il   PIC, connessione effettuata mediante interfaccia SPI a tre fili. Per questa applicazione è possibile utilizzare anche un DS1306. Il PIC legge i dati dal DS1305 e li invia ad un PC attraverso una connessione RS232. La linea DTR della porta seriale è utilizzata per resettare il PIC ed avviare quindi il programma. La conversione dei livelli TTL/RS232 viene effettuata con un DS232. Il listato 1 riporta il sorgente assembler/assembly da utilizzare nel PIC.

Figura 1. Schema elettrico per la connessione del RTC al PIC

Figura 1. Schema elettrico per la connessione del RTC al PIC

#include <P16F628.inc>
list p=16F628
__config H’3F2A’
#define BAUD_VALUE 0x15
#define SPI_CLK PORTA,1
#define SPI_MOSI PORTA,2
#define SPI_MISO PORTA,3
#define SPI_CE PORTA,4
SCRATCH equ 0x40
TMP equ 0x41
TMP2 equ 0x42
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
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:
SET_BANK0
movlw 0x07
movwf CMCON
SET_BANK1
movlw 0x00
movwf VRCON
SET_BANK0
clrf PORTA
movlw 0x08
SET_BANK1
movwf TRISA
bsf OPTION_REG, 7
SET_BANK0
movlw 0x07
movwf CMCON
call uart_init
CheckForCommands:
movlw banner-1
call write
call uart_getchar
call uart_putchar
movwf TMP
bcf TMP,5
movf TMP,W
xorlw ‘S’
btfss STATUS,Z
goto not_ss
call set_clock
goto CheckForCommands
not_ss:
movf TMP,W
xorlw ‘R’
btfss STATUS,Z
goto not_rr
call read_clock
goto CheckForCommands
not_rr:
goto CheckForCommands
;———————-———————-—————————
;—- uart routines
;——————————————-——————————
uart_putchar:
charwait1:
btfss PIR1, TXIF
goto charwait1
movwf TXREG
return
;—————————————————————————
uart_getchar:
charwait2:
btfss PIR1, RCIF
goto charwait2
movfw RCREG
return
;——-——————————————————————
uart_init:
SET_BANK1
movlw BAUD_VALUE
movwf SPBRG
bcf TXSTA, SYNC
bsf TXSTA, BRGH
bsf TXSTA, TXEN
bcf PIE1, RCIE
SET_BANK0
bsf RCSTA, SPEN
bsf RCSTA, CREN
return ; return
;————————————————————————
banner:
dt “\n\rDS1305 SPI
DEMO\n“
dt “\rR)ead time S)et”
dt “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 —
;— ascii to bcd ———-
readbcd:
clrf TMP
gobcd:
call uart_getchar
call uart_putchar
xorlw 0dh
btfss STATUS,Z
goto bcd
movf TMP,W
return
bcd:
xorlw 0dh
addlw -30h
btfsc W,4
addlw -7
digit:
andlw 0x0f
bcf TMP,4
bcf TMP,5
bcf TMP,6
bcf TMP,7
movwf SCRATCH
movf TMP,W
movwf TMP2
movf SCRATCH,W
movwf TMP
movf TMP2,W
swapf TMP2,W
iorwf TMP,W
movwf TMP
goto gobcd
;— convert bcd to ascii —
;— entry: W=bcd value
;— exit: W=last ascii
writebcd:
movwf TMP
swapf TMP,W
andlw 0x0f
addlw 0x06
btfss STATUS,DC
goto lessnine
addlw 0x31
goto digit1
lessnine:
addlw 0x2a
digit1:
call uart_putchar
movf TMP,W
andlw 0x0f
addlw 0x06
btfss STATUS,DC
goto lessnine2
addlw 0x31
goto digit2
lessnine2:
addlw 0x2a
digit2:
call uart_putchar
return
;— display RTC data —
read_clock:
call RTC_brst_rd
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
call uart_putchar
return
;— write to the RTC ———-
set_clock:
movlw year-1
call write
call readbcd
movwf YRS
movlw month-1
call write
call readbcd
movwf MON
movlw date-1
call write
call readbcd
movwf DAYS
movlw dow-1
call write
call readbcd
movwf DOW
movlw hour-1
call write
call readbcd
movwf HRS
movlw minute-1
call write
call readbcd
movwf MINS
movlw second-1
call write
call readbcd
movwf SECS
call RTC_brst_wr
return
;— RTC routines ————-———-
RTC_brst_rd:
bsf SPI_CLK
bsf SPI_CE
movlw 0h
call write_RTC
call read_RTC
movwf SECS
call read_RTC
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
return
RTC_brst_wr:
bsf SPI_CLK
bsf SPI_CE
movlw 08fh
call write_RTC
movlw 0
call write_RTC
bcf SPI_CE
bsf SPI_CLK
bsf SPI_CE
movlw 08fh
call write_RTC
movlw 0
call write_RTC
bcf SPI_CE
bsf SPI_CLK
bsf SPI_CE
movlw 80h
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
return
;—— Read RTC into W ———-
read_RTC:
movlw 08h ;Send 8 bits
movwf COUNT
SPI_read_loop:
rlf TMP, 1
bcf SPI_CLK
bcf TMP, 0
btfsc SPI_MISO
bsf TMP, 0
bsf SPI_CLK
decfsz COUNT, 1
goto SPI_read_loop
movf TMP, W
return
;—- Write the W to RTC —-
write_RTC:
movwf TMP
SPI_write:
movlw 08h
movwf COUNT
SPI_w_loop:
bcf SPI_CLK
bcf SPI_MOSI
btfsc TMP, 7
bsf SPI_MOSI
SPI_w_cont:
rlf TMP, 1
bsf SPI_CLK
decfsz COUNT, 1
goto SPI_w_loop
return
pclsub:
incf SCRATCH,F
movf SCRATCH,W
movwf PCL
;— write a string to
; USART ————-———-———-———-
write:
movwf SCRATCH
GoWrite:
call pclsub
addlw 0h
btfsc STATUS,Z
return
call uart_putchar
goto GoWrite
END
Listato 1

Una risposta

  1. Maurizio Di Paolo Emilio Maurizio 30 luglio 2016

Scrivi un commento