Como vimos na parte anterior, a ligação do DS1302 ao PIC é feita por três sinais: CE, SCLK e I/O. O sinal CE (chip enable) deve ser colocado em nível "1" para inicial uma operação e só ser retornado a "0" ao seu final. O sinal SCLK (serial clock) determina quando cada bit deve ser lido ou escrito na linha I/O. Os sinais CE e SCLK são sempre comandados pelo microcontrolador, o sinal I/O é bi-direcional.
As transferência de dados são compostas por bytes (8 bits). O primeiro byte de toda transferência é enviado do microcontrolador para o DS1302 e determina a operação que será realizada e endereça um registrador do relógio ou uma posição da memória Ram do DS1302:

Os bits são transferidos serialmente do menos significativo para o mais. Os bits devem ser enviados pelo transmissor na borda de descida de SCLK e lidos pelo receptor na borda de subida. A figura abaixo mostra os ciclos básicos de leitura e escrita de um byte:

O byte de comando possui 5 bits de endereçamento. No acesso ao relógio, existem 9 registradores; na Ram são 31 posições. Nos dois casos o endereço 11111 indica o modo burst. Neste modo, múltiplos bytes são transferidos com o endereço começando em zero e incrementando automaticamente a cada byte lido ou escrito. A figura abaixo mostra um resumo dos registradores e endereços:

Um cuidado necessário ao escrever nos registradores do relógio é que é preciso desprotegê-los primeiro (escrevendo 0 em WP).
Para concluir esta descrição do DS1302, vejamos o funcionamento do circuito de carga da bateria. O DS1302 alimenta a bateria a partir da sua própria alimentação (no caso 5V), podendo colocar em série 1 ou 2 diodos (para reduzir a tensão) e um dentre 3 resistores (para limitar a corrente):

A programação que usei coloque em série os dois diodos e a resistência de 2K. Desta forma, a tensão máxima será 5 - 2*0,7 = 3,6V e a máxima corrente (supondo a bateria totalmente zerada) será 3.6V / 2K = 1,8 mA.
Vamos, finalmente, ao código. As rotinas abaixo são responsáveis pelo envio e recepção de bytes:
- #define DS1302_CE PIN_B0
- #define DS1302_IO PIN_B1
- #define DS1302_SCLK PIN_B2
- // Envia um byte ao DS1302
- void DS1302_TxByte (byte b)
- {
- int i;
- set_tris_b (0xF8); // I/O é output
- for (i = 0; i < 8; i++)
- {
- if (b & 1)
- output_high (DS1302_IO);
- else
- output_low (DS1302_IO);
- delay_us (1);
- output_high (DS1302_SCLK);
- delay_us (1);
- output_low (DS1302_SCLK);
- b = b >> 1;
- }
- set_tris_b (0xFA); // I/O volta a ser input
- }
- // Recebe um byte do DS1302
- byte DS1302_RxByte ()
- {
- int i;
- byte dado;
- for (i = 0; i < 8; i++)
- {
- delay_us (1);
- dado = dado >> 1;
- if (input (DS1302_IO))
- dado |= 0x80;
- output_high (DS1302_SCLK);
- delay_us (1);
- output_low (DS1302_SCLK);
- }
- return dado;
- }
- // Alguns registradores do DS1302
- #define DS1302_WP 0x0E
- #define DS1302_TC 0x10
- #define DS1302_CBURST 0x3E
- // Lê relogio em modo burst
- void DS1302_ReadClock (byte *regs)
- {
- byte i;
- output_high (DS1302_CE);
- delay_us (4);
- DS1302_TxByte (DS1302_CBURST | 0x81);
- for (i = 0; i < 8; i++)
- {
- *regs++ = DS1302_RxByte ();
- delay_us (4);
- }
- output_low (DS1302_CE);
- }
- // Escreve relogio em modo burst
- void DS1302_WriteClock (byte *regs)
- {
- byte i;
- DS1302_Write (DS1302_WP, 0x00);
- DS1302_Write (DS1302_TC, 0xA9); // tricle charger, 2 diodes, 2Kohms
- output_high (DS1302_CE);
- delay_us (4);
- DS1302_TxByte (DS1302_CBURST | 0x80);
- for (i = 0; i < 8; i++)
- {
- DS1302_TxByte (*regs++);
- delay_us (4);
- }
- output_low (DS1302_CE);
- }
- // Lê um byte de um endereço do DS1302
- byte DS1302_Read (byte ender)
- {
- byte result;
- output_high (DS1302_CE);
- delay_us (2);
- DS1302_TxByte (ender | 0x81);
- result = DS1302_RxByte ();
- delay_us (2);
- output_low (DS1302_CE);
- return result;
- }
- // Escreve um byte em um endereço do DS1302
- void DS1302_Write (byte ender, byte dado)
- {
- output_high (DS1302_CE);
- delay_us (2);
- DS1302_TxByte (ender | 0x80);
- DS1302_TxByte (dado);
- delay_us (2);
- output_low (DS1302_CE);
- }
Nenhum comentário:
Postar um comentário