Comportamento inesperado do 12F629

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Comportamento inesperado do 12F629

Mensagempor lpagano » 15 Jan 2009 10:00

Pessoal,

Ontem durante uma programação usando o MikroC do PIC com interrupção via pin change para sair do sleep me deparei com uma coisa nada convencional: dependendo da maneira como você declara o TRIS ele tem um comportamento diferente durante a execução do programa, ou seja, literalmente ele dá um reset (e com watchdog desligado). Vejam abaixo as possibilidades de declaração do TRIS no MikroC e ASM:


1º exemplo:
Código: Selecionar todos

TRISIO = 0b001100;




agora traduzindo isso em assembly, de acordo com que o MikroC gera:

Código: Selecionar todos

    movlw  12 ;
    movwf  trisio ;




Usando o código em C descrito acima funcionou legal o meu programa. Agora vejam abaixo num segundo exemplo onde eu declaro os TRIS individualmente:


2º exemplo:
Código: Selecionar todos

TRISIO.F0 = 0;
TRISIO.F1 = 0;
TRISIO.F2 = 1;
TRISIO.F3 = 1;
TRISIO.F4 = 0;
TRISIO.F5 = 0;



agora traduzindo isso em assembly, de acordo com que o MikroC gera:

Código: Selecionar todos

bcf   trisio, 0 ;
bcf   trisio, 1 ;
bsf   trisio, 2 ;
bsf   trisio, 3 ;
bcf   trisio, 4 ;
bcf   trisio, 5 ;





Declarando os TRISIO de acordo com o 2º exemplo quando acontece a interrupção o PIC dá um reset.
Já fiz isso várias vezes no PIC e deu sempre a mesma coisa.


Alguém sabe explicar o motivo desse comportamento do PIC???


Valeu!
lpagano
Byte
 
Mensagens: 393
Registrado em: 06 Nov 2006 14:23

Mensagempor renatokodaira » 15 Jan 2009 13:19

Quando voce faz definiçao individual de bits em sequencia num registrador do PIC e nao deixa uma instruçao NOP entre duas instruçoes de bit ocorre um problema de read-modify-write devido aa estrutura de pipeline: como duas instruçoes podem ser executadas defasadamente, uma vai ler o registrador inteiro, modificar e gravar, mas a seguinte no ciclo de modificar da anterior vai ler o estado anterior aa modificaçao da instruçao anterior e vai gravar o bit modificado anteriormente com o estado nao desejado. Isso pode estar acontecendo com o bit 3, que ao inves de ficar setado (1) pode ficar com o valor resetado (0) que nao eh o desejado.

Pra evitar isso: use a instruçao para modificar de uma soh vez todos os bits do registrador ou insira nops entre as instruçoes de modificaçao de bit.
renatokodaira
Byte
 
Mensagens: 402
Registrado em: 11 Out 2006 15:15

Mensagempor RobL » 15 Jan 2009 14:48

Dê uma olhada no sleep que não me lembro bem, mas há duas forma de retomada, uma resetando e outra continuando o código.
Para continuar o código, após sleep, deve haver um nop antes da próxima instrução. Dê uma recordada no datasheet.

O que o renato colocou pode acontecer sim mas penso que não explica o reset. Use uma operação OR para setar os bits como:
Trisa = 1<<bit7|0<<bit6|1<<bit5 etc.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor RobL » 15 Jan 2009 18:28

Em vez de reset veja se não é um salto para 0004h, pois se GIE estiver habilitado ao sair do sleep, após executar a primeira instrução haverá um salto para 0x4. Pode parecer reset mas não é.
Para prosseguir o pgm GIE tem que estar desabilitado. Veja no manual pois não me lembro bem disso.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor lpagano » 15 Jan 2009 22:04

RobL tem razão nos seus comentários. Eu dei uma olhada no datasheet e realmente se o INTCON.GIE = 1 após o wake-up ele vai para o endereço 0004h.

Removi do programa essa declaração e funcionou. O problema agora é que durante o sleep o consumo está alto, da ordem de 110uA, mas todos os periféricos estão desligados. Parece que tem um tópico no fórum falando sobre isso. Vou verificar.




Quanto à dica do renatokodaira, infelizmente não deu certo a implementação que você sugeriu.


Valeu!
lpagano
Byte
 
Mensagens: 393
Registrado em: 06 Nov 2006 14:23

Mensagempor RobL » 16 Jan 2009 10:00

Quanto a setagem da direção da porta não é para escrever TRISA nem bit 7, 6, etc, não e sim TRISIO = (1<<7 | 0<<6...etc) conforme os nomes dos seus bits num arquivo include ou head, seu chip e compilador e isto se nesse ponto seu TRISIO for = 0.

Quanto ao consumo:
1- Pullup desligados.
2- Mude as direções das portas como entrada e se alguma saída estiver consumindo pela malha externa, mesmo como entrada, tente usar essa como saída e jogar 5V ou zero, ou seja, o que fizer reduzir o consumo nessa malha.
3- Se usar oscilador interno, passe-o para a mais baixa frequencia. Veja no manual pois no modo sleep talvez isso não seja necessário.
4- Se possível não use WDT se é que nos pics ele pára o oscilador dele, quando desabilitado, penso que sim.
5- Comparador desabilitado e com portas digitais.
6- Enfim pare tudo que puder.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor lpagano » 19 Jan 2009 09:56

RobL,

Nem tinha pensado em desabilitar os pull-ups. A gente vai chegando numa idade em que acaba esquecendo das coisas. :lol:

Por isso que há uns meses eu coloquei um 12F629 em sleep e a corrente dele foi para menos e 1uA (medi isso com um multímetro na escala de 200uA e deu zero).

Vou desabilitar esses pull-ups.


Valeu!
lpagano
Byte
 
Mensagens: 393
Registrado em: 06 Nov 2006 14:23


Voltar para PIC

Quem está online

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

cron

x