Página 1 de 1

ATmega32

MensagemEnviado: 02 Nov 2010 08:49
por Kim Robert
Caros Colegas estou com um problema com um ATMEGA32, eu fiz o programa, e esta funcionando perfeitamente, e um programa de contador com 6 digitos de Display BCD. mas o problema e que o programa funciona normalmente por aproximadamente 5 Minutos, a pos isto o programa para de processar, ficando apenas um dos digitos acesso, e só volta a funcionar novamente, apos precionar o resete, o que esta acontecendo, será que deixei de setar alguma coisa no Def inicial?

MensagemEnviado: 02 Nov 2010 11:29
por cfreund
vou aindatar...
se puder postar seu código, fica melhor para ajudar.

uma das causas mais comuns para essas panes, é n respeitar tamanho de variaveis.

MensagemEnviado: 02 Nov 2010 19:07
por RobL
Software
1- Falta de rigor na linguagem, se em C em algum trecho.
Por exemplo, falta de um break, e um default, bloco perdido, etc. Isto pode gerar problema em retorno e seu stack invade suas variáveis.
Há alguma interrupção que foi usado alguma atribuição isr_naked sem prólogo nem epílogo e esqueceu de retornar ao final ?
2- Ponteiros avançando por região que não é sua praia.
3- Contador de vetor indo além do tamanho definido e modificando algo que quando testado dá zebra.

Hardware
Menos provável se o tempo é em torno de 5 minutos. Pois se fosse térmico um reset não deveria resolver.
Ruído, não seria bem comportado, em torno de 5 minutos.

Difícil sugerir sem conhecer algo mais.

Tem como usar Debug Wire ou similar ?
Tire algumas funções que suspeite para teste.
Daria esse mesmo erro no simulador num PC ?

MensagemEnviado: 02 Nov 2010 20:08
por zazulak
Se puder postar o código, melhor. Se for extenso, poste em http://pastebin.com

Se for um programa que se baseia em interrupções - subentenda-se, onde o seu loop principal é tão somente um "while(1);" - as causas mais comuns, além das ja citadas pelo RobL, que tenho visto para esse tipo de travamento são:

- Uma interrupção de timer que se suicida. Basta um pipe ("|") faltando numa linha de atribuição para que, ao se setar um bit de um TIMSK da vida, acabe zerando os outros.

- Flag I sendo zerada para alguma operação que não pode ser interrompida, e não voltando a ser setada

- Em programas orientados a interrupção, falta de uma linha final ("while(1);" ou similar). O GCC adiciona automaticamente um loop final, mas não sei se os outros compiladores de C fazem o mesmo.

- Por fim, um loop while testando uma condição eternamente verdadeira ou falsa, tipo: while(ADCSRA & _BV(ADSC)); sem ter setado o ADEN

MensagemEnviado: 05 Nov 2010 08:10
por Fandango
Os colegas disseram tudo. Se não for algo do estilo, o problema certamente é paranormal (um encosto ou algo assim... hehehe).
Procure também por ";" ou "}" (faltante ou excedente), apesar de que um bom compilador deveria avisar, mas sem o código fica difícil saber.

MensagemEnviado: 05 Nov 2010 09:30
por enigmabox
Durante o funcionamento de 5 min, tudo funcionou perfeitamente, ou foi habilitado alguma subrotina depois dos 5 min que travou tudo?
Tive um caso similar quando eu tinha uma placa de prototipo cheia de fios, depois de alguns tempo travava o Atmega16 apos funcionamento normal, só voltava a funcionar via Reset. O codigo já tinha revisado e nao encontrava problemas, e tinha incluido varias rotinas de debug para ver onde parava a MCU.
Foi resolvido o problema quando fiz uma fonte melhor com regulador linear, por segurança, antes usava uma fonte chaveada de 5V, mesmo vendo no osciloscopio, nao via quanquer tipo de interferencia na linha de 5V, e eliminado o monte de fios da placa prototipo.
Analisando as rotinas de Debug, via que a MCU entrava em pane quando acionava com frequencia o porto I2C ou serial, isso irradiava interferencias no MCU.
Parecia problema paranormal, como o Fandango disse... :)
E outra coisa, a quantidade de capacitores ceramicos e eletroliticos nas duas placas era a mesma, não era isso a causa do problema.

Analise o codigo gerado e a disposição dos componentes na PCI.



:D

MensagemEnviado: 07 Nov 2010 05:35
por Kim Robert
Pois é estou muito satisfeito com as observações de VCS, respondendo a vossas perguntas, eu ja desliguei varias rotinas mas o problema continua, cheguei até a mudar o tipo do estouro do timer ou coisas assim, e nao adiantou nada, mas o meu timer está com recarga altomatica, sem a necessidade de recarregar um valor, ele estoura em 255, gera interrupção e reinicia a contagem, en todo caso ai está o codigo para que voces possam verificar. O CODIGO É EM ASM.

acessem aqui: http://pastebin.com/Ax2GAmn9

MensagemEnviado: 07 Nov 2010 10:58
por Djalma Toledo Rodrigues
Se um programa é fácil de ler, ele é provavelmente um bom programa;
se ele é difícil de ler, provavelmente ele não é bom.
(Kermighan & Plauger)


Quando um programador é bom, ele é muito muito bom,
mas, quando ele é ruim, ele é horrível
(Edward Yourdon)


Questão de Lógica, de ter um raciocinio lógico.

DJ

MensagemEnviado: 07 Nov 2010 11:47
por RobL
Assembly, muda de figura.

Na sua rotina de serviço int Time0 não salva o status, no entanto ele é modificado. Pode estar aqui o erro. Coloca isso aí e teste.
Código: Selecionar todos
push R0 ;  //salva r0
push R1 ;
in R0, SREG  ;  //coloca SREG em R0
push R0 ;  //salva R0 na pilha

Rotina Time0

pop R0 ;  // pega de volta o status register
out  SREG, R0 ; volta com status antes da int
pop R1 ; //recoloca os registros r0 e r1
pop R0 ; // salvar R1 eh classico devido a Mult usa-lo
Reti ;



Procure ver se o registro de Status foi salvo em todas suas interrupções e outras chamadas às rotinas.
Nas suas rotinas de interrupção, há outros registros que devem ser salvos.
Há casos, na qual essa rotina vai acontecer, de forma não determinística, neste caso temos que salvar o status e todos os 32 registros, caso os 32 estejam sendo utilizados.
Por exemplo, ví no seu programa, uma rotina de divisão com vários push, mas não ví no topo dela o registro de status salvo. Pode ser que neste caso não fosse reutilizá-lo. Não estou com tempo para checar seu programa.

O grande problema com asm é esquecer de salvar na pilha um registro que vai ser modificado.
Sugiro verificar primeiro as interrupções, salvar registros e verificar se em todas você está retornando com RETI e nao RET.