Relógio Digital.

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Mensagempor Pask » 14 Jan 2007 08:24

Se vc puder me ajudar na inicialização quanto ao uso dos DS1307 e/ou DS1305 eu agradeceria muito. O caso é que eu nunca trabalhei em projetos que usem a USART do PIC. Este é um mundo novo para mim. Tenho bons livros sobre o assunto, mas gostaria de saber como fazer uma comunicação entre o PIC e o DS. Aguardo sua ajuda se possível. Obrigado.

Pask.
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

Mensagempor wjr1955 » 14 Jan 2007 09:43

wjr1955
Bit
 
Mensagens: 18
Registrado em: 11 Out 2006 14:04
Localização: Sao Paulo SP

Mensagempor Pask » 14 Jan 2007 18:35

Valeu sobre o DS1307. Vou dar uma estudada. Obrigado.

Pask.
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

Mensagempor Cláudio » 15 Jan 2007 07:57

E se quiser precisão, se o o seu projeto absorve:

http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2940

+ RTC qualquer.

Precisão de 1 minuto por ano.
[]´s
Cláudio
_______________________________________
"Quem quer, de verdade, faz. Quem não quer, inventa desculpas.
Avatar do usuário
Cláudio
Byte
 
Mensagens: 110
Registrado em: 17 Out 2006 09:19

Mensagempor andre_luis » 15 Jan 2007 08:05

para o ds1307:

Código: Selecionar todos
////////////////////////////////////////////////////////////////////////
void ds1307_send_time( void )
{
   delay_us   ( 10 )                      ;     /* Solucao Empirica       */
   i2c_start()                            ;     /* START CONDITION        */
   i2c_write( SELECT_DS1307 | ESCRITA )   ;     /* SLAVE ADDRESS -> WRITE */
   i2c_write( MINUTES )                   ;     /* WORD ADDRESS           */
   i2c_write( Minuto_ds1307_digitos )     ;     /* WRITE DATA             */
   i2c_write( Hora_ds1307_digitos   )     ;     /* WRITE DATA             */
   i2c_write( Semana_ds1307_digitos )     ;     /* WRITE DATA             */
   i2c_write( Dia_ds1307_digitos )        ;     /* WRITE DATA             */
   i2c_write( Mes_ds1307_digitos )        ;     /* WRITE DATA             */
   i2c_write( Ano_ds1307_digitos )        ;     /* WRITE DATA             */
   i2c_stop()                             ;     /* STOP CONDITION         */
   delay_ms  ( 50 )                       ;     /* Solucao Empirica       */
}
////////////////////////////////////////////////////////////////////////


Se voce estiver programando com o CCS e carregando via ICSP, ainda pode atualizar a hora atual toda vez que fizer download do firmware, pela funcao a seguir, que deve rodar no main() antes do while(1) :

Código: Selecionar todos
////////////////////////////////////////////////////////////////////////
void clock_initiate( void )
{
unsigned int8 Time[] =  __time__         ;
unsigned int8 HoraDecimal                ;
unsigned int8 MinutoDecimal              ;
unsigned int8 HoraDezena                 ;
unsigned int8 HoraUnidade                ;
unsigned int8 MinutoDezena               ;
unsigned int8 MinutoUnidade              ;
unsigned int8 Data[] =  __date__         ;
unsigned int8 DiaDecimal                 ;
unsigned int8 MesDecimal                 ;
unsigned int8 AnoDecimal                 ;
unsigned int8 DiaDezena                  ;
unsigned int8 DiaUnidade                 ;
unsigned int8 MesDezena                  ;
unsigned int8 MesUnidade                 ;
unsigned int8 AnoDezena                  ;
unsigned int8 AnoUnidade                 ;
HoraDecimal   = ( ( ( Time[0]-'0' ) * 10 ) + ( Time[1]-'0' ) ) ;
MinutoDecimal = ( ( ( Time[3]-'0' ) * 10 ) + ( Time[4]-'0' ) ) ;
HoraDezena    = ( HoraDecimal / 10 ) ;
HoraUnidade   = ( HoraDecimal % 10 )  ;
MinutoDezena  = ( MinutoDecimal / 10 ) ;
MinutoUnidade = ( MinutoDecimal % 10 )  ;

DiaDecimal    = ( ( ( Data[0]-'0' ) * 10 ) + ( Data[1]-'0' ) ) ;
AnoDecimal    = ( ( ( Data[7]-'0' ) * 10 ) + ( Data[8]-'0' ) ) ;
DiaDezena     = ( DiaDecimal / 10 ) ;
DiaUnidade    = ( DiaDecimal % 10 )  ;
AnoDezena     = ( AnoDecimal / 10 ) ;
AnoUnidade    = ( AnoDecimal % 10 )  ;

switch ( Data[3] )
   {
   case 'J' :
   case 'j' :
      if ( ( Data[4] == 'A' ) || ( Data[4] == 'a' ) )
         {
         MesDezena  = 0 ;
         MesUnidade = 1 ;
         }
         else
            {
            if ( ( Data[5] == 'N' ) || ( Data[5] == 'n' ) )
               {
               MesDezena  = 0 ;
               MesUnidade = 6 ;
               }
               else
               {
               MesDezena  = 0 ;
               MesUnidade = 7 ;
               }
            }
   break ;
   ///////////////////
   case 'F' :
   case 'f' :
      MesDezena  = 0 ;
      MesUnidade = 2 ;
   break ;
   ///////////////////
   case 'M' :
   case 'm' :
      switch ( Data[5] )
         {
         case 'R' :
         case 'r' :
            MesDezena  = 0 ;
            MesUnidade = 3 ;
         break ;
         case 'I' :
         case 'i' :
            MesDezena  = 0 ;
            MesUnidade = 5 ;
         break ;
         }
   break ;
   ///////////////////
   case 'A' :
   case 'a' :
      switch ( Data[4] )
         {
         case 'B' :
         case 'b' :
            MesDezena  = 0 ;
            MesUnidade = 4 ;
         break ;
         case 'G' :
         case 'g' :
            MesDezena  = 0 ;
            MesUnidade = 8 ;
         break ;
         }
   break ;
   ///////////////////
   case 'S' :
   case 's' :
      MesDezena  = 0 ;
      MesUnidade = 9 ;
   break ;
   ///////////////////
   case 'O' :
   case 'o' :
      MesDezena  = 1 ;
      MesUnidade = 0 ;
   break ;
   ///////////////////
   case 'N' :
   case 'n' :
      MesDezena  = 1 ;
      MesUnidade = 1 ;
   break ;
   ///////////////////
   case 'D' :
   case 'd' :
      MesDezena  = 1 ;
      MesUnidade = 2 ;
   break ;
   }

  ds1307_send_byte( CONTROL, CONTROL_WORD );
  ds1307_send_byte( SECONDS ,        ( CH | 0 )                              ) ;
  ds1307_send_byte( MINUTES ,        ( ( MinutoDezena << 4 ) | MinutoUnidade ) ) ;
  ds1307_send_byte( HOURS   ,        ( ( HoraDezena   << 4 ) | HoraUnidade   ) ) ;
  ds1307_send_byte( DAY     ,                         INIT_DAY               ) ;
  ds1307_send_byte( DATE    ,        ( ( DiaDezena   << 4 )  |  DiaUnidade   ) ) ;
  ds1307_send_byte( MONTH   ,        ( ( MesDezena   << 4 )  |  MesUnidade   ) ) ;
  ds1307_send_byte( YEAR    ,        ( ( AnoDezena   << 4 )  |  AnoUnidade   ) ) ;
}
////////////////////////////////////////////////////////////////////////
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Mensagempor Pask » 15 Jan 2007 20:21

Caros amigos, muito obrigado realmente pelo material enviado. Mas, eu gostaria talvez de desenvolver um projeto totalmente meu envolvendo o DS1307 com o PIC via USART. Para isto, eu precisaria saber umas coisinhas iniciais. Por exemplo:

1) Como eu acertaria as horas e os minutos do relógio? Qual comando eu teria que enviar ao DS para acertar o relógio para 4:27 por exemplo?

2) Suponhamos que eu queira ler a hora e os minutos. Qual comando eu teria que enviar ao DS para isto? Em qual formato ele me envia os dados?

3) No meu caso, eu gostaria de apenas usar a função relógio do mesmo. Como configurá-lo desta forma?

Alguém poderia me enviar "fragmentos" de código pelo menos, para que eu pudesse começar a entender o bicho? Eu já tenho o datasheet do DS1307 comigo.
Desculpem a ignorância no assunto... :oops:

Pask.
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

Mensagempor andre_luis » 16 Jan 2007 08:46

Eu acho que grande parte das suas perguntas já formam respondidas noipo 'post' anterior : ( fragmento de código, formato de dados, etc... ); masta voce dar uma olhada no código acima.

Agora, caso sua dúvida seja mais profunda, tipo, programacao em 'C', então creio que haja um outro tópico indicado para isso.

+++
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Mensagempor microeletronica » 16 Jan 2007 21:57

Acima esta um codigo muito claro.
Caso ainda haja duvida, por favor seja especifico.

[]s
microeletronica
Byte
 
Mensagens: 158
Registrado em: 05 Dez 2006 18:22

Mensagempor Pask » 17 Jan 2007 07:49

A minha dúvida é muito simples: estou acostumado com o assembly e nele, o acesso à comunicação serial via USART é bem mais chato devido à falta de automatismo daquela linguagem. Eu sei que na linguagem C tudo é mais direto, por isso estou achando estranho o código!
Eu apenas gostaria que alguém me explicasse o código em C para que eu pudesse me situar em relação a ele. Eu já usei a linguagem C mas não o suficiente para conhecer todos os seus detalhes. Obrigado.

Pask.
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

Mensagempor zielpunkt » 17 Jan 2007 08:32

Olá, Pask.

Seguinte, por eu trabalhar quase que exclusivamente com assembly, entendo a sua grande dificuldade em interpretar um código em C. Também sofri e ainda sofro para assimilar bem essa linguagem. Acontece que o que vc está pedindo (explicar o código em C acima, o qual poderia ser feito de mil maneiras, por ex) fica quase impossível nesse espaço, por várias razões. A principal delas é porque a sua compreensão depende de que vc tenha certo conhecimento da linguagem C, o que vai ser obtido a partir de um estudo mais aprofundado para se libertar dos conceitos do assembly. Outra razão é porque vc demonstra não compreender, seja em assembly ou C, como manipular o RTC o qual quer utilizar. Então, vc tem dois desafios pela frente e, lamento dizer, só depende de vc mesmo. A partir daqui vc só vai obter informações que pouco vão te auxiliar.

É isso.
"Talento é mais barato que sal. O que separa a pessoa talentosa da bem-sucedida é muito trabalho duro." [ Stephen King ]
zielpunkt
Byte
 
Mensagens: 376
Registrado em: 12 Out 2006 11:36
Localização: Sao Paulo - SP

Mensagempor ÁgioFelipe » 28 Jan 2007 12:34

Pask, teu relógio funcionou?
ÁgioFelipe
Word
 
Mensagens: 626
Registrado em: 27 Out 2006 20:04

Mensagempor Pask » 28 Jan 2007 13:42

Eu ainda não fiz o relógico com o chip da DALLAS.[/img]
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

ds1307

Mensagempor fernandor » 13 Mar 2009 09:26

quero ler o valor do ds1307. Achei este trecho de programa na internet mas nao entendi porque tenho que usar
i2c_write(0xd0); //Chip address from the data sheet - write selected

ao inves de usar diretamente

i2c_write(0xd0); //Chip address from the data sheet - write selected

-----------------------------------------------------------------------------------
i2c_start();
i2c_write(0xd0); //Chip address from the data sheet - write selected
i2c_write(1); //Select register 1
i2c_start(); //Send a restart PORQUE TEM ESTE START DENOVO???
i2c_write(0xd1); Chip address - read selected
mins=i2c_read(); //read the minutes
i2c-stop(); //finish the transaction
------------------------------------------------------------------------------------

se eu fizer o programa assim:

i2c_start();
i2c_write(0xd1); Chip address - read selected
i2c_write(1); //Select register 1
mins=i2c_read(); //read the minutes
i2c-stop(); //finish the transaction

vai funcionar?

valeu

fernando
fernandor
Bit
 
Mensagens: 29
Registrado em: 12 Mar 2009 15:01

Mensagempor msamsoniuk » 13 Mar 2009 11:07

soh ressussitando o negocio...

obviamente sempre existe um escorregamento lento entre os osciladores, seja o cristal do mcu, seja um relogio de tempo real, unica forma de eliminar o escorregamento eh sincronizar com uma referencia externa. por outro lado, um bom oscilador nao escorrega tanto assim, entao fiquei com uma duvida em relacao ao que o proex falou.

nao tem como programar o timer do PIC para operar automaticamente, com auto-reload e interrupcao apenas para indicar que o auto-reload ocorreu? nos hc908 eu programo os timers desta forma e o unico efeito colateral eh um pouco de jitter entre o auto-reload automatico e a interrupcao, mas sem acumular delay.

se for possivel programar o timer do PIC para operar desta forma e se o oscilador for bom, o escorregamento tem que ser bastante pequeno.

proex escreveu:Existem duas coisas criticas na interrupçao do Timer. A primeira é em relaçao ao tempo de resposta a interrupçao gerada. Vc sempre terá alguns ciclos de maquina que poderá variar em funçao do que o PIC estiver executando naquele dado momento.

A segunda é sobre a atualizaçao do registrador do timer afim de que ele possa reiniciar o ciclo. Depois que vc escreve o valor no registrador do timer, ele demora mais alguns ciclos para recomeçar a contagem.

Essas "demoras" vão de somando e ao longo de um periodo vc começará a perceber o atraso na contagem.

Particularmente eu já testei algumas rotinas para compensar isso mais nao obtive bons resultados.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor juarezbazzo » 15 Mar 2009 10:06

Olá caro amigo, já queimei quase todos meus neurônio (que já são poucos) num relógio, pois não conseguia a tal precisão, enchia o saco dos colegas sobre os atrasos, até que entendi que era os ciclos gasto com outras funções que geravam os a atraso, como eu já montava relógios com os CIs convencional, coloquei o “baratíssimo” 4060 que custa +- R$ 0,50, mais um cristal de um relógio paraguaio comprado na “1,99” por uns dois reais, então usava interrupção externa do Pic, no pino 13 do 4060 saí 64 Hz, é o suficiente para fazer todas as funções com folga, no mais, não precisa de muitos cálculos no código. Se assim desejar, te mando o código da interrupção e circuito do mesmo, pois eu uso o mesmo nos 12F675, 16F676, 16F628 e 16F877A. 100+; um abraço Juarez Bazzo NH - RS
juarezbazzo
Bit
 
Mensagens: 25
Registrado em: 25 Nov 2006 21:58

AnteriorPróximo

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

cron

x