Dúvida Subrotina

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Mensagempor chipselect » 03 Dez 2009 11:38

não estaria estourando o resquício de stack que o pic tem?
chipselect
Word
 
Mensagens: 744
Registrado em: 16 Out 2006 18:50

Mensagempor gilliard » 03 Dez 2009 11:41

Não, senão ele exibiria um erro. E mesmo, porque eu fiz outros teste, e mesmo assim, não ta voltando para o void main !!!!

Não sei oque pode ser !!!!
Avatar do usuário
gilliard
Byte
 
Mensagens: 121
Registrado em: 26 Ago 2008 13:32

Mensagempor barboza » 03 Dez 2009 11:41

Considerando que o main é o inicio do seu programa (vamos desconsiderar inicialização de registradores e stack), o que você quer é um reset por software.

Pesquise no forum e vai achar alguns topicos sobre isso.

O mais comum e recomendado em alto nível é usar o WDT, claro se você o tiver. Neste caso, habilite-o, e faça um while(1); dentro da sua LCD().

Nada convencional o que esta querendo, mas não vou entrar no mérito da sua necessidade.
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor fabim » 03 Dez 2009 11:44

giliard....
Poracaso, tu colocou um statemant de ciclo infinito ?

Se não sabe eu explico o que é.

void main(void){

Faz_isto;

Faz_Aquilo;

Aquilo-Outro;

lcd();


}

O programa vai executar tudo o que esta ai dentro apenas uma vez.

Ta vendo a chave no final ?
O montador substitui por

GOTO $.

ou seja, ele chega aí e para, não faz mais nada, o programa fica travado.!!!
Exatamente por isto tu esta achando que ele não esta voltando!!

Agora faça assim.;

for(;;){ // inicio de execução infinita
void main(void){

Faz_isto;

Faz_Aquilo;

Aquilo-Outro;

lcd();

} //fim de execução infinita
} //fecha main

quando chegar no fim de execução infinita, ele volta logo apos o main e inicia o ciclo novamente.

Agora se o seu projeto esta usando tudo nativo do mikroZ, e esta parecendo que esta travando, o problema é o sistema de segurança do menino que bagunça tudo o asm, por causa da droga que você deu pra ele ficar full...

adioz 2is
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor ivan » 03 Dez 2009 12:06

Gilliard,

O q vc "precisa fazer" simplesmente fere o conceito de programação estruturada.
Tem solução? Tem sim!
Toda a vez q vc fizer uma chamada a rotina lcd(), na próx instrução vc executa um "goto XXX"(arghhh!!!) onde XXX é um label para o return da sua subrotina.
Vai fazendo isso(arghhh) até desmontar a pilha de chamadas de subrotinas de volta a rotina Main.

Muito BOA SORTE!!!!
"A mente que se abre a uma nova idéia jamais volta ao seu tamanho original." (Albert Einstein).
Avatar do usuário
ivan
Word
 
Mensagens: 618
Registrado em: 12 Out 2006 21:27

Mensagempor Jozias del Rios » 03 Dez 2009 12:08

Gillard, coloca aqui no forum o codigo INTEIRO que vc diz que não funciona como deveria.

Espero que vc esteja usando o "while(1)" ou o "for (;;)" que indicamos
abs
Os vencedores são aqueles que sabem o que fazer se perderem.
Os perdedores são aqueles que não sabem o que fazer se ganharem.
Avatar do usuário
Jozias del Rios
Byte
 
Mensagens: 279
Registrado em: 31 Out 2009 03:36
Localização: SJCampos-SP

Mensagempor Djalma Toledo Rodrigues » 03 Dez 2009 15:49

Há possibilidade de colocar a chamada a essa Sub LCD no final do Main ?

DJ
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Mensagempor gilliard » 03 Dez 2009 22:45

Então.... Testei os esquema do FOR e do WHILE(1), funcionou direitinho, mas tem um problema, e é o problema que estou tentando solucionar com vocês.

Quando a subrotina lcd() é chamada por outra subrotina(), a subrotina lcd() trava, e não respeita os 500 ms de exibição, e não volta ao void main !!!! Eu preciso chamar essa subrotina, e preciso que ela termine e volte a executar oque esta dentro do void main ();
Avatar do usuário
gilliard
Byte
 
Mensagens: 121
Registrado em: 26 Ago 2008 13:32

Mensagempor Djalma Toledo Rodrigues » 03 Dez 2009 23:52

Além dessas Sub Sub existe Interrupção ?

DJ
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Mensagempor gilliard » 04 Dez 2009 00:25

Existe sim. Dentro do Void Main !!!!
Avatar do usuário
gilliard
Byte
 
Mensagens: 121
Registrado em: 26 Ago 2008 13:32

Mensagempor Djalma Toledo Rodrigues » 04 Dez 2009 01:04

A Interrupção também salva o PC + 1 no na Pilha do Stack

Pode ser essa a causa, isso precisa ser bem cuidado, bem administrado

É responsabilidade do Programador Resetar os os Bits: INTF, RBIF, EEIF , T0IF, etc. ao final da ISR e imediatamente antes da Instrução RETFIE

Caso contrário pode truncar os Endereços de Retorno. A Pilha do Stack tem apenas 8 Níveis mas ela é Circular de modo que pode truncar o End. de Retorno tanto das Subrotinas quanto da própria Interrupção .

DJ
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Mensagempor Jozias del Rios » 04 Dez 2009 08:40

Por isso que eu digo, cola o código todo aqui, que a gente pode até depurar e ver qual é o problema DE FATO, e não ficar divagando em possibilidades...
Os vencedores são aqueles que sabem o que fazer se perderem.
Os perdedores são aqueles que não sabem o que fazer se ganharem.
Avatar do usuário
Jozias del Rios
Byte
 
Mensagens: 279
Registrado em: 31 Out 2009 03:36
Localização: SJCampos-SP

Mensagempor fabim » 04 Dez 2009 08:40

gilliard escreveu:Então.... Testei os esquema do FOR e do WHILE(1), funcionou direitinho, mas tem um problema, e é o problema que estou tentando solucionar com vocês.

Quando a subrotina lcd() é chamada por outra subrotina(), a subrotina lcd() trava, e não respeita os 500 ms de exibição, e não volta ao void main !!!! Eu preciso chamar essa subrotina, e preciso que ela termine e volte a executar oque esta dentro do void main ();


intão, sabe-se lá Deus como, tu conseguiu estourar a pilha stack!!rsrs
E o programa esta se perdendo!!!

O 18FXXXX tem 32 endereços de retorno.
Quando tu abre a janela de config dos fuses, tem uma opção que o uC reseta caso houver estouro de pilha.
Faça um simples teste.
logo no inicio do main, logo apos ter configurado o display.
Escreva. "estourou"
De 1 S de delay +/-
Apague

E entre no loop principal, e fique olhando o display para ver se ele vai apresentar novamente esta mensagem.
Se apresentar, é que a pilha esta estourando.
Se não apresentar, e simplesmente se perder.

O problema é o mesmo que o cristian, e o fernando fernandes estavam se descabelando.

O sistema ant ***** do mikroC, esta funcionando direitinho ..hehe

coloque o seu projeto aqui, pra vermos onde esta implantado a bomba de estouro.

Fabim
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor Djalma Toledo Rodrigues » 04 Dez 2009 09:32

gilliard escreveu: ... a subrotina lcd() trava, e não respeita os 500 ms de exibição, e não volta ao void main !!!! ....

Não respeita os 500 ms porque certamente houve interrupção
Isso pode ser alguma Interrupção que não esta sendo tratada (ou maltratada rs)
Faz o seguinte:
Desabilita Geral as Interrupções
Tem Pinos I/O disponível ? Pendura LEDs para monitorar Entrada e Saída das Subs e Main
assim:
No Main liga Lmain , desliga Lsub1 e Lsub2
Entrou na Sub1 desliga Lmain , liga Lsub1
Na Sub2 desliga Lsub1 , liga Lsub2

DJ
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Mensagempor gilliard » 04 Dez 2009 22:05

Conforme pedido, esta aqui o meu programa teste.

Interrupção:

Código: Selecionar todos
//********** Inicio da configuraçao da contagem do TIMER 1 **********//

unsigned contagem;

void interrupt() {

contagem++;                              // incrementa variável de contagem

PIR1.TMR1IF = 0;                         // clear TMR1IF

}

//********** Fim da configuraçao da contagem do TIMER 1 **********//


Programa teste:

Código: Selecionar todos
#include "lcd.c"
#include "teclado.c"
#include "interrupcao.c"

void lcd( ){

Lcd_custom_cmd(LCD_CLEAR);

Lcd_custom_cmd(LCD_CURSOR_OFF);

Lcd_Custom_out(1,2,"Seja Bem Vindo");

Delay_ms(10);

}

//********** Inicio da configuração do menu **********//

void chamada(){

unsigned char tecla;

                //-------------------------------
                Lcd_custom_Cmd(Lcd_Clear); // Limpa o LCD 16x2 //
                Lcd_custom_out(1,1,"1 - teste");
                Delay_ms(20);
                //-------------------------------

                do {
                    tecla=0;// limpa o valor atual do teclado

                while (tecla==0) tecla=teclado(); // Aguarda algo ser digitado

                if(tecla=='1'){ // Se for digitado 1
                lcd();
                }

                    } while(1); // Faz isso eternamente

}

//********** Fim da configuração do menu **********//

//********** Inicio do programa principal **********//

void main() {

  unsigned char tecla,

  adcon1 = 0x06;        // define pinos AD como I/O de uso geral
  config_lcd();         // Inicia a configuração do LCD
  trisa = 0;
  trisb = 0;              //configura portb como saida
  trisb.f4 = 0;
  trisb.f7 = 0;
  trisc = 0;
  trisd = 0x0F;            //configura portd como entrada(teclado) e saida(LCD)
  trisd = 0;            // Define portd como saida
  trise = 0;            // Define porte como saida
  portb= 255;            //portb em FF
  portd= 255;            //portd em FF
  T1CON = 1;
  PIR1.TMR1IF = 0;                                 // clear TMR1IF
  PIE1  =   1;                                     // enable interrupts
  INTCON = 0xC0;

  lcd();

  tecla = teclado();

   while(1) {

    if (contagem == 1) {

         portb.rb4 = ~ portb.rb4;
         
    }

    if (contagem == 4) {

         if (tecla==0) tecla=teclado();

         if (tecla=='1') { //Se for digitado um 1

         chamada();// chama subrotina chamada()
         }

         portb.rb7 = ~ portb.rb7;

         contagem = 0; // Zera contagem.
    }

  }

}

//********** Fim da programa principal **********//
Avatar do usuário
gilliard
Byte
 
Mensagens: 121
Registrado em: 26 Ago 2008 13:32

AnteriorPróximo

Voltar para PIC

Quem está online

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

x