Ir ao conteúdo
  • Cadastre-se
Otavio Pessini Bini

PIC interrupção por mudança de estado - pic16f877a

Recommended Posts

@Isadora Ferraz , bom dia.

 

Pensava que minha dor de cabeça havia acabado... SÓ QUE NÃO!

 

Simulando no Proteus, o programa está correspondendo exatamente da forma em que eu quero...

 

Porém, na protoboard, isso não acontece!

 

A saída RC4 (onde estou testando com resistor + led conforme pode ser visto na imagem a seguir), simplesmente não aciona com variação na entrada RB.

 

Notas:

 

1. O circuito está sendo alimentado, constatado pelo multimetro;

2. A saída RC4 não oscila nenhuma tensão, constado pelo multimetro (logo não é o resistor, nem o LED);

3. A entrada RB5, mesmo não alimentada, constatei que fica com uma tensão de 0.45V (não sei porque...). Pensei que talvez seja isso o problema, já que não fica em 0 absoluto conforme a condição do programa (não há mudança na entrada). Caso for isso, como posso corrigir e tirar essa tensão residual?

4. O estranho é que quando jogo a entrada RB5 para o neutro (forçando assim o 0V absoluto), também nada acontece.. O que penso que desafirma a questão acima, correto?

5. Testei com diferentes fontes de alimentação: 5V e pouquinho, 3.7V , e 4V e pouquinho.

6. O estranho é que nos primeiros testes, por incrivel que pareça e antes de tentar mil coisas, a programação constatava acendendo o led por 2 segundos, porém apenas quando ia de 0 para 1 na entrada.. dps alterei algumas coisas, religuei os fios achando que era algum curto, e apenas piorou, simplesmente a saída RC4 não faz nada!

 

Segue abaixo o código que estou usando:

 

unsigned char temp;

void interrupt (void)
{
       if(INTCON.RBIF == 1)
{
       RBIE_bit     =   0x00;
       RBIF_bit     =   0x00;
       RC4_bit      =   0x01;
       temp         =   PORTB;
       RBIE_bit     =   0x01;
 }
}

void main()
{
       CMCON        =   0x07;   // Desabilita Comparadores;
       RBIE_bit     =   0x01;   // Habilita a interrupção por mudança do PORTB <7:4>
       RBIF_bit     =   0x00;
       PEIE_bit     =   0x01;   // Desabilita Periféricos
       GIE_bit      =   0x01;   // Habilita a interrupção global

       TRISB        =   0xFF;   // PORTB configurado como entrada digital
       TRISC        =   0xEF;   // Apenas usaremos RC4 como saída digital

       RC4_bit      =   0x00;

 while(1){
       if(RC4_bit)
{
       delay_ms(2000);
       RC4_bit      =   0x00;

 }
}
}

 

E segue em anexo a imagem do circuito de teste na protoboard.

 

Consegue me ajudar dizendo se há algum erro no código ou no circuito montado?

 

No mais, agradeço... To batendo cabeça a noite inteira! rs

 

 

 

WhatsApp Image 2018-11-16 at 04.57.45.jpeg

Compartilhar este post


Link para o post
Compartilhar em outros sites

bixo burro kk

Observando seu questionamento #3, não vejo resistor de pullup no pino RB5. Penso que eis aí seu problema. Coloque um R de 10K entre o pino e vcc. E pro led coloque 1K

Seu desafio é pequeno "acender um led por 2 segundos quando mudar o estado de um port". Já já a gente consegue!😉

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz ,

 

hahahaha tenha paciencia comigo... rs

 

Segue a imagem do "novo circuito" em anexo.. É assim que você sugeriu a ligação? está correta?!

 

Outra coisa, não irei acender um led, isso é apenas para teste.. Vou utilizar para controlar um relé de estado sólido..

 

Ah, e como não possuo um resistor de 1K, coloquei um de 2 pro led.. Acho que não influencia muito né?!

 

Resumo: Caso a ligação esteja ok, adianto que com o interruptor não pressionado (NA), ainda consta a pequena tensão em RB5..

WhatsApp Image 2018-11-16 at 09.32.20.jpeg

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Otavio Pessini Bini ,

 

Faltam o famoso parzinho de capacitores : um cerâmico de 100nF e um eletrolítico de valor entre 10 a 47uF, ambos colocados o mais perto possível dos pinos de +VCC e GND do Pic... Detalhe que se aprende na prática !

 

Paulo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Meu sem noção amigo, seu pullup ta esquisito. Veja como tem que ser...

img1i.jpg

Coloque o cap de desacop do direto nos furos ao lado do ci. Coloque também um de 10uF. Coloque um 100nF no reset e gnd. Verifique se programou pro oscilador correto. No seu caso parece cristal 4Mhz o que seria XT nas configurações.

Agora vai!

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Otavio Pessini Bini ,

 

Opa, por aqui tudo beleza sim kkk !

 

Repare o circuito formado pelo seu capacitor de desacoplamento... ele não faz desacoplamento nenhum, pois deveria estar "colado"  aos pinos do PIC, em vez de estarem ligados nas barras que se ligam através de fios, formando indutâncias e resistências à passagem da alta frequência. O circuito oscilador a cristal muitas vezes não consegue oscilar justamente por causa desse problema !

 

E cadê o eletrolítico ?  Ele é muito importante para estabilizar as possíveis variações de corrente, por exemplo quando aciona um Led.

 

Não tenha vergonha de colocar esses capacitores em cima do Pic, pode até mesmo colocar atravessado em cima, dependendo da posição dos pinos de GND e de VCC.

 

Outra dica : existe um par de barras de alimentação à esquerda do Pic, e outro par á direita do Pic, certo ?

Faça todas as ligações de GND e de VCC do PIC usando apenas uma dessas barras ! Evita os famosos loops de corrente que podem fazer sua simples montagem ter problemas absurdos e te deixar doido kkkk !

 

Paulo

 

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fala Professores,

 

Acharam que não iria voltar né, rsrsrsrs]

 

Pois bem, segui as diversas dicas por aqui, conforme podem ver na imagem em anexo do circuito atual, e .... NADA FEITO.

 

Simplesmente a saída RC4 não aciona diante do acionamento do push button na entrada..

 

Mais dicas?

WhatsApp Image 2018-11-17 at 14.17.56.jpeg

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Otavio Pessini Bini ,

 

Vi que voce colocou o eletrolitico, mas .... ( sempre tem um Mas ...) continuou ligando os pinos do Pic que devem ir ao GND e ao VCC nos dois conjuntos de barras de alimentação do protoboard : tanto na barra da esquerda como na barra da direita !

 

Mude isso, ou liga tudo nas barras à esquerda ou nas barras à direita !  Nas duas ao mesmo tempo pode ter problemas de não iniciar o oscilador a cristal.

 

Ah, outra coisa : monte o cristal e os dois capacitores diretamente nos pinos do PIC !!! Essa montagem longe, levando a ligação com fios até eles não dá certo !

 

Paulo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Puts... apanhando de 1 bit... quasiliteralmente. Só falta eu ir aí fazer pra você.😠

 

Fale sobre a V no RB5. Reteste no simulador. Ve o lance da programação do cristal que te falei. Faça um pisca led simples:

for(;;)
{
RB4_bit^=1;
delay(500);
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@aphawk  Paulo, boa tarde.

 

Seguindo seu conselho, conforme pode ver na imagem abaixo, utilizei so os pinos a direita para alinmentação, e recoloquei o cristal colado ao PIC..

 

@Isadora Ferraz  , o pino RB5 agora está em 5V sem o interruptor pressionado, porém quando pressiono, vai para 0V absoluto, só que não faz nenhuma diferença na saída RC4..

 

A saída RC4 está setada sempre em 5V agora (alimentando o LED), nada nas entradas consegue mudar a tensão nessa saída..

 

Vi que as outras entradas RB estavam em 5V.. pensei que como a gente estava analisando o PORTB, poderia dar algum conflito só alterando a RB5 e as outras não.. Portanto, setei o PORTB para iniciar em 0V, e agora fica assim: Apenas RB5 em 5V, e as todas as outras RB e RC com exceção da RC4 ficam em 0.54V mais ou menos...

 

Estou gravando com cofig HS, pois o cristal é de 16MHz..

 

Seguindo seu conselho, tentei usar esse código abaixo para testar um led piscando a cada 3 sregundos apenas:

 

void main()
{
       CMCON        =   0x07;   // Desabilita Comparadores;
       RBIE_bit     =   0x01;   // Habilita a interrupção por mudança do PORTB <7:4>
       RBIF_bit     =   0x00;
       PEIE_bit     =   0x01;   // Desabilita Periféricos
       GIE_bit      =   0x01;   // Habilita a interrupção global

       TRISB        =   0xFF;   // PORTB configurado como entrada digital
       TRISC        =   0xEF;   // Apenas usaremos RC4 como saída digital
       RC4_bit      =   0x00;

 for(;;)
{
RC4_bit=1;
delay_MS(3000);
RC4_bit=0;
}

}

 

996112823_WhatsAppImage2018-11-21at14_04_28.thumb.jpeg.f5cb9a298cc9eb7c04f8f43a52fc1d35.jpegPorém ele a RC4 fica sempre ligada (LED aceso), porém não pisca..

 

Sabem o que estou fazendo errado ? Estou desesperado.. tenho 2 dias para concluir esse projeto..

 

 

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Com relação a isso...

27 minutos atrás, Otavio Pessini Bini disse:

a RC4 fica sempre ligada (LED aceso), porém não pisca..

.. sei sim.

27 minutos atrás, Otavio Pessini Bini disse:

 for(;;)
{
RC4_bit=1;
delay_MS(3000);
RC4_bit=0;
}

Ahhh dá um tempo!. Ao pé da letra, você não dá um tempo pro led ficar em zero pow. Faça:

 

for(;;)
{
RC4_bit=1;
delay_MS(3000);
RC4_bit=0;
delay_MS(3000); //2º delay
}

ou

for(;;)
{
RC4_bit^=1;
delay_MS(3000);
}

como te disse lá atrás. Prestenção pow!! Não viu o 'baita' ^ ? Sabe nem dar ctrl-c ctrl-v kk

 

(só brinco com você pois és bem humorado e tmj!... fiz algo semelhante com outro e Brunão me deu uma enrabadinha básica kk).

 

Sorte sua, sou phd em pisca led pra mc. Só sei fazer isso e mais naaadddaaa... Depois que o pisca led funcionar a gente toca o barco...

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz  hahaha sem erro com as brincadeiras.. rs

 

agora a bad news, usando:

for(;;) {

RC4_bit=1;

delay_MS(3000);

RC4_bit=0;

delay_MS(3000); //2º delay }

 

O LED NÃO PISCA! que diabos ser isso ?

 

Ele fica aceso full time.. Sério, nao da p entender!

 

o cristal de 16 usa-se p gravar o HS esmo né ?

 

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

E na simulação funciona????? Querido só pode ser alguma cagadinha básica sua. Verifique a (simples) montagem. Verifique se no pino 1 reset tá com vcc. Sim 16 é HS. Coloque cristal menos freq.Este mc não tem osc interno mas tem como programar com osc RC externo. Ve o d.sheet . Nunca fiz mas é uma alternativa se cristal com defeito. Verifique vcc nos pinos... 'vcc'. verifique gnd. Mau contato no protoboard e etc. Verifique se não está programando com o debug liberado (acho que tem um fuse pra isso). Verifique se watch dog ligado, desligue. tem fuse pra ele.

 

Ah lembrei agora... nesta etapa pisca leds, desligue o GIE. Quando for ligar de novo, coloque pullup em todo o portb.. Ruídos na entrada não deixa sair do interrupt.

 

Me dá boa notícia no próximo post hein!!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Confirme que entendeu que se deixar a porta aberta entra intruso. Eletricamente falando, você a deixa flutuando. O pullup resolve. Então vamos dar uma melhorada na tramela da porta: deixe como entrada APENAS a porta do botão:

Não a isso:

18 horas atrás, Otavio Pessini Bini disse:

TRISB        =   0xFF;   // PORTB configurado como entrada digital

e sim a isso:

TRISB=0b00100000;//esqueci qual bit está o botão... é o 5?

Pullup nele...

Reabilite GIE e pau na máquina.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz , bom dia.

 

Realmente houve uma melhora.. Mas ainda continua estranho..

 

A saída fica ligada (LED ACESO), quando eu corto a alimentação de RB5, o LED apaga, porém quando volto a alimentação ele acende (mas não fica 3 segundos e desliga de novo)..

 

Percebi que as outras entradas RB ainda estão sendo alimentadas (não sei porque).. Não teria um jeito de simplesmente desativar elas para teste? Não colocando apenas como saída?

 

Outra coisa que pensei, na interrupt, não daria apenas para monitorar a porta que eu quero para acionamento da saída, ao invés de monitorar o PORTB inteiro?

 

No aguardo, e com prazo esgotando.. hahahaha

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, Otavio Pessini Bini disse:

na interrupt, não daria apenas para monitorar a porta que eu quero para acionamento da saída, ao invés de monitorar o PORTB inteiro?

1/2 que dá sim amigo. É o que te falei...

5 horas atrás, Isadora Ferraz disse:

TRISB=0b00100000;//esqueci qual bit está o botão... é o 5?

só RB5 como entrada.

 

1 hora atrás, Otavio Pessini Bini disse:

Percebi que as outras entradas RB ainda estão sendo alimentadas (não sei porque).. Não teria um jeito de simplesmente desativar elas para teste? Não colocando apenas como saída?

Amigo, é exatamente isso que te propus lá atrás, lembra?

5 horas atrás, Isadora Ferraz disse:

Então vamos dar uma melhorada na tramela da porta: deixe como entrada APENAS a porta do botão:

ô amnésia hein...

 

1 hora atrás, Otavio Pessini Bini disse:

Percebi que as outras entradas RB ainda estão sendo alimentadas

É porque você não as mandou "desalimentar"... tipo PORTB=0x00; mas não vem ao caso.

 

1 hora atrás, Otavio Pessini Bini disse:

A saída fica ligada (LED ACESO), quando eu corto a alimentação de RB5, o LED apaga, porém quando volto a alimentação ele acende (mas não fica 3 segundos e desliga de novo)..

Acho que você foi apresentando ao efeito bouncing. Coloque um capacitor xute 100nF em paralelo com o botão

 

Olha isso...



#include <pic.h> #define led RC4 unsigned char temp; static void interrupt _int(void) { if (RBIF) { temp=PORTB; led=1; RBIF=0; } } void delay(unsigned int dl) { while(dl--); } void main(void) { CMCON=0x07; ADCON1=0x07; TRISC=0; TRISB=0b00100000; TRISA=0; RBIE=1; PEIE=1; GIE=1; //led=0; for(;;) { if (led) delay(50000); led=0; } }

perceba: não é mikroc, delay criado na unha

Funcionou na simulação. A cada mudança de estado do port, led dá uma acendidinha.

Já dei o empurrão..zão. Vê se pega no tranco.

  • Haha 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz , Sim, eu entendi .. Mas foi o que falei, direcionando só a RB5 como entrada e as outras como saída, indifere se elas ficam alimentadas então, é isso ?

 

Vou colocar o cap conforme mencionado, e testar esse código que você está citando..

 

Posto já para não perder-lo de vista kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk

 

 

E to tentando epgar no tranco, mas tá difícil..

Compartilhar este post


Link para o post
Compartilhar em outros sites
8 minutos atrás, Otavio Pessini Bini disse:

outras como saída, indifere se elas ficam alimentadas então, é isso ?

É isso. Só pra constar, tá valendo mas tecnicamente não se diz "alimentadas" e sim nível lógico 1 ou no seu caso 5V.

Sugiro não mexer nas RB7...4 pois elas são sensíveis a interrupt, ou seja se você mudar de estado manualmente no sw - tipo RB7=1;RB7=0; - , penso que pode ir pra interrupt... não tenho certeza.

 

E aí..? Deu certo? kk

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz ,

 

Eis meu codigo atual :

 

 

unsigned char temp;

void interrupt (void)
{
       if(INTCON.RBIF == 1)
{
       RBIE_bit     =   0x00;
       RBIF_bit     =   0x00;
       RC4_bit      =   0x01;
       temp         =   PORTB;
       RBIE_bit     =   0x01;
 }
}

void main()
{
       CMCON        =   0x07;   // Desabilita Comparadores;
       RBIE_bit     =   0x01;   // Habilita a interrupção por mudança do PORTB <7:4>
       RBIF_bit     =   0x00;
       PEIE_bit     =   0x01;   // Desabilita Periféricos
       GIE_bit      =   0x01;   // Habilita a interrupção global

       TRISB        =   0b00100000;    // PORTB configurado como entrada digital
       TRISC        =   0xEF;         // Apenas usaremos RC4 como saída digital
       RC4_bit      =   0x00;


 while(1){
       if(RC4_bit)
{
       delay_ms(2000);
       RC4_bit      =   0x00;

 }
}
}

 

 

Bom, coloquei o cap conforme mencionou, na entrada do RB5, e ligado ao resistor e ao pushbutton.

 

Porém, agora o que acontece é que quando RB5 está em nivel logico alto, RC4 também fica, por alguns mtos segundos, e depois desliga.

 

Quando nesse estagio que está RB5 em nivel alto e RC4 em nivel alto tb, se eu mando p nivel baixo a entrada, RC4 vai para 0 (desliga LED), e quando volto p nivel 1 a entrada ele acende de novo, porém nao por tantos segundos e desliga.. ainda está meio confuso..

 

Eu ein......

Compartilhar este post


Link para o post
Compartilhar em outros sites

ok... então repita de novo como você deseja que o led se comporte em função da alteração de estado do RB5...

Algo que pode fazer e não sei se entendi direito o que você ainda vai descrever (!?), é:

desabilite a interrupt durante o delay...

 

while(1){
       if(RC4_bit)
{
RBIE_bit     =   0x00; 

     delay_ms(2000);
       RC4_bit      =   0x00;

RBIE_bit     =   0x01;   // Habilita a interrupção por mudança do PORTB <7:4> 

}
}

Fale também pra que vai servir este treco. Um 555 daria conta disso homi!

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz Bom, vamos lá.

 

Isso será para controlar uma solenoide.. como?

 

Por exemplo, a entrada no caso (RB5), será ligado um detector de tensão. O que eu quero é que, caso o detector de tensão está apontado que está em 1 (alimentado), vai para 0 (queda de tensão), quero que acione a saída RC4, ddurante 2 segundos, e depois desligue a saída RC4.. 

 

Quando essa entrada que caiu a tensão, se reestabelecer (ir para 1), quero que de novo a saida RC4 acione, durante 2 segundos, e desligue novamente.. Esse processo inifinito.

 

Por que?! Veja, a saída RC4 será ligada a um relé de estado sólido, e esse relé será ligado a um pistão eletromagnetico..

 

O pistão precisa só de um pico de 2 segundos para acionar e ter a força que precisamos..

 

Entendeu?

 

Vamos ver como se comporta desabilitando a interrupt durante o delay.

 

Valeu!

Compartilhar este post


Link para o post
Compartilhar em outros sites

entendi... você faz isso com um simples 555 monestável e um capacitor e 2 transistores bcxxx no disparo. Mas claro, fica muito fácil e chato  e sem o charme e versatilidade do mc

Ah e tem que ter um filtrinho nesta entrada RB5, devido ao boucing, lembra?

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz Bom, fiz o que voce falou (tirar o interrupt no delay).. e notei algo..

 

Pode ser besteira, mas por exemplo, quando está em nivel alto a entrada, agora está apagada a saída.. Só de chegar proximo(encostar) no push button para direcionar a 0 a entrada, a saida faz o processo certo (vai p 1 no tempo do delay, e retorna a 0).

 

Se eu fico segurando o button, sem apertar para fechar p 0 a entrada, a saida ja identifica a mudança, ai fica em 1 intermitente.. Ai preciso segurar o push button (que joga p 0), e soltar p a saida desligar de novo..

 

Algo que possa fazer para tirar essa sensibilidade?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro 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 publicações 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

×