H P S P I N E l e t r ô n i c a D i g i t a l e P r o g r a m a ç ã o d e M i c r o c o n t r o l a d o r e s P I C |
HOME PROJETOS PROGRAMAÇÃO |
O objetivo desta página é mostrar duas funções para comunicação entre um microcontrolador e o relógio de tempo real DS1302:
1 - A função DS1302_READ_BURST que faz a leitura do relógio.
2 - A função DS1302_SET_TIME que permite acertar o relógio.
Ambas as funções se incumbem de fazer a comunicação serial entre o microcontrolador e o RTC.
Essas funções estão disponíveis em versões para a família 16F e para a família 18F.
Um relógio de tempo real (RTC) permite que aplicações que necessitem adiquirir informações de data e hora possam obtê-las de um circuito externo. Aqui, em particular, falaremos sobre relógio de tempo real (RTC) DS1302.
Existem vantagens e desvantagens em se usar um dispositivo RTC externo no projeto.
Uma das vantagens de se usar um RTC externo é que o programador não precisa se preocupar em desenvolver um algorítmo escrito especialmente para manter o relógio funcionando, o que geralmente deveria ser feito usando-se uma interrupção de Timer, talvez um cristal externo apropriado e muito controle sobre o código escrito para que o relógio seja o mais preciso possível.
Outra vantagem é que o RTC externo geralmente permite o uso de uma bateria para servir de nobreak, o que permite ao RTC continuar funcionando durante a falta de energia da rede. O projetista não teria que se preocupar em implementar um circuito de nobreak, que certamente complicaria o circuito.
As desvantagens são que, dependendo do tipo RTC adotado, será necessário dedicar um certo número de portas do microcontrolador para poder se comunicar com o RTC e também a necessidade de escrever um código para se comunicar com ele.
Usando-se as funções aqui descritas, não será necessário escrever o código para comunicação com o RTC e, assim, uma das desvantagens fica eliminada, restando apenas a desvantagem de usarmos algumas portas do microcontrolador para acessar o RTC.
O DS1302 é um dispositivo de acesso serial que fornece data, hora e dia da semana.
A figura abaixo mostra a pinagem do integrado.
|
|
|
Pinagem do DS1302.
Obtenha aqui o data sheet do DS1302
Antes de usar as funções DS1302_READ_BURST e DS1302_SET_TIME será necessário definir as características do hardware que será configurado para o microcontrolador se comunicar com o DS1302. Os seguintes símbolos e registradores devem ser definidos no programa:
1 DS1302_CMD RES 1 ; byte de comando
2 DS1302_WK1 RES 1 ; registrador de trabalho
3 DS1302_WK2 RES 1 ; registrador de trabalho
4 DS1302_WK3 RES 1 ; registrador de trabalho
5
6 #define DS1302_CE_TRIS TRISB ; controle de I/O da porta CE
7 #define DS1302_CE_PORT PORTB ; porta para o sinal CE
8 DS1302_CE equ 0 ; bit do sinal CE
9
10 #define DS1302_IO_TRIS TRISB ; controle de I/O da porta IO
11 #define DS1302_IO_PORT PORTB ; porta para o sinal IO
12 DS1302_IO equ 4 ; bit do sinal IO
13
14 #define DS1302_SCLK_TRIS TRISB ; controle de I/O da porta SCLK
15 #define DS1302_SCLK_PORT PORTB ; porta para o sinal SCLK
16 DS1302_SCLK equ 5 ; bit do sinal SCLK
|
Os registradores DS1302_CMD, DS1302_WK1, DS1302_WK2 e DS1302_WK3 são registradores de trabalho usados internamente pelas funções DS1302_READ_BURST e DS1302_SET_TIME. Esses registradores devem ser definidos como se apresentam, sem modificações.
Qualquer bit de qualquer porta pode ser usado na configuração de hardware. A comunicação com o DS1302 será feita através dos sinais SCLK, IO e CE do RTC e, para que o circuito e o programa funcionem adequadamente, cada um desses sinais deverá ser definido usando-se os símbolos apropriados.
Para o sinal CE devemos definir os símbolos DS1302_CE_TRIS que especifica o controle de I/O da porta escolhida no símbolo DS1302_CE_PORT e o símbolo DS1302_CE representa o bit da porta DS1302_CE_PORT escolhido para esse sinal.
Para o sinal IO devemos definir os símbolos DS1302_IO_TRIS que especifica o controle de I/O da porta escolhida no símbolo DS1302_IO_PORT e o símbolo DS1302_IO representa o bit da porta DS1302_IO_PORT escolhido para esse sinal.
Para o sinal SCLK devemos definir os símbolos DS1302_SCLK_TRIS que especifica o controle de I/O da porta escolhida no símbolo DS1302_SCLK_PORT e o símbolo DS1302_SCLK representa o bit da porta DS1302_SCLK_PORT escolhido para esse sinal.
A função DS1302_SET_TIME é usada para acertar data, a hora e o dia da semana do DS1302.
Essa função gravará todos os registradores do RTC de uma só vez com os dados especificados pelo programador num buffer de 8 bytes na ordem "ssmmhhDDMMWWAAWP", onde:
ss ............. segundos (0-59)
mm ............. minutos (0-59)
hh ............. horas (0-59)
DD ............. dia (0-31)
MM ............. mes (0-12)
WW ............. semana (01-07) dia da semana (Domingo=01 ate Sabado=07)
AA ............. ano (01-99)
WP ............. sempre zero para desabilitar a proteção contra gravação
|
A função DS1302_SET_TIME espera que o endereço do buffer de dados de 8 bytes seja passado no registrador especial FSR e que os dados do buffer estejam preenchidos corretamente pois não a função não fará validação dos mesmos, assim, pode acontecer do relógio ficar com data e hora inválidos.
Se programa estiver usando o registrador FSR, este deverá ser salvo antes da chamada da função DS1302_SET_TIME pois, ao retornar, esse registrador conterá um valor inválido.
Abaixo temos um trecho de programa assembler que exemplifica o uso da função DS1302_SET_TIME para acertar o relógio no dia 13 de Maio de 2012, Domingo, às 15:23:35 horas.
1 DS1302_CMD RES 1 ; buffer de comando
2 DS1302_WK1 RES 1 ; registrador de trabalho
3 DS1302_WK2 RES 1 ; registrador de trabalho
4 DS1302_WK3 RES 1 ; registrador de trabalho
5
6 #define DS1302_CE_TRIS TRISA
7 #define DS1302_CE_PORT PORTA
8 DS1302_CE equ 6
9
10 #define DS1302_IO_TRIS TRISB
11 #define DS1302_IO_PORT PORTB
12 DS1302_IO equ 4
13
14 #define DS1302_SCLK_TRIS TRISA
15 #define DS1302_SCLK_PORT PORTA
16 DS1302_SCLK equ 7
17
18 . .
19 . .
20 . .
21 seg res 1 ; segundos
22 min res 1 ; minutos
23 hor res 1 ; horas
24 dia res 1 ; dia
25 mes res 1 ; mes
26 sem res 1 ; dia da semana
27 ano res 1 ; ano
28 wp res 1 ; write protect
29 . .
30 . .
31 . .
32 movlw 0x35 ; segundos
33 movwf seg
34 movlw 0x23 ; minutos
35 movwf min
36 movlw 0x15 ; horas
37 movwf hor
38 movlw 0x13 ; dia
39 movwf dia
40 movlw 0x05 ; mes
41 movwf mes
42 movlw 0x01 ; dia da semana = Domingo
43 movwf sem
44 movlw 0x12 ; ano
45 movwf ano
46 movlw 0x00 ; desabilita o write protect
47 movwf wp
48;
49 movlw seg ; endereco do inicio do buffer
50 movwf FSR ; carrega o indexador
51 call DS1302_SET_TIME ; acerta o RTC
52 . .
53 . .
54 . .
|
Da linha 1 a linha 16 vemos a definição dos registradores de trabalho e dos símbolos da configuração de hardware.
Da linha 21 à linha 28 temos a definição do buffer de dados de 8 bytes a serem enviados ap relógio.
Da linha 32 à linha 47 fazemos a carga de valores a serem gravados para acertar o relógio. Note que todos os valores a serem especificados devem estar no formato BCD, por isso a carga desses valores é feita, por exemplo, usando-se a instrução "movlw 0x35" e não "movlw 35" nem "movlw .35".
Na linha 49 obtemos o endereco do início do buffer.
Na linha 50 carregamos o endereco do buffer no registrador especial de FSR
Na linha 51, finalmente, chamamos a função DS1302_SET_TIME para acertar o relógio.
O uso da função DS1302_SET_TIME em microcontroladores da família 18F é identico, porém, a carga do endereço do buffer será feita pela instrução "lfsr FSR0,seg" ao invés da instrução "movlw seg" seguida de "movwf FSR".
A função DS1302_READ_BURST lê todos os registradores do DS1302 colocando o resultado num buffer de 9 bytes na ordem "ssmmhhDDMMWWAAWPC", já vista na função DS1302_SET_TIME, exceto que o último byte C será caracter marcador de fim do buffer 0x0D.
A função DS1302_READ_BURST espera que o endereço do buffer de dados de 9 bytes seja passado no registrador especial FSR.
Após a leitura, os valores lidos estarão no formato BCD, conforme dito anteriormente.
Abaixo temos um trecho de programa assembler que exemplifica o uso da função DS1302_READ_BURST.
1 DS1302_CMD RES 1 ; buffer de comando
2 DS1302_WK1 RES 1 ; registrador de trabalho
3 DS1302_WK2 RES 1 ; registrador de trabalho
4 DS1302_WK3 RES 1 ; registrador de trabalho
5
6 #define DS1302_CE_TRIS TRISA
7 #define DS1302_CE_PORT PORTA
8 DS1302_CE equ 6
9
10 #define DS1302_IO_TRIS TRISB
11 #define DS1302_IO_PORT PORTB
12 DS1302_IO equ 4
13
14 #define DS1302_SCLK_TRIS TRISA
15 #define DS1302_SCLK_PORT PORTA
16 DS1302_SCLK equ 7
17
18 . .
19 . .
20 . .
21 seg res 1 ; segundos
22 min res 1 ; minutos
23 hor res 1 ; horas
24 dia res 1 ; dia
25 mes res 1 ; mes
26 sem res 1 ; dia da semana
27 ano res 1 ; ano
28 wp res 1 ; write protect
29 . .
30 . .
31 . .
32 movlw seg ; endereco do inicio do buffer
33 movwf FSR ; carrega o indexador
34 call DS1302_READ_BURST ; le o RTC
35 . .
36 . .
37 . .
|
O uso da função DS1302_READ_BURST em microcontroladores da família 18F é identico, porém, a carga do endereço do buffer será feita pela instrução "lfsr FSR0,seg" ao invés da instrução "movlw seg" seguida de "movwf FSR".
A seguir, para quem gosta de lixar bits e bytes, daremos uma rápida explicação de como funciona o submundo de um I/O no RTC DS1302.
Além de registradores que contêm os valores da data, hora e dias da semana, o RTC DS1302 pussui 248 bytes de memória RAM que podem ser usados pelo programador para qualquer finalidade mas uso dessa memória não será explorado aqui.
O RTC DS1302 é programado através de 3 pinos de controle no modo serial.
Sua programação consiste no envio de um comando de 8 bits seguido de um ou mais bytes de dados, dependendo do modo usado para programá-lo que são dois:
1 - Os registradores podem ser lidos, todos de uma só vez, com o uso do código de endereço 0xBF.
2 - Os registradores podem ser gravados, todos de uma só vez, com o uso do código de endereço 0xBE.
Esse tipo de operação chama-se "burst mode".
A figura abaixo mostra o layout do comando de 8 bits que deve ser enviado para o DS1302 iniciar uma operação de I/O.
O envio de comandos e dados deve sempre iniciar pelo bit de mais baixa ordem.
No layout de comando acima, o bit 7 é sempre 1. Se esse bit contiver 0 a gravação ficará desabilitada.
O bit 6 chaveia entre o acesso da memória RAM e o acesso aos registradores do relógio. Se o bit 6 for 1, você estará acessando a memória RAM e, se o bit 6 for 0, você estará acessando o relógio.
Os bits de 5 a 1 (A4 - A0) correspondem ao código do endereço do registrador onde a operação de I/O será executada. Veja os códigos de READ e WRITE na tabela abaixo.
O bit 0 (zero) indica o tipo de operação a ser executada. Se o bit zero contiver o valor 0, será executada uma gravação e, se o bit zero contiver o valor 1, será executada uma leitura.
A tabela abaixo mostra os registradores do relógio do DS1302. Cada um tem um endereço hexadecimal diferente para as operações de leitura e gravação. Assim, se quisermos acertar as horas do relógio, devemos gravar o valor das horas usando o registrador de endereço 0x84. Do mesmo modo, se quisermos ler o valor das horas, devemos usar o registrador de endereço 0x85.
LAYOUT DOS REGISTRADORES DO RELÓGIO DO DS1302
Para iniciar uma operação com o DS1302 os sinais SCLK e CE devem estar em nível zero. A operação de I/O inicia quando o sinal CE e levado ao nível alto e termina quando o sinal CE for levado ao nível baixo novamente.
Acompanhe o processo observando a figura abaixo, retirada o data sheet.
Gráficos de temporização para leitura e gravação no DS1302
Os bits de comandos e dados enviados ao RTC são reconhecidos pelo chip na subida do sinal de clock e são enviados a partir do bit menos significativo.
A leitura se inicia na borda descendente do sinal de clock, logo após a subida deste, quando o último bit do comando de leitura for enviado ao RTC. Daí para frente todos os dados devem ser lidos na borda de descida do sinal de clock.
A gravação do relógio será feita no modo "Burst", isto é, todos os registradores do DS1302 serão gravados numa única operação, usando-se o comando 0xBE e mantendo-se o sinal CE alto enquanto os bytes são enviados ao RTC. A gravação, 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 não for especificado em "WP", o relógio não receberá os dados.
Os dados deverão 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 (01-07) dia da semana (Domingo=01 ate Sabado=07)
AA ............. ano (01-99)
WP ............. sempre zero para desabilitar a proteção contra gravação
|
Ao final o sinal CE será levado ao nivel baixo novamente.
A leitura do relógio também será feita no modo "Burst", isto é, todos os registradores serão lidos de uma só vez, usando-se o comando 0xBF e mantendo-se o sinal CE alto enquanto os bytes são lidos do RTC. Ao final o sinal CE será levado ao nivel baixo novamente. Os valores dos registradores serão colocados num buffer de leitura na ordem 'ssmmhhDDMMWWAA0D'. Notar que o final do buffer sera marcado com Carriage Return (0x0D).
H P S P I N Desde 04 de Março de 2010 Atualização: 08 de Dec de 2024 |