Ir ao conteúdo
  • Cadastre-se

Interrrupção PIC 18F4620 - MikroC


Posts recomendados

Pessoal, estou tentando fazer a interrupçao externa no 18F4620 e não estou conseguindo.. creio que falta pouca coisa.. alguém consegue me ajudar?

Estou usando MikroC, parti de um exemplo da internet....


void interrupt(){
  if(INT0F_bit == 1 ) {
    LATD0_bit = 0xFF;
    Delay_ms(250);
    LATD0_bit = 0x00;
    Delay_ms(250);
    INT0F_bit = 0;
  }

  if(INT1F_bit == 1 ) {
    LATD1_bit = 0xFF;
    Delay_ms(250);
    LATD1_bit = 0x00;
    Delay_ms(250);
    INT1F_bit = 0;
  }

  if(INT2F_bit == 1 ) {
    LATD2_bit = 0xFF;

    Delay_ms(250);
    LATD2_bit = 0x00;
    Delay_ms(250);
    INT2F_bit = 0;
  }
}

void main() {
  ADCON0 = 1;
  TRISB = 1; // Set PORT B (only RB0) as input
  TRISD = 0; // Set PORT D as output
  LATD = 0x00; // Set all pin on PORT D Low

  INTEDG0_bit = 1; // Set interrupt on rising edge
  INT0IF_bit = 0; // Clear INT0 flag
  INT0IE_bit = 1; // Enable INT0 interrupts
  GIE_bit = 1; // Enable GLOBAL interrupts

  LATD0_bit = 0xFF;
  Delay_ms(250);
  LATD0_bit = 0x00;
  Delay_ms(250);
 
  LATD1_bit = 0xFF;
  Delay_ms(250);
  LATD1_bit = 0x00;
  Delay_ms(250);
  
  LATD2_bit = 0xFF;
  Delay_ms(250);
  LATD2_bit = 0x00;
  Delay_ms(250);

 
  while(1) {

  }
}

interrupt.PNG

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Percebo que usas delay() em interrupts diversas e no main(). Isso pode não ser interessante pois imagina se a rotina estiver dentro do delay() e ser interrompido por outra interrupt que vai usar o delay() de novo e quando voltar, o que vai ser do delay()? . Talvez o compilador chie. Outra, pode ser que haja mais bit a ser ligado pra liberar a interrupt de periféricos externos. Este pic não sei mas em outros eram 3 (se não me falha a memória). E + outra, 10k de pulldown me parece ser alto. Tente 1k

@mrdores

Link para o comentário
Compartilhar em outros sites

No proteus

ADCON1 =  0b00001111;

OU

ADCON1 = 0x0F;

 

Isso para você configurar essas portas como digitais em vez de analógicas como vem configuradas de "fábrica".

Depois

 

Em vez de todos esses variáveis de

LATD = 0x00; // Set all pin on PORT D Low

  INTEDG0_bit = 1; // Set interrupt on rising edge
  INT0IF_bit = 0; // Clear INT0 flag
  INT0IE_bit = 1; // Enable INT0 interrupts
  GIE_bit = 1; // Enable GLOBAL interrupts

  LATD0_bit = 0xFF;

 

você pode substituir por

INTCON = 0b11011000;

 

Com isso(só com o adcon1) você já consegue fazer o proteus funcionar com primeiro interrup, já os outros interrupts são outras configurações você tem que configurar INTCON2 e INTCON3.

 

Fiz aqui

 



void interrupt(){
  if(INT0F_bit==1) {
    LATD0_bit = 0xFF;
    Delay_ms(500);
    LATD0_bit = 0x00;
    Delay_ms(500);
    LATD0_bit = 0xFF;
    Delay_ms(500);
    LATD0_bit = 0x00;
    Delay_ms(500);
    LATD0_bit = 0xFF;
    Delay_ms(500);
    LATD0_bit = 0x00;
    Delay_ms(500);
    LATD0_bit = 0xFF;
    Delay_ms(500);
    LATD0_bit = 0x00;
    Delay_ms(500);
    INT0F_bit = 0;
  }

  if(INT1F_bit == 1 ) {
    LATD1_bit = 0xFF;
    Delay_ms(500);
    LATD1_bit = 0x00;
    Delay_ms(500);
    LATD1_bit = 0xFF;
    Delay_ms(500);
    LATD1_bit = 0x00;
    Delay_ms(500);
    LATD1_bit = 0xFF;
    Delay_ms(500);
    LATD1_bit = 0x00;
    Delay_ms(500);
    LATD1_bit = 0xFF;
    Delay_ms(500);
    LATD1_bit = 0x00;
    Delay_ms(500);
    INT1F_bit = 0;
  }

  if(INT2F_bit == 1 ) {
    LATD2_bit = 0xFF;

    Delay_ms(500);
    LATD2_bit = 0x00;
    Delay_ms(500);
     LATD2_bit = 0xFF;

    Delay_ms(500);
    LATD2_bit = 0x00;
    Delay_ms(500);
     LATD2_bit = 0xFF;

    Delay_ms(500);
    LATD2_bit = 0x00;
    Delay_ms(500);
     LATD2_bit = 0xFF;

    Delay_ms(500);
    LATD2_bit = 0x00;
    Delay_ms(500);
    INT2F_bit = 0;
  }
}

void main() {
  //  ADCON1 = 0x0F;
  ADCON1 =  0b00001111;
  TRISB = 0b11111111;
  TRISD = 0;
 PORTB =0;
 PORTD= 0 ;

                                                    INTCON = 0b11011000;
  INTCON2 = 0b11110101;
  INTCON3 = 0b11011110;



  PORTD.RD0 = 1;
  LATD0_bit = 0xFF;
  Delay_ms(250);
  LATD0_bit = 0x00;
  Delay_ms(250);




  LATD1_bit = 0xFF;
  Delay_ms(250);
  LATD1_bit = 0x00;
  Delay_ms(250);

  LATD2_bit = 0xFF;
  Delay_ms(250);
  LATD2_bit = 0x00;
  Delay_ms(250);


  while(1) {

  }
}

Ainda tem uns bugs, mas só olhando melhor o programa...

 

Tenho relato (se não me falha a memória) que o bug só dá no proteus que não tem que configurar no real , no pic mesmo, não tem que fazer essa configuração meio bugada.

adicionado 1 minuto depois

 

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

Bom dia pessoal....

Funcionou no Proteus, quando fui para a protoboard nao funcionou, para debugar o código e saber até onde a inicialização estava chegando eu coloquei para piscar um led. No proteus funciona inclusive o "debug", já quando gravo (usando o pickit3) e coloco o pic na protobard o led do "debug" nao pisca, fica aceso direto. Meu conhecimento técnico de pic é muito baixo, eu nao faço a menor ideia do motivo, se puderem me ajudar mais uma vez fico agradecido.

Tem um detalhe, quando eu comento a interrupção (configuração do intcom o restante funciona porém, como é de se esperar, sem interrupção.

 

 

void main()
{
  ADCON1 =  0b00001111;
  TRISB = 0b11111111;
  TRISD = 0b10000000; //d7 estou usando com input, para inicializar o RTC caso esta porta esteja em 5v, as demais como output
  PORTB = 0;
  PORTD = 0;
// ja tentei com essas duas formas de iniciliar o intcon
  //INTCON = 0b11011000;
 // INTCON2 = 0b11011000;
  //INTCON3 = 0b11011000;

 // INTCON  = 0b11011000;
 // INTCON2 = 0b11110101;
  //INTCON3 = 0b11011110;
  
  INT0F_bit = 0;
  INT1F_bit = 0;
  INT2F_bit = 0;
  
  LATD6_bit = 1;
  Delay_ms(1000);
  LATD6_bit = 0;
  Delay_ms(5000);

  UART1_Init(9600);
  Delay_ms(100);


  LATD6_bit = 1;
  Delay_ms(1000);
  LATD6_bit = 0;
  Delay_ms(5000);

  I2C1_Init(100000);            //inicia comunication i2c
//minute, hour, weekday, day, month, year (6 - Saturday)
  if(RD7_bit == 1) { //se d7 estiver alta inicio o relógio e pisco o led d5
    WriteTime(0,2,7,22,11,17);
    LATD5_bit = 1;
    Delay_ms(1000);
    LATD5_bit = 0;
    Delay_ms(5000);
  }

  LATD6_bit = 1;
  Delay_ms(1000);
  LATD6_bit = 0;
  Delay_ms(5000);

  Sound_Init(&PORTD, 4);     // inicia o buzzer

  init();

  //Delay_ms(5000); //aguarda 5s para o arduino ficar pronto
  LATD6_bit = 1;
  Delay_ms(1000);
  LATD6_bit = 0;
  Delay_ms(5000);

  while (1) {

...

}

 

 

void interrupt(){
  if(INT0F_bit==1) { //botão mais
 /*   LATD0_bit = 0xFF;
    Delay_ms(100);
    LATD0_bit = 0x00; */
    INT0F_bit = 0;
    alterado = 1;
    alterando = 1;
    valor++;
    if(tela == 6) {
      exibindo = 0;
    }
  }
  if(INT1F_bit == 1 ) { //botão Menu/ok
   /* LATD1_bit = 0xFF;
    Delay_ms(100);
    LATD1_bit = 0x00; */
    INT1F_bit = 0;
    if(alterando) { //OK
      gravar = 1;
      exibindo = 1;
      alterado = 1;
      alterando = 0;
    }else{//menu
      exibindo = 1;
      alterado = 1;
      tela++;
    }
  }

  if(INT2F_bit == 1 ) { // botao menos
  /*  LATD2_bit = 0xFF;
    Delay_ms(100);
    LATD2_bit = 0x00;  */
    INT2F_bit = 0;
    valor--;
    alterando = 1;
    alterado = 1;
  }

 

o esquema elétrico é o mesmo, porém adicionado outras coisas como i2c para o rtc, serial para trocar informações com um arduino e acionamento de relés

 

 

 

Link para o comentário
Compartilhar em outros sites

Tá antes de eu começar a pensar nos possíveis problemas, me reponde:

 

Você consegue acender um led , fazer ele piscar no pic? Quero saber que o programa está sendo passado.

 

 

adicionado 0 minutos depois

Me passa o circuito que você colocou para o PIC.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Penso que deves saber a função dos intcon e não apenas ir "socando" e tirando bits deles. Certeza que têm que ser programados com o mesmo byte? Mesmos bits? Mesmas posições dos mesmos bits?

 

Outra.. no compilador deve ter algum opção algo como "debug" ou "release" . Opte corretamente. Também verifique a montagem, fuses e afins

 

+outra... @Bommu Perneta ... assuma daqui kk

Link para o comentário
Compartilhar em outros sites

O desenho de baixo é do arduino heehhe

Qual o programador você está usando O Pickit3 ou está usando algum programador de outra forma?Me mostra um link dele. Você está usando o programa Mikroc?

1 hora atrás, mrdores disse:

remover as configurações intcom ai funciona normalmente

Não entendi muito bem... você tentou fazer um led piscar com um programa simples (tipo led blink)e colocou intcom ou você está falando do programa que eu coloquei ai em cima corrigido e você retirou o intcom e está funcionando no pic?

 

Ora... se for o segundo caso e  está funcionando do jeito que você quer pronto, assunto resolvido. O Proteus precisa algumas configurações a mais para funcionar, como disse no real as vezes não se faz necessário isso. Mas todos esses registradores como intcom estão lá pre configurados quando você roda, se você digitar ele no programa ele vai modificá-los. Intcom modifica várias coisas no pic, só olhar o datasheet dos dos oito bits da esquerda para direita.

 

 

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...