; ---------------------------------------------------------------------------------------------------------- ; Subrotinas de controle do relogio de tempo real DS1302 para familia PIC16F 09/05/2012 ; ; ; As seguintes subrotinas fazem parte deste arquivo: ; ; DS1302_SET_TIME................... Acerta data e hora do DS1302 ; CHAMADA: movlw buffer ; movwf FSR ; call DS1302_SET_TIME ; ; DS1302_READ_BURST................. Leitura bufferizada do DS1302 ; CHAMADA: movlw buffer ; movwf FSR ; call DS1302_READ_BURST ; ; ---------------------------------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------------------------------- ; LAYOUT DOS REGISTRADORES DO CHIP DS1302 CONFORME SEU DATA SHEET ; REGISTRADORES ; CAMPO LER GRAVAR FORMATO ; ---------------------------------------------------------------------------------------------------------- ; Segundos 0x81 0x80 decimal (BCD 00-59) ; Minutos 0x83 0x82 decimal (BCD 00-59) ; Horas 0x85 0x84 decimal (BCD 00-23 para relogio de 24 horas) ; Dia do mes 0x87 0x86 decimal (BCD 00-31) ; Mes 0x89 0x88 decimal (BCD 00-12) ; Dia da semana 0x8B 0x8A decimal (BCD 01-07) ; Ano 0x8D 0x8C decimal (BCD 00-99) ; WP 0x8F 0x8E ; TSC 0x91 0x90 ; ; ---------------------------------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------------------------------- ; Incluir os seguintes registradores e simbolos no programa ; ---------------------------------------------------------------------------------------------------------- ;DS1302_CMD RES 1 ; buffer de comando ;DS1302_WK1 RES 1 ; registrador de trabalho ;DS1302_WK2 RES 1 ; registrador de trabalho ;DS1302_WK3 RES 1 ; registrador de trabalho ; ;#define DS1302_CE_TRIS TRISB ;#define DS1302_CE_PORT PORTB ;DS1302_CE equ 0 ; ;#define DS1302_IO_TRIS TRISB ;#define DS1302_IO_PORT PORTB ;DS1302_IO equ 4 ; ;#define DS1302_SCLK_TRIS TRISB ;#define DS1302_SCLK_PORT PORTB ;DS1302_SCLK equ 5 ; ; ---------------------------------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------------------------------- ; Funcoes de controle de uso interno das subrotinas (o programador nao necessitara usar isto) ; ---------------------------------------------------------------------------------------------------------- #define DS1302_CE_ENABLE bsf DS1302_CE_PORT,DS1302_CE ; funcao chip enable #define DS1302_CE_DISABLE bcf DS1302_CE_PORT,DS1302_CE ; funcao chip disable #define DS1302_SCLK_ENABLE bsf DS1302_SCLK_PORT,DS1302_SCLK ; funcao clock enable #define DS1302_SCLK_DISABLE bcf DS1302_SCLK_PORT,DS1302_SCLK ; funcao clock disable ; ---------------------------------------------------------------------------------------------------------- ; ACERTA O RELOGIO ; ; Esta subrotina acerta o relogio do DS1302. ; ; ENTRADA: FSR0 aponta buffer de dados com SSMMHHDDMMWWAA ; ; Os dados devem ser passados para esta rotina atraves de um buffer de 8 bytes, enderecado pelo registrador ; FSR0, na memoria de dados do PIC, no formato 'SSMMHHDDMMWWAAwp' onde: ; ; SS ........................ segundos em decimal (BCD 00-59) ; MM ........................ minutos em decimal (BCD 00-59) ; HH ........................ horas em decimal (BCD 00-23 para relogio de 24 horas) ; DD ........................ dia em decimal (BCD 00-31) ; MM ........................ mes em decimal (BCD 00-12) ; WW ........................ dia sem em decimal (BCD 01-07) ; AA ........................ ano em decimal (BCD 00-99) ; wp ........................ write protect - sempre 0x00 ; ; -------------------------------------------------------------- ; EXEMPLO: ; Acertar data e hora do DS1302: ; Data: 08/05/12 ; Dia da semana: terca feira (3) ; Horas: 12:44:00 ; ; seg res 1 ; segundos ; min res 1 ; minutos ; hor res 1 ; horas ; dia res 1 ; dia ; mes res 1 ; mes ; sem res 1 ; dia da semana ; ano res 1 ; ano ; wp res 1 ; write protect ; ; movlw 0x00 ; segundos ; movwf seg ; movlw 0x44 ; minutos ; movwf min ; movlw 0x12 ; horas ; movwf hor ; movlw 0x08 ; dia ; movwf dia ; movlw 0x05 ; mes ; movwf mes ; movlw 0x03 ; dia da semana ; movwf sem ; movlw 0x12 ; ano ; movwf ano ; movlw 0x00 ; desabilita o write protect ; movwf wp ; movlw seg ; endereco do inicio do buffer ; movwf FSR ; carrega o indexador ; call DS1302_SET_TIME ; acerta o RTC ; ; movlw seg ; endereco do inicio do buffer ; movwf FSR ; carrega o indexador ; call DS1302_READ_BURST ; leitura do RTC ; ---------------------------------------------------------------------------------------------------------- DS1302_SET_TIME bsf STATUS,RP0 bcf DS1302_SCLK_TRIS,DS1302_SCLK ; <=== OUTPUT bcf DS1302_CE_TRIS,DS1302_CE ; <=== OUTPUT bcf DS1302_IO_TRIS,DS1302_IO ; <=== OUTPUT bcf STATUS,RP0 DS1302_CE_DISABLE ; desabilita o CE DS1302_SCLK_DISABLE ; abaixa o sinal de clock nop nop nop nop movlw .8 ; enviar 8 bits do comando movwf DS1302_WK1 ; carrega o contador movlw 0xBE ; write burst movwf DS1302_CMD DS1302_CE_ENABLE ; habilita o CE nop nop nop nop nop nop nop nop DS1302_SETME1 bcf DS1302_IO_PORT,DS1302_IO ; IO=0 bcf STATUS,C ; C=0 rrf DS1302_CMD,f ; empurra um bit de dado para o Carry btfsc STATUS,C ; se C=0 deixa IO como esta, senao, bsf DS1302_IO_PORT,DS1302_IO ; IO=1 nop nop nop nop DS1302_SCLK_ENABLE ; levanta o sinal de clock (envia) nop nop nop nop DS1302_SCLK_DISABLE ; abaixa o sinal de clock decfsz DS1302_WK1,f ; ja acaou de enviar o comando? goto DS1302_SETME1 ; nao, continua... movlw .8 ; bytes de dados a enviar movwf DS1302_WK2 DS1302_SETME2 movlw .8 ; bits em cada byte de dado movwf DS1302_WK1 DS1302_SETME3 bcf DS1302_IO_PORT,DS1302_IO ; IO=0 bcf STATUS,C ; C=0 rrf INDF,f ; C=x btfsc STATUS,C ; se C=0 deixa IO como esta bsf DS1302_IO_PORT,DS1302_IO ; IO=1 nop nop nop nop DS1302_SCLK_ENABLE ; levanta o sinal de clock (envia) nop nop nop nop DS1302_SCLK_DISABLE ; abaixa o sinal de clock decfsz DS1302_WK1,f ; ja acaou de enviar um byte? goto DS1302_SETME3 ; nao, continua... movf INDF,w ; somente avanca um byte no buffer incf FSR,f decfsz DS1302_WK2,f ; ja acaou de todos os dados? goto DS1302_SETME2 ; nao, continua... DS1302_CE_DISABLE return ; ---------------------------------------------------------------------------------------------------------- ; LEITURA DO DS1302 ; ; Le os 8 registradores do DS1302 e coloca o resultado no buffer de leitura, marcando o final ; dos dados com 0x0D. ; ; ENTRADA: FSR0 aponta para o buffer de leitura de 8 bytes. ; ; SAIDA : O buffer de leitura contera o resultado. ; FSR0 aponta para o ultimo byte (0x0D) no buffer de leitura. ; ; ---------------------------------------------------------------------------------------------------------- DS1302_READ_BURST bsf STATUS,RP0 bcf DS1302_SCLK_TRIS,DS1302_SCLK ; <=== OUTPUT bcf DS1302_CE_TRIS,DS1302_CE ; <=== OUTPUT bcf DS1302_IO_TRIS,DS1302_IO ; <=== OUTPUT bcf STATUS,RP0 DS1302_CE_ENABLE ; habilita o CE nop nop nop nop nop nop nop nop movlw 0xBF ; read burst movwf DS1302_CMD ; movlw .8 ; enviar 8 bits do comando movwf DS1302_WK1 ; carrega o contador DS1302_READ_B3 bcf DS1302_IO_PORT,DS1302_IO ; IO=0 bcf STATUS,C ; C=0 rrf DS1302_CMD,f ; empurra um bit de dado para o Carry btfsc STATUS,C ; se C=0 deixa IO como esta, senao, bsf DS1302_IO_PORT,DS1302_IO ; IO=1 nop nop nop nop DS1302_SCLK_ENABLE ; levanta o sinal de clock (envia) nop nop nop nop DS1302_SCLK_DISABLE ; abaixa o sinal de clock decfsz DS1302_WK1,f ; ja acabou de enviar o comando? goto DS1302_READ_B3 ; nao, continua... bsf STATUS,RP0 bsf DS1302_IO_TRIS,DS1302_IO ; <=== INPUT bcf STATUS,RP0 movlw .8 ; ler os 8 registradores movwf DS1302_WK2 DS1302_READ_B35 movlw .8 ; 8 bits por registrador movwf DS1302_WK1 DS1302_READ_B4 movf DS1302_IO_PORT,w ; le a porta de I/O movwf DS1302_CMD ; salva o conteudo lido bcf STATUS,C ; C=0 btfsc DS1302_CMD,DS1302_IO ; se leu zero, deixa como esta bsf STATUS,C ; senao, C=1 rrf INDF,f ; rola C para o buffer de resultado nop nop nop nop DS1302_SCLK_ENABLE ; engatilha a leitura nop nop nop nop DS1302_SCLK_DISABLE ; dispara a leitura nop nop nop nop decfsz DS1302_WK1,f ; pegou um byte completo? goto DS1302_READ_B4 ; ainda nao, continua no mesmo byte movf INDF,w ; somente avanca um byte no buffer incf FSR,f decfsz DS1302_WK2,f ; ja leu os 8 registradores? goto DS1302_READ_B35 ; ainda nao, continua... movlw 0x0D ; marca de fim movwf INDF ; marca o fim dos dados no buffer DS1302_CE_DISABLE ; senao, fim da leitura DS1302_SCLK_DISABLE ; return ; ---------------------------------------------------------------------------------------------------------- ; Processo de I/O no RTC DS1302. ; ; INICIO DO PROCESSO DE I/O ; Para iniciar uma operacao com o DS1302 os sinais SCLK e CE devem estar em nivel zero. ; A operacao se inicia quando o sinal CE e levado ao nivel alto e termina quando o ; sinal CE for levado ao nivel baixo novamente. ; ; ENVIO DE DADOS AO RTC ; Os bits de comandos e dados enviados ao RTC sao reconhecidos pelo chip na ; subida do sinal de clock e sao enviados a partir do bit menos significativo. ; ; RECEBIMENTO DE DADOS DO RTC ; A leitura se inicia na borda descendente do sinal de clock, logo apos a subida deste, ; quando o ultimo bit do comando de leitura for enviado ao RTC. Dai para frente todos ; os dados devem ser lidos na borda de descida do sinal de clock. ; ; PROCESSO DE GRAVACAO ADOTADO NESTA ROTINA ; A gravacao do relogio sera feita no modo "Burst", isto e, todos os ; registradores do DS1302 serao gravados numa unica operacao, usando-se o comando ; 0xBE e mantendo-se o sinal CE alto enquanto os bytes sao enviados ao RTC. ; A gravacao, para acertar a data e hora, deve enviar 8 bytes de dados, iniciando ; pelo campo "Segundos" e terminando com 0x00 no campo "WP". Se 0x00 nao for ; especificado em "WP", o relogio nao recebera os dados. ; Os dados deverao ser enviados na ordem 'ssmmhhDDMMWWAA00', onde: ; ss ............. segundos (0-59) ; mm ............. minutos (0-59) ; hh ............. horas (0-59) ; DD ............. dia (0-31) ; MM ............. mes (0-12) ; WW ............. semana (1-7) dia da semana (Domingo=1 ate Sabado=7) ; AA ............. ano (1-99) ; 00 ............. zeros para desabilitar o write protect ; Ao final o sinal CE sera levado ao nivel baixo novamente. ; ; PROCESSO DE LEITURA ADOTADO NESTA ROTINA ; A leitura do relogio tambem sera feita no modo "Burst", isto e, todos os ; registradores serao lidos de uma so vez, usando-se o comando 0xBF e mantendo-se o ; sinal CE alto enquanto os bytes sao lidos do RTC. Ao final o sinal CE sera levado ao ; nivel baixo novamente. Os valores dos registradores serao colocados num buffer de ; leitura na ordem 'ssmmhhDDMMWWAA0D'. ; Notar que o final do buffer sera marcado com Carriage Return (0x0D). ; ; --------------------------------------------------------------------------------------------------