Ir ao conteúdo
  • Cadastre-se
wBB

Medição de tempo por sinal externo

Recommended Posts

Olá!

Estou precisando determinar o tempo de ciclo de um sinal externo. Estou usando PIC16F73, que tem uma única interrupção externa, e pensei em usar essa interrupção para contar o tempo entre as bordas de subida deste sinal externo.

 

DÚVIDA:

Como determino o fim do ciclo medido? pois o fim deste ciclo medido é também o início do próximo ciclo, o que geraria outra interrupção sem que a primeira interrupção tivesse terminado.

 

Obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@wBB ,

 

Esse PIC tem 3 timers. Pode usar um timer de 16 bits para de tempos em tempos amostrar o seu sinal externo e assim calcular o tempo total.

 

Outra maneira é programar uma interrupção por mudança de nível em um determinado pino do Pic, além de programar uma base de tempo no Timer. Assim, toda vez que o nível desse pino mudasse, geraria uma interrupção, e você pode usar a contagem do Timer como sua base de tempo bem precisa e calcular o tempo total envolvido.

 

Em resumo, use o Timer de 16 bits para gerar uma base de tempo bem precisa, e implemente um contador dessas interrupções, para pode usar essa contagem quando ocorre a transição de nível.

 

Paulo

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
13 horas atrás, wBB disse:

DÚVIDA:

Como determino o fim do ciclo medido? pois o fim deste ciclo medido é também o início do próximo ciclo, o que geraria outra interrupção sem que a primeira interrupção tivesse terminado.

sobre isso:

-na interrupt, desabilite a mesma, zere o contador,espere a mudança de estado do pino (com um timeout pra não travar),  capture o contador, reabilite a interrupt. Se bem que acho que você pode habilitar interrupt por queda OU subida de sinal. Confira no d.s. Caso este sinal tenha dutty cicle de quase 100%, seu medo deve ser de não sobrar tempo pra outras tarefas. Sem problema: ignore alguns habilitando a interrupt de vez em quando apenas.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado peças dicas @aphawk e @Isadora Ferraz . Vou testar tentar implementar e ver no que dá.

Me falta bastante conhecimento, muito mais do que imagino... hehehe... mas eu chego lá!

Compartilhar este post


Link para o post
Compartilhar em outros sites

@wBB ,

 

O conhecimento vem com a leitura de teoria e também com a prática !

 

Pesquise por alguns projetos prontos com os PICS , de preferência aqueles que possuam esquemas completos e que explique o programa utilizado !

 

Paulo

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pessoal, me deem uma ajuda por favor para continuação. Implementei o uso de interrupção por mudança de nível na PortB, RB4/RB7 e usei o código abaixo para teste. Aí coloquei um led no Pino A0 para poder ver o processo ocorrendo, só que está havendo dois problemas:

1- O led fica piscando direto a cada 50ms, sem que haja mudança de estado em nenhum dos pinos RB4 a RB7;

2- Mesmo que eu simule uma interrupção nesses pinos, o led continua piscando como se nada tivesse ocorrido.


 

int1 ck;

#INT_RB
void RB_Interrupt(void) {
   if (ck)
      output_high(pin_a0);
   else
      output_low(pin_a0);
   ck = ~ck;
   delay_ms(50);
}


void main()
{

   enable_interrupts(INT_RB);
   enable_interrupts(GLOBAL);

   ck = false;
   while(TRUE)

}

 

================================

Aproveitando também o tópico, qual sintaxe é aceita no MPLab (se é que aceita) para setar diretamente um registrador qualquer. Exemplo: em lugar de escrever "enable_interrupts(GLOBAL);" eu escreveria "GIE_bit = 0x01;" para setar o bit 7 do registrador  INTCON. Ou outro exemplo, para habilitar um timer, já vi sendo usado "OPTION_REG = 0b10000001;" para configurar o referido timer setando diretamente os bits do registrador.

Eu vi alguns programadores fazerem isso em alguns tutoriais, mas no ambiente do MPLab e do CCs esta sintaxe não é aceita.

Compartilhar este post


Link para o post
Compartilhar em outros sites

provavelmente você não colocou pullup ou pulldown no PORTB. Também percebo a falta de ; depois do while true;

 

você está no caminho certo querendo acessar e entender os registros internos do mc. 1ªmente hás de conhecer a função de cada um (dos que pretende usar) bit a bit . Depois hás de consultar o help do seu compilador pra ver como ele os acessa. Caso não te sintas confortável com ele, há também a possibilidade de usar outro compilador.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá @Isadora Ferraz

Coloquei os quatro resistores de pullup no PORTB conforme sua orientação (eu estava colocando apenas um deles anteriormente) e o comportamento está quase do jeito que preciso.

OBS.: Coloquei o ";" no While, mas neste caso não fez diferença.

 

PROBLEMA:

Quando faço o aterramento de um dos pinos do PORTB, o led do pino A0 é acionado.

Porém, apesar de o led ser acionado na mudança de estado de um dos pinos do PORTB, em lugar dele ficar apenas acionado ou desligado de forma contínua, ele fica piscando como se estivesse ocorrendo alteração de estado no PORTB continuamente. O led não deveria alterar o estado apenas quando fosse alterado o estado de um dos pinos de PORTB? É esse comportamento que preciso que exista, ou seja, ao alterar o estado de um dos pinos do PORTB, o led deve acender ou apagar.

adicionado 12 minutos depois

Complementando, sobre a outra questão que coloquei, para setar diretamente os bits de um determinado registrador, o que achei muito interessante e mais prático de fazer por depender apenas das informações do datasheet, é como esse programador demonstra neste vídeo do link abaixo (já será exibido no tempo correto em que ele mostra o que estou falando).

Interrupção por mudança no PORTB

Compartilhar este post


Link para o post
Compartilhar em outros sites
35 minutos atrás, wBB disse:

apenas quando fosse alterado o estado de um dos pinos de PORTB?

sim devia. Pode estar havendo algum ruído,  caso você estiver com circuito real.

Tente:

-habilitar os pullups internos

-colocar um capacitor chute 1...100nF entre pino e gnd

-deixar apenas o pino que deseja que cause a interrupt como entrada e claro habilitar a interrupt só nele.

-desabilitar - forçar o bit a zero - de todas as interrupções no inicio do programa pra depois reabilitar as que deseja. Aí está o lance de manipular as entranhas do mc.

-publique o circuito

 

 

Dá pra fazer sem interrupt...

43 minutos atrás, wBB disse:

ao alterar o estado de um dos pinos do PORTB, o led deve acender ou apagar.

 

Enquanto isso, num outro compilador...
 

#define led RA0
#define botao RB0
...//inicilaização do hw
for(;;)
{
if (!botao) led^=1;
while(!botao);
}

Momento descobrir o efeito deboucing

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isadora, grato pela atenção. Peço até desculpas se não alcanço o conteúdo que você espera que eu verifique, mas sou "café com leite" no assunto hehehehe...

 

Vamos lá, por partes:

1- Não é circuito real. Está em protoboard;

2- Habilitar pullups internos: feito! (eu acho... hehehe);

3- Colocar o capacitor de chute, escolhi 100nF, apenas no pino habilitado. Habilitei apenas o pino RB4. Feito!

4- Forçar a zero todas as interrupções na inicialização do programa (não encontrei o meio de fazer isso ainda, caso possa informar...);

 

Sobre o circuito: É um PIC16F73, com um led conectado ao pino RA0, cristal de 8Mhz, um resistor de 10K para pullup no pino RB4.

 

COMPORTAMENTO ATUAL DO CIRCUITO:

Quando aterro o pino RB4, para detecção da mudança de estado, a função "RB_Interrupt" fica sendo executada enquanto o pino se mantiver aterrado, fazendo com que o led fique piscando.

 

COMPORTAMENTO ESPERADO:

Enquanto o pino RB4 estiver aterrado, o a função "RB_Interrup" deveria ser executada uma única vez e consequentemente o led deveria alterar seu estado anterior uma única vez.

 

O código ficou o seguinte:


 

#include <16f73.h>
#fuses HS
#use fast_io(B)
#use delay(clock=8MHz,crystal=8MHz)


int1 ck;


#INT_RB
void RB_Interrupt(void) {
   if (ck)
      output_high(pin_a0);
   else
      output_low(pin_a0);
   ck = ~ck;
   delay_ms(50);
}


void main()
{
   set_tris_b(0b00010000);         // apenas o pino B4 como entrada
   enable_interrupts(INT_RB);
   port_b_pullups(TRUE);
   enable_interrupts(GLOBAL);

   ck = false;


   while(TRUE);

}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Enquanto isso no datasheet do cara  página 21

 

RBIF: RB Port Change Interrupt Flag bit
A mismatch condition will continue to set flag bit RBIF. Reading PORTB will end the mismatch
condition and allow flag bit RBIF to be cleared.
1 = At least one of the RB7:RB4 pins changed state (must be cleared in software)

 

Por isso há importância em saber escovar alguns bits, por isso disse que você está no caminho certo mas com 1 pouco de preguiça de ler d.s.

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Poxa Isadora! meio injusto heim... estou tentando sem sucesso, mas não por preguiça e sim por desconhecimento. É aquela história, quando não se sabe muita coisa, sequer há dúvida ou pergunta a ser feita, ainda que a resposta esteja na nossa frente.

 

mas vamos lá: 
Suponho que você esteja dizendo que na minha função que trata a interrupção eu deva verificar se está setada a flag que indica que houve mudança de estado em RB4, podendo assim evitar a oscilação. OK. Fiz isso que está abaixo (na função de interrupção), mas não funcionou. 

    if (interrupt_active(INT_RB)) {
        clear_interrupt(INT_RB);       
    } else {
        if (ck)
            output_high(pin_a0);
        else
            output_low(pin_a0);
        
        ck = ~ck;
        delay_ms(50);
    }

 

O que eu precisaria mesmo é acessar a flag via o endereço do INTCON, que no datasheet está:

INTCON REGISTER (ADDRESS 0Bh, 8Bh, 10Bh, 18Bh)
 

Aí criei as variáveis abaixo:

#byte INTCON_REG = 0xF0B; // também tentei com os outros endereços
#bit B0 = INTCON_REG.0

 

    if (B0) {
       B0 = 0;       
    } else {
        if (ck)
            output_high(pin_a0);
        else
            output_low(pin_a0);
        
        ck = ~ck;
        delay_ms(50);
    }

 


Obrigado novamente pela atenção e ajuda. Postei as informações apenas para registro. Vou ver se consigo resolver de outra maneira.

 

abs!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Quase lá!

Após verificar essa condição de incompatibilidade indicada pela Isadora no datasheet do microcontrolador, acrescentei a informação de simples leitura de PORTB conforme o datasheet indica ser necessário (parece ser um comportamento atípico, mas padrão deste microcontrolador) e o problema de execução contínua da função de tratamento da interrupção foi resolvido. Ou seja, quando altera o estado (borda de subida e de descida) no pino RB4, que configurei com entrada, o pino RA0 também altera seu estado, mas não fica mais pulsando enquanto o botão está pressionado.

 

O que está faltando resolver agora é:

Ao pressionar e soltar rapidamente várias vezes seguidas o botão para alteração de estado em RB4, as vezes o nível lógico de RA0 fica alto e as vezes fica baixo, como se RB4 tivesse sido incapaz de detectar alguma borda de subida ou de descida. Talvez esteja havendo algum ruído, sei lá. Mas está com capacitor chute.

 

Alguma sugestão de como corrigir?

adicionado 1 minuto depois

O código atual:

#byte INTCON_REG = 0x0B  // Os outros endereços dos outros 3 bancos
                         // de memória também funcionarão
#bit  RBIF          = INTCON_REG.0
#bit  GIE           = INTCON_REG.7

#byte PORTAA = 0x05
#bit  A0     = PORTAA.0

#byte PORTAB = 0x06

unsigned short temp = 0;

#INT_RB
void RB_Interrupt(void) {
    temp = PORTAB;         // RBIF: RB Port Change Interrupt Flag bit
                         // A mismatch condition will continue to set
                         // flag bit RBIF. Reading PORTB will end the mismatch
                         // condition and allow flag bit RBIF to be cleared.

    // Verifica se houve alteração de estado de PORTB por meio da Flag
    if (RBIF) {
        RBIF = 0;

        if (A0)
            output_high(pin_a0);
        else
            output_low(pin_a0);
        
        A0 = !A0;
    }
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tentei "compilar" seu "fonte" mas apareceu um "warning: missing magic words". você tem algo a dizer sobre isso? Tudo bem. você faz parte da maioria.

 

Bem...

La atrás minha bola de cristal previu o momento debouncing. pois é.. ele chegou. Cadê o delay que estava na interrupt? Quem mandou você tirar?

 

E desculpe se você não me entende com facilidade. Como disse, você faz parte da maioria.

Ah sim.. já ia me esquecendo .. de nada!

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Prezada @Isadora Ferraz . Desculpe-me a falta de atenção em não te agradecer pelo último post. Achei que os outros três "obrigados" e "grato pela atenção" indicados nos posts anteriores, poderiam ter gerado um nível de camaradagem e até algum resquício de amizade por meio de uma simples atitude altruísta* de sua parte. Vejo que me enganei.


Falando em altruísmo e camaradagem, não é esse o objetivo dos Fóruns de discussão? Ou seja, o objetivo não é ajudar pelo simples prazer em ajudar, sem esperar nada em troca? Não estou falando de dar todas as informações de mão beijada, apesar de nada impedir que isso seja feito assim. Estou falando de facilitar a vida e, a medida em que se percebe que um usuário tem real dificuldade, então a ajuda de quem se propõe a responder poderia passar a ser realmente mais detalhada. Não é essa a ideia?


Vejo que você tem um determinado padrão ao se dirigir a aqueles a quem você responde posts aqui no fórum. Já li vários deles. Ao mesmo tempo em que você tem uma ânsia quase desesperada em responder rapidamente a tudo e a todos, você também tem uma forma constante de agressão velada e, por vezes, como agora, com ares de grande superioridade ao se dirigir a mim e aos outros como sendo “igual a maioria”, onde sua posição seria com aqueles outros poucos que restam e que transcendem a vida simples e preguiçosa dos simples mortais. Veladamente o que você está dizendo a mim e “a maioria”, é que somos burros. Desculpe, mas você não me conhece, não sabe quem sou, nem sabe o que tenho, nem o que já fiz na minha vida, nem minhas experiências. Também duvido que conheça essas informações da “maioria” a quem você se refere, para se portar dessa forma a quem quer que seja, muito menos de forma aberta e desnecessariamente incompatível com o que se espera de quem se propõe a “ajudar” a quem precisa. Quando postei minha primeira questão, há poucos dias em que me cadastrei, assim como muitos outros fazem eu também já me identifiquei como sendo iniciante. Estou estudando isso como hobby, o que, quem sabe, pode tomar uma abordagem profissional no futuro. Por que não?


Quando eu e muitas outras pessoas entramos em fóruns como este e infinitos outros, o que esperamos é, no mínimo, respeito e cordialidade.  A qualquer um é permitido cadastrar-se e postar questões sobre quaisquer assuntos. Porém, e sempre tem um porém, NINGUÉM É OBRIGADO A RESPONDER qualquer quer seja a questão que está pendente. E em respondendo a questão, espera-se que sejam seguidas regras de conduta, civilidade, educação e comportamento sociável, tanto no diálogo, como num todo. Principalmente na resposta a questão propriamente dita.


Apenas finalizando, para fechar o post e esse assunto deste post encerrar, pois pretendo abrir outro já que esse praticamente acabou indo pro vinagre, vamos a suas colocações:


1- No compilador que eu uso, o CCS, não deu esse warning.  Sim, eu sei que você faz questão de frisar que usa outro compilador e que o CCS é uma porcaria. Mas, com o objetivo de ser mais produtiva, em outra oportunidade que você propuser a alguém que use outro compilador ou fizer uma crítica qualquer, sugiro que indique o nome por favor ou a solução imediata do problema em questão. Talvez as pessoas possam tentar seguir sua orientação (e é opção delas não seguir também) e até concordarem com você, agradecendo pela sua magnânima e inigualável ajuda aos mortais;


2- debouncing: sim, eu já tinha testado com o delay, de vários tempos inclusive, mas quando copiei o código para postar eu havia feito o teste sem o delay para verificar se mudava. Mas não resolveu nem com delay, nem sem delay. E não tem a ver com “quem mandou” e sim com opção para teste. Desculpe se a minha bola de cristal falhou ao não me informar que você ficaria irritada com isso e desculpe por não ter lhe perguntado se eu poderia retirar o delay;


3- Está desculpada, mas é engano seu que não lhe entendo com facilidade. Apenas tento seguir minhas regras de vida e conduta, sendo cordial para amenizar situações de conflito iminente como nos posts #11 e #13, em que eu já poderia ter lhe respondido com um pouco menos de simpatia dada à falta de noção em chamar de preguiçoso alguém que estava trocando mensagens o dia todo com você, ou seja, estudando para resolver o problema, mas ainda perdido. Problema este, que supostamente é ridículo do seu ponto de vista e que você, como pessoa inteligente, experiente e competente como é, já poderia ter sido mais prática, proativa e produtiva (nossa, quantas palavras com “p”... né?!), ajudado ao iniciante aqui e fechado o post muito antes de chegar neste ponto. Mas enfim....


*Altruísmo, segundo dicionários em geral, é: Ausência de egoísmo; atitude que visa o bem-estar do próximo, não tendo em consideração os seus próprios interesses; dedicação desinteressada; ação de amar ao próximo sem esperar nada em troca.
OBS.: coloquei o significado da palavra aqui, pois queira lhe poupar tempo de procurar em um datasheet de seres humanos, também conhecido como dicionário. Afinal, o fórum é para tirar duvidas, criar um banco de conhecimento e assim facilitar a vida de muitos através de um primeiro que encontrou determinada dificuldade/dúvida.


Muito, muito, muito obrigado, obrigado, obrigado novamente pela sua atenção e pelo seu tempo.
De verdade você me ajudou. Não é brincadeira. Mas, se me permite um conselho para sua vida é: mude seu jeito de tratar as pessoas. Ainda que para você esteja tudo aparentemente normal e até possa parecer espontâneo ou engraçado, não está normal e nem é engraçado.

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ufa.. quase perdi o fôlego pra ler kk. De fato tentei APENAS descontrair mas o tiro saiu pela culatra kk.

é disso que to falando...

Só 1 coisa "maioria" me referi aos que não me entendem mensagens implícitas e nunca (nunca mesmo) aos que eventualmente (eventualmente) menos dotados tecnicamente falando ok?. Mas sua opinião foi muito importante sim amigo. No entanto se não te importas (claro que não, né) prefiro manter meu estilo literário a continuar contribuindo com sua formação ok?

 

Ah sim você não é o 1º (e talvez não o último. O próximo sê-lo-á) que passa por isso. De fato dois (02!) moderadores já me puxaram a orelha por mp kk. Pode não acreditar (mas deve): até me deu infração formal. to com 19,999 pontos na certeira kk

 

Perdão e boa sorte!

 

moderador , espere ele ler e depois apague pra não queimar meu filme kk

 

ah.. foque nisso apenas então: o delay logo em seguida ao evento faz o sistema ignorar os repiques que o botão dá. De fato nem havia pensado em coloca-lo dentro da interrupt. Boa ideia a sua!

E outra: basta fazer RBIF=0 pra que o evento não fique se autorepetindo.

 

Agora sim moderador .. perdão e boa sorte, edite e pode fechar se o autor quiser... kk

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Prezada Isadora.

Não tenho intenção nenhuma de ficar com briguinhas online com quem quer que seja. Aliás, além de não acrescentar nada, ainda tomam um tempo precioso que poderia estar sendo usado para várias outras coisas. Se você realmente entende que está se excedendo, e imagino que sim, dada a sua auto acusação de que esse tipo de problema já ocorreu antes, por mim tudo bem. Acho louvável sua atitude e demonstra humildade neste ponto. Mais ainda: se você ainda se prontifica a continuar contribuindo na formação minha e dos outros que já chamaram sua atenção pelo mesmo motivo, também mostra profissionalismo. Para mim toda ajuda é bem vinda.

 

De minha parte o assunto está encerrado.

Fique tranquila!

 

Obrigado pelas novas dicas.

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

@wBB ,

 

Opa , legal pela sua compreensão. A @Isadora Ferraz é muito prestativa, e também já relativamente idosa, então de vez em quando recebemos alguns "avisos" sobre a educação que recebemos de nossos avós , pois como tal ela se acostumou com eles kkkkkkkkkk

 

Mas sempre eles são feitos como uma brincadeira. Eu também costumo brincar um pouco para descontrair, sei que algumas pessoas não gostam desse "estilo", então fiquei contente em ver que isso não foi algo levado muito a sério, ok ?

 

Paulo

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa @aphawk ! Foi um simples mal entendido e há intenção de mudança da parte dela, então não tem mais motivo para discutir. Além de tudo, como você disse, ela é mesmo muito prestativa. Vamos tocando...

 

Abraço a todos!

  • Curtir 1

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

×