Página 1 de 2

LPC2368 + RTOS + Alteração RTC (problema bizarro)

MensagemEnviado: 15 Jan 2010 08:08
por lrfad2
oi gente...
Depois de quase um mês quebrando a cabeça em cima de um problema, consegui identificar que a data e hora é alterada erroneamente, quando lemos constantemente as variáveis do RTC.
É bizarro por vários motivos: 1º - estou lendo a variável; 2º - pq eu tenho várias outras aplicações que utilizam o RTC, acesso da mesma maneira e esse problema não se apresenta; 3º - desconfiado o problema seria no hardware do processador, testei com várias placas e o problema continua
Pensei ainda que fosse alguma ponteiro que estava indo para o lugar errado, ou sei lá um buffer que estava estourando e não percebia... mas depois eu desencanei dessa ideia, pq eu vi no mapeamento de memória, que o RTC está muito longe da RAM e da flash.
Coloquei no título RTOS, pois imagino que possa ser um problema de chaveamento de task... que o RTOS não está conseguindo salvar o stack, sei lá eu...

Alguem já viu alguma bizarrice do tipo?

Re: LPC2368 + RTOS + Alteração RTC (problema bizarro)

MensagemEnviado: 15 Jan 2010 08:18
por Rodrigo_P_A
Eu uso LPC2368 com RTC + RTOS e não peguei este tipo de problema.

MensagemEnviado: 15 Jan 2010 08:32
por lrfad2
pois é.... eu tb não... rs..

para vc ter uma ideia eu desconfiei primeiro disso:
HoraAtual = (RTC_HOUR * 60 ) + RTC_MIN;

eu mudei para

unsigned short horatemp, mintemp;
horatemp = RTC_HOUR;
mintemp = RTC_MIN;
HoraAtual = ( horatemp * 60 ) + mintemp;


o problema continuou e ai eu mudei para isso
horatemp = 1;
mintemp = 2;
HoraAtual = ( horatemp * 60 ) + mintemp;


e ai o problema acabou claro!

PS: esqueci de comentar. utilizo o Keil

MensagemEnviado: 15 Jan 2010 09:23
por Djalma Toledo Rodrigues
" Se eu tivesse 10 000 $ vocês me soltavam ?"
O chefão da Máfia : Soltava
Ele: " É numa hora dessas que a gente vê a falta que faz 10 000 $." rs

Isso da tirinha, fazendo analogia:

É numa hora dessas que a gente vê a falta que faz o ASM.

DJ

MensagemEnviado: 15 Jan 2010 09:50
por proex
O unico problema que eu tenho com o RTC do ARM é o atraso do relogio.

.

MensagemEnviado: 15 Jan 2010 10:27
por Rodrigo_P_A
Muito estranho esse problema.

Você mediu a frequência do cristal de 32768?

Na hora da inicialização, do chip, será que você num está desligando o RTC e depois religando? isso pode fazer ocorrer algum tipo de atraso no relógio interno né?

como eu disse, eu fiz uma aplicação para um cliente, ele já vendeu mais de 1000 unidades, certa vez ele me ligou reclamando do relógio, eu pedi para ele verificar o cristal e os capacitores do cristal, e em resumo o problema era esse, ele resolveu e nunca mais me ligou.

verifique se num é isso, acho difícil o problema ser porque você usa C ao invés de Assembler, eu até agora não encontrei erros de geração de código e uso o ARM programando somente em C.

MensagemEnviado: 15 Jan 2010 11:06
por proex
Na inicialização eu testo um bit pra saber se o RTC já foi inicializado anteriormente, se sim, eu pulo a função de inicializaçao.

A frequencia do cristal esta correta, somente a senoide dele fica um pouco deformada no semiciclo negativo.


.

MensagemEnviado: 15 Jan 2010 12:42
por veioloko
Ja viu se não são os capacitores?

Eu usei o rtc do 2148 e não tive problema....

MensagemEnviado: 15 Jan 2010 15:09
por MarcusPonce
Irfad2, no seu post não ficou claro se o RTC é alterado ou se apenas você lê e pega uma leitura errada às vezes.

Se for leitura errada às vezes, é porque o horário no RTC está mudando enquanto você está lendo. Precisa ler o RTC mais de uma vez seguida e comparar até conseguir a mesma leitura.

Se for o caso do RTC ser modificado, ele está só atrasando ou muda para qualquer coisa aleatoriamente ?

Você ajusta o Clock Control Register (CCR), bit 4 CLKSRC, sempre que inicia ?

No LPC2138 o RTC funcionou direito, menos de 1 segundo de desvio ao mês, mas não usava RTOS.

MensagemEnviado: 15 Jan 2010 17:10
por lrfad2
proex,
eu já tive problema com o atraso do RTC (depois de 1 dia ou 1 mes - não me lembro ao certo - ele atrasava um segundo). era o valor do capacitor que estava errado. Eu não me lembro daonde que arrumei uma conta onde o valor do capacitor dava 22,47pf, ou algo do tipo. Coloquei o de 21pf e nunca mais tive problema

Rodrigo, Marcus, Veioloko
Ele fica umas 7, 8 horas funcionando sincronizado certinho, mesmo vc forçando uns wdt ou resetando o uC. Do nada ele altera umas 8 horas, bem nada a ver.... acabei de fazer um teste travando o chaveamento de task, quando ele vai ler esses registradores. Não adiantou.... ficou sincronizado umas 7 horas e voltou a se perder

Marcus, eu ajsuto o CCR quando inicializo. por favor, da uma olhada e vê se é isso que vc estava pensando

RTC_AMR = 0xFF;
RTC_CIIR = 0x00;
RTC_CCR = 0x00;
RTC_PREINT = ( RTC_PREINT & ~MA_PREINT_RTC_MASK ) | MA_PREINT_RTC;
RTC_PREFRAC = ( RTC_PREFRAC & ~MA_PREFRAC_RTC_MASK ) | MA_PREFRAC_RTC;
RTC_CCR = 0x11;


galera,
por enquanto, valeu pela força

MensagemEnviado: 15 Jan 2010 20:30
por MarcusPonce
Irfad2, pelo que li no manual (mas não testei) dá para simplificar a inicialização para:
RTC_AMR = 0xFF;
RTC_CIIR = 0x00;
RTC_CCR = 0x11;
Acontece que usando um xtal 32768Hz e fazendo o bit 4 de RTC_CCR = 1, não precisa usar o prescaler, logo não precisa ajustar.

Se isso não resolver, sugiro deixar de ler os registradores SEC, MIN, HOUR, etc. e alterar o firmware para ler CTIME0, CTIME1, CTIME2.

MensagemEnviado: 18 Jan 2010 07:53
por lrfad2
Marcus,
Testarei suas opções, e assim que tiver novidades "posto" as novidades
Muito obrigado
Leandro

MensagemEnviado: 18 Jan 2010 20:56
por barboza
Também tenho um projeto com o código abaixo usando RTOS e não tive problemas ainda.


Código: Selecionar todos
/************************************************************************
   FUNCAO:      p_init_rtc
   PARAMETROS: NENHUM
   RETORNO:   NENHUM
   DESCRICAO:   FUNÇÃO PARA INICIALIZAR O HW DO RTC
*************************************************************************/
void   p_init_rtc   (void)
{
   // Habilita RTC com clock externo
   CCR = DEF_BIT_CLKEN | DEF_BIT_CLKSRC;

   // Habilita a interrupção a cada minuto
   CIIR = DEF_BIT_IMMIN;

   // Desabilita o alarme
   AMR = 0;

   // Define a função da interrupção
   VICVectAddr13 = (U32) p_rtc_isr;
   VICVectCntl13 = DEF_VIC_ENABLE_RTC;
   VICIntEnable = DEF_VIC_BIT_RTC;

   // Verifique se foi gravado a hora de desligamento
   p_eep_cmd(EEP_READ, EEP_END_TIME_DOWN, (U8 *) &st_rtc_eep_cache, sizeof(st_rtc_eep_cache));
   p_eep_flush();

   if (!(
      (p_rtc_check_hora (&st_rtc_eep_cache)) &&
      (p_rtc_check_data (&st_rtc_eep_cache))
      ))
   {
      // Hora inicial
      st_rtc_eep_cache.hora = 0;
      st_rtc_eep_cache.min = 0;
      st_rtc_eep_cache.seg = 0;
      st_rtc_eep_cache.dia = 24;
      st_rtc_eep_cache.mes = 9;
      st_rtc_eep_cache.ano = 2008;
   }
   p_rtc_write_time (&st_rtc_eep_cache);
   p_rtc_load_ttl();
}

/************************************************************************
   FUNCAO:      p_rtc_read_time
   PARAMETROS: st_rtc_temp
   RETORNO:   NENHUM
   DESCRICAO:   SALVA O VALOR DO RTC INTERNO NA ESTRUTURA PASSADA
*************************************************************************/
void   p_rtc_read_time   (st_rtc * st_rtc_temp)
{
   st_rtc_temp->hora = (U8) HOUR;
   st_rtc_temp->min = (U8) MIN;
   st_rtc_temp->seg = (U8) SEC;
   st_rtc_temp->dia = (U8) DOM;
   st_rtc_temp->mes = (U8) MONTH;
   st_rtc_temp->ano = (U16) YEAR;
}

/************************************************************************
   FUNCAO:      p_rtc_write_time
   PARAMETROS: st_rtc_temp
   RETORNO:   NENHUM
   DESCRICAO:   SALVA O VALOR PASSADO NO RTC INTERNO
*************************************************************************/
void   p_rtc_write_time   (st_rtc * st_rtc_temp)
{
   HOUR = st_rtc_temp->hora;
   MIN = st_rtc_temp->min;
   SEC = st_rtc_temp->seg;
   DOM = st_rtc_temp->dia;
   MONTH = st_rtc_temp->mes;
   YEAR = st_rtc_temp->ano;
}

MensagemEnviado: 19 Jan 2010 08:50
por lrfad2
Barboza...
Hj de manhã escrevi um código muito similar ao seu (mas dando interrupção a cada segundo). Tenho esperanças que seja uma solução... de qq maneira, até agora não sei o que está causando o problema e eu não curto muito ficar sem entender as coisas....

eu vi um negócio legal no seu código -> gravar a hora que foi desligado. Vc poderia me explicar um pouco melhor isso? Como vc faz para gravar sendo que vc já retirou a alimentação da placa? Vc tem uma bateria que mantem só o processador funcionando? ou o processador + RTC?

MensagemEnviado: 19 Jan 2010 08:58
por barboza
lrfad2 escreveu:Barboza...
Hj de manhã escrevi um código muito similar ao seu (mas dando interrupção a cada segundo). Tenho esperanças que seja uma solução... de qq maneira, até agora não sei o que está causando o problema e eu não curto muito ficar sem entender as coisas....

eu vi um negócio legal no seu código -> gravar a hora que foi desligado. Vc poderia me explicar um pouco melhor isso? Como vc faz para gravar sendo que vc já retirou a alimentação da placa? Vc tem uma bateria que mantem só o processador funcionando? ou o processador + RTC?



Coloca um sensor de queda (zener + transistor) na entrada da fonte, e um capacitor antes ou depois do regulador grande o suficiente para manter a placa o ligada para gravar os dados que manter.

O sensor de queda deverá estar antes do capacitor, senão não funciona.

Tipo:

Fonte -> Sensor de queda -> Diodo -> Capacitor -> Regulador -> MCU

Assim, cai a fonte, gera o alarme pro MCU e o capacitor no caminho segura a onda.....