Ir ao conteúdo

Posts recomendados

Postado

Boa noite!!

 

Estou desenvolvendo um projeto no MikroC em que a entrada é lida pela função ADC_Read, conforme a variação, a saída se comporta de uma maneira diferente. Porém, em um dos casos eu necessito inserir um delay para que haja um atraso na execução da função. Mas inserindo a função "delay_ms(200)" o meu programa acaba ficando bloqueado durante o período e eu necessito que dependendo da minha leitura, execute a próxima função ignorando esse delay.

 

Ou seja, alguém pode me ajudar em alguma outra função para que eu consiga retardar a execução??

Caso não, estou colando abaixo o que eu fiz utilizando o Timer0, que deveria ter prioridade sobre o delay, mas não está funcionado.

Alguém pode me ajudar?? 

 

 

#define solenoide GPIO.F1

int pedal = 0;


void interrupt()        // vetor de interrupção
{

  if(T0IF_bit)          //Houve estouro do Timer0?
  {

    T0IF_bit = 0x00;    //Limpa a flag
    TMR0     = 0x00;    //Reinicia o timer0

    if(pedal   >= 280)
    {
      solenoide = 1;    // solenoide desce para a costura
    }

   }
} // fim interrupt


void main()
{
  ANS0_bit    = 1;                        // seleciona analógico
  ANS1_bit    = 0;                        // seleciona digital
  ANS2_bit    = 0;                        // seleciona digital
  ADCON0      = 1;                        // seleciona a entrada AN0
  CMCON       = 7;                        // desabilita os comparadores

  TRISIO0_bit = 1;                        // GPIO.F0 seja uma entrada
  TRISIO1_bit = 0;                        // GPIO.F1 seja uma saída
  TRISIO2_bit = 1;                        // GPIO.F2 seja uma entrada
  GPIO        = 0;                        // inicia tudo em low
  
  WPU         = 0;                        // desabilita pull ups
  OSCCAL      = 0XFF;                     // configura o oscilador interno para frequencia maxima(4mhz)
  INTCON      = 0XE0;                     // habilita interrupção do timer 0 e interrupção global e de perifericos
  OPTION_REG  = 0x81;                     // configura o prescaler para 1:4

  TMR0        = 0;                        // inicia a contagem em zero


  while(1)
  {
    pedal = ADC_Read(0);

    if((GPIO.F2 == 0)&&(pedal < 5))
    {
      solenoide = 1;          // utilizei para atrasar a execução que preciso, porém se tiver outra opção, me ajudaria bem mais
      delay_ms(200);
      solenoide = 0;          // sobe o solenoide quando agulha estiver em cima
      delay_ms(10000);        // nesse momento eu gostaria que esse delay pudesse ser interrompido quando alterasse o valor de entrada 								 // não somente após terminar o tempo
    }

    if((pedal >= 5)&&(pedal < 120))
    {
      solenoide = 1;          // solenoide desce para o corta fio
    }

    if((pedal >= 120)&&(pedal < 280))
    {
      solenoide = 0;         // solenoide sobe
    }
    
     delay_ms(100);          // taxa de atualização do ADC



} // fim while

} // fim main

 

  • Membro VIP
Postado

De fato delay() é uma perda de tempo. E no seu caso com 10 segundos é uma eternidade

Tem umas maneiras mais melhor pra evitar o delay e usar só a interrupt do timer pra tudo mas to com preguiça de explicar agora - talvez sempre. Vamos usar o que você já tem e "enganar o sistema" mas com total controle. Algo como:

11 horas atrás, JSM90 disse:

delay_ms(10000);    // nesse momento eu gostaria que esse delay pudesse ser interrompido quando alterasse o valor de entrada // não somente após terminar o tempo

Espero que precisão não seja precisa.

for (i=0;i<100;i++)
{
delay_ms(100);
pedal1=adc_read(0);
if (pedal1!=pedal) return; //ou break nem lembro
}

Caso altere, vai atrasar só 0,1 seg. Tá bom pro c?.

Postado

O problema é que nesse 0,1s fica bloqueado para outra função e no meu caso teria que interromper a qualquer momento.

  • Membro VIP
Postado

Eu não vou explicar os conceitos de RTOs pra você! (porque nem sei kk) Mas se achar que deve, pesquise sobre. É a real necessidade "Operacional em Tempo Real" do seu sistema. (subliminei)...

 

Alternativamente, a alternativa é você criar seu próprio "delay com saída drástica" (inventei isso agora) pela diferença das leituras do ad. Algo como:

meu_delay_com_saida(unsigned int dl,unsigned int saidadrastica)//tempo e valor capturado do ad
{
unsigned int ad;//nem precisa
while (dl--) //ao saber o tempo da iteração abaixo, você pode controlar direitinho o tempo da rotina
{
ad=adc_read(0);
if (ad!=saidadrastica) return;
}
}

Na prática, provavelmente vais precisar de alguma histerese. Pra dar muito mais precisão, decremente sua variável dl na interrupt dum timer p.ex.

 

 

 

Postado

@JSM90 ,

 

Vai ter de redesenhar o seu programa...em vez de usar essa função de Delay, crie uma interrupção de Timer para que a cada milisegundo um contador seja incrementado. Aí você fica monitorando essa contagem em um loop do seu programa principal ! Assim você pode

também esperar que ocorra a sua outra interrupção.

 

Importante : não existe prioridade nas interrupções nessas famílias mais simples

de Pic !!!! 

 

Paulo

  • Membro VIP
Postado

De fato. Ao dar uma olhadela menos superficial no fonte, percebi sua fraqueza. Mas penso que é melhor aguardar algum retorno seu. Vai que já resolveu. Neste caso, penso que é motivo adicional pro retorno pra manter viva a essência do forum (e da vida): "partilhas".

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...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!