substituindo rotina de delay

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

substituindo rotina de delay

Mensagempor edybahia » 12 Mai 2012 16:10

Olá pessoal

estou a tempos tentando desenvolver alguma coisa para substituir o delay do PIC por uma contagem de timer.

No meu projeto estou com 5 contagem de tempo diferente, acontece que se eu definir com IF, as 5 rotinas meu tempo vai para o espaço rsrsrsrs... pois a base da contagem nao funciona na pratica acho que necessito ligar o timer - setar o tempo (fazer a contagem) desligar o timer... e assim sucessivamente

estou utilizando o timer zero

segue um pequeno exemplo de uma só rotina

Código: Selecionar todos
 
WHILE(1)
  {
  if(cont==2930) // EM EXATOS 1,5S
  {
  output_toggle(PIN_a0);
  cont=0;
  }

[i]  if(cont==2930) // EM EXATOS 1,5S[/i]

  }
}

[/b]
::: EDY
edybahia
Bit
 
Mensagens: 15
Registrado em: 23 Abr 2009 09:25

Mensagempor xultz » 12 Mai 2012 17:06

Quais são os valores de temporização que você precisa? (mais ou menos)
É diferente falar de delay de 10s e 100us.
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Mensagempor edybahia » 13 Mai 2012 10:25

xultz escreveu:Quais s�o os valores de temporiza��o que voc� precisa? (mais ou menos)
� diferente falar de delay de 10s e 100us.


seria estes aqui

800ms
900ms
1s
1,5s
2s
::: EDY
edybahia
Bit
 
Mensagens: 15
Registrado em: 23 Abr 2009 09:25

Mensagempor edybahia » 13 Mai 2012 15:06

edybahia escreveu:
xultz escreveu:Quais s�o os valores de temporiza��o que voc� precisa? (mais ou menos)
� diferente falar de delay de 10s e 100us.


seria estes aqui

800ms
900ms
1s
1,5s
2s


olá pessoal, alguma sugestão para que eu possa proseguir no desenvolvimento deste projeto. Na prática o que eu necessito e setar valores no mesmo timer e ligar e desligar o mesmo quando a rotina mandar contar estes tempos acima.
::: EDY
edybahia
Bit
 
Mensagens: 15
Registrado em: 23 Abr 2009 09:25

Mensagempor xultz » 13 Mai 2012 20:50

Ó, eu não conheço os detalhes do teu circuito, então eu faria assim:
Configurava o timer0 prá gerar uma interrupção a cada 100ms.
Criava 5 variáveis, uma para cada tempo (vou chamar de count1 a count5) do tipo unsigned char.
No inicio do programa, zerava todas as cinco.
Dentro do tratamento da interrupção, incrementa as 5 variávies e só, e retorna
No teu laço principal do programa, fica analizando as 5 variáveis. Quando count 1 chegou a 8, sabe que passou 800ms, zera ele. Se count2 chegou a 9, mesma coisa. O count3 compara com 10, count4 com 15 e count5 com 20.

É essa sua dúvida, ou eu que não entendi tua pergunta?
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Mensagempor edybahia » 13 Mai 2012 21:00

xultz escreveu:�, eu n�o conhe�o os detalhes do teu circuito, ent�o eu faria assim:
Configurava o timer0 pr� gerar uma interrup��o a cada 100ms.
Criava 5 vari�veis, uma para cada tempo (vou chamar de count1 a count5) do tipo unsigned char.
No inicio do programa, zerava todas as cinco.
Dentro do tratamento da interrup��o, incrementa as 5 vari�vies e s�, e retorna
No teu la�o principal do programa, fica analizando as 5 vari�veis. Quando count 1 chegou a 8, sabe que passou 800ms, zera ele. Se count2 chegou a 9, mesma coisa. O count3 compara com 10, count4 com 15 e count5 com 20.

� essa sua d�vida, ou eu que n�o entendi tua pergunta?


OLÁ gabriel entedi o que vc quiz falar... walleuu
Mais gostaria tenho uma dúvida teria que ser char ?, serviria só para indicar o estouro, ou melhor a contagem.

Não estou conseguindo obter sucesso nesta funcao, sei que se utilizar o delay funciona mais acontece que gostaria de evitar utiliza-lo, pois teria tempos muitos longos...

seria mais ou menos isso que estou fazendo apenas para 1 tempo se funcionar farei para os outros, o meu prob e que tenho 4 botoes para escolher entre 4 tempo 1,2,3,4 segundos (para teste) rsrsrsrs
::: EDY
edybahia
Bit
 
Mensagens: 15
Registrado em: 23 Abr 2009 09:25

Mensagempor xultz » 14 Mai 2012 08:53

Cara, eu estou entendo cada vez menos o que você precisa.
Não precisa ser char, mas é mais interessante que seja, porque na ISR ele faz o incremento da variável numa única instrução, se for outro tipo de variável consome mais CPU, mas a rigor a variável pode ser de qualquer tipo, até float, mesmo que isto não faça o menor sentido.

O resto da tua dúvida eu não entendi nada, se possível, descreva um pouco melhor o que você precisa.
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Mensagempor ze » 14 Mai 2012 08:54

a ideia do xts é boa. para tempos maiores crie uma variável tipo int uai
unsigned char t0,t1,t2,t3,t4;
unsigned int t5;

e não faça if (tx== 8) pois pode dar pau e sim if (tx>7) . bom acho que não ia fazer mesmo
abç
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Mensagempor edybahia » 14 Mai 2012 09:39

xultz escreveu:Cara, eu estou entendo cada vez menos o que voc� precisa.
N�o precisa ser char, mas � mais interessante que seja, porque na ISR ele faz o incremento da vari�vel numa �nica instru��o, se for outro tipo de vari�vel consome mais CPU, mas a rigor a vari�vel pode ser de qualquer tipo, at� float, mesmo que isto n�o fa�a o menor sentido.

O resto da tua d�vida eu n�o entendi nada, se poss�vel, descreva um pouco melhor o que voc� precisa.


Poxa... acho que estou me empolgado na explicacao rsrsrs..

Bom na verdade o que necessito e substituir o delay como por exemplo: vou precisar acionar 4 cargas com tempo definidos e iniciado por um botao.

if(input(PIN_B0)
{
output_high(PIN_A1);
delay_ms(1000);
}

if(input(PIN_B1)
{
output_high(PIN_A2);
delay_ms(2000);
}

if(input(PIN_B2)
{
output_high(PIN_A2);
delay_ms(3000);
}

if(input(PIN_B3)
{
output_high(PIN_A3);
delay_ms(4000);
}

Acontece que com o delay sei que funciona pois tenho um projeto com a utilização do mesmo, mais acontece que nesse projeto terei tempo maiores e preciso de mair confiaca para esse projeto. Na prática tentei substituir o delay, com timer, mais para um tempo funciona blz mais acontece que como são 4 tempos tenho problemas com o timer do pic,
como setar para contar em diferente tempos.

por isso coloquei aqui que podia ligar e desligar dentro da funcao acredito que assim irá funcionar.

Att.
::: EDY
edybahia
Bit
 
Mensagens: 15
Registrado em: 23 Abr 2009 09:25

Mensagempor xultz » 14 Mai 2012 10:51

Edy, a primeira coisa que você deve ter em mente é que o uso de funções do tipo delay deve ser evitado ao máximo. A maioria dos programadores considera o uso delas uma tremenda gambiarra. A menos que você esteja usando um sistema operacional no teu firmware, em que cada rotina é uma thread, aí sim, o uso do delay é obrigatório. Porém, se você não está usando um sistema operacional (que acho que é teu caso), o delay é uma péssima prática. Existem situações muito específicas que eu uso, por exemplo, num device driver para acionar display alfanumérico, que exige um pequeno delay (de 100us) para gravar um byte nele. Note que o delay é pequeno, e para uma situação muito específica.

Prá exemplificar minha ideia, vamos supor que você tenha o seguinte projeto:
Você tem um circuito com 4 botões, que vou chamar de A, B, C e D. E suponha que tenha 4 leds, que vou chamar de L1, L2, L3 e L4.
Suponha a seguinte especificação:
-Se pressionar A, liga L1 por 2 segundos.
-Se pressionar B, liga L2 por 3,5 segundos.
-Se pressionar C, liga L3 por 2,5 segundos.
-Se pressionar D, liga L4 por 5 segundos.
Se um led estiver aceso e pressionar outro botão, o led anterior deve continuar aceso (pelo seu tempo programado) e deve acender o outro led. Ou seja, é como se um led não tivesse nenhuma influência do outro. Cada led obedece ao seu botão e só.
Se um led estiver aceso e durante este período eu pressionar seu botão, o seu tempo reinicia. Se mantiver o botão pressionado, o led fica aceso, e quando soltar, ele apaga após passar seu tempo programado.

Pronto, é uma especificação tosca, mas é assim que o firmware deve se comportar.

Como implementar isto? Tem milhões de jeitos, vou exemplificar apenas um deles.

Eu crio uma interrupção de timer que gera a cada 100ms. Vou chamar a rotina de interrupção de timer_isr

Eu crio 4 variáveis globais do tipo unsigned char chamadas T1, T2, T3, T4 e inicializo todas com 0.

Na rotina timer_isr, faço o seguinte código:
T1 !=0 ? Então T1--
T2 !=0 ? Então T2--
T3 !=0 ? Então T3--
T4 !=0 ? Então T4--

Ou seja, se uma variável de tempo T estiver diferente de 0, ele decrementa em 1 esta variável.

Na rotina principal, ele vai ter um loop:
Botão A pressionado? Então T1 = 20, liga L1
Botão B pressionado? Então T2 = 35, liga L2
Botão C pressionado? Então T3 = 25, liga L3
Botão D pressionado? Então T4 = 50, liga L4

T1 == 0? Então desliga L1
T2 == 0? Então desliga L2
T3 == 0? Então desliga L3
T4 == 0? Então desliga L4

E refaz o loop

Me fiz entender?
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Mensagempor marcelo campos » 14 Mai 2012 11:35

Não sei se gostaria, pra iniciar pode ser um pouco dificil mas depois acredito que simplefique bastante: usar um RTOS mesmo que mais simples como o BRTOS: com ele você pode como que "agendar" tarefas

Neste link tem ele portado pro pic18F4520: http://smartradio.com.br/pic/MultiPIC/BRTOS%20PIC18%20MultiPICAdv.zip

Aqui o link do desenvolvedor dele: http://brtosblog.wordpress.com/category/brtos/page/2/

E um video: http://www.youtube.com/watch?v=5cOaYN2Te2Q
"Há 10 tipos de pessoas: os que entendem números binários e os que não entendem..."
marcelo campos
Word
 
Mensagens: 648
Registrado em: 08 Ago 2009 08:37

Mensagempor edybahia » 14 Mai 2012 13:53

xultz escreveu:Edy, a primeira coisa que voc� deve ter em mente � que o uso de fun��es do tipo delay deve ser evitado ao m�ximo. A maioria dos programadores considera o uso delas uma tremenda gambiarra. A menos que voc� esteja usando um sistema operacional no teu firmware, em que cada rotina � uma thread, a� sim, o uso do delay � obrigat�rio. Por�m, se voc� n�o est� usando um sistema operacional (que acho que � teu caso), o delay � uma p�ssima pr�tica. Existem situa��es muito espec�ficas que eu uso, por exemplo, num device driver para acionar display alfanum�rico, que exige um pequeno delay (de 100us) para gravar um byte nele. Note que o delay � pequeno, e para uma situa��o muito espec�fica.

Pr� exemplificar minha ideia, vamos supor que voc� tenha o seguinte projeto:
Voc� tem um circuito com 4 bot�es, que vou chamar de A, B, C e D. E suponha que tenha 4 leds, que vou chamar de L1, L2, L3 e L4.
Suponha a seguinte especifica��o:
-Se pressionar A, liga L1 por 2 segundos.
-Se pressionar B, liga L2 por 3,5 segundos.
-Se pressionar C, liga L3 por 2,5 segundos.
-Se pressionar D, liga L4 por 5 segundos.
Se um led estiver aceso e pressionar outro bot�o, o led anterior deve continuar aceso (pelo seu tempo programado) e deve acender o outro led. Ou seja, � como se um led n�o tivesse nenhuma influ�ncia do outro. Cada led obedece ao seu bot�o e s�.
Se um led estiver aceso e durante este per�odo eu pressionar seu bot�o, o seu tempo reinicia. Se mantiver o bot�o pressionado, o led fica aceso, e quando soltar, ele apaga ap�s passar seu tempo programado.

Pronto, � uma especifica��o tosca, mas � assim que o firmware deve se comportar.

Como implementar isto? Tem milh�es de jeitos, vou exemplificar apenas um deles.

Eu crio uma interrup��o de timer que gera a cada 100ms. Vou chamar a rotina de interrup��o de timer_isr

Eu crio 4 vari�veis globais do tipo unsigned char chamadas T1, T2, T3, T4 e inicializo todas com 0.

Na rotina timer_isr, fa�o o seguinte c�digo:
T1 !=0 ? Ent�o T1--
T2 !=0 ? Ent�o T2--
T3 !=0 ? Ent�o T3--
T4 !=0 ? Ent�o T4--

Ou seja, se uma vari�vel de tempo T estiver diferente de 0, ele decrementa em 1 esta vari�vel.

Na rotina principal, ele vai ter um loop:
Bot�o A pressionado? Ent�o T1 = 20, liga L1
Bot�o B pressionado? Ent�o T2 = 35, liga L2
Bot�o C pressionado? Ent�o T3 = 25, liga L3
Bot�o D pressionado? Ent�o T4 = 50, liga L4

T1 == 0? Ent�o desliga L1
T2 == 0? Ent�o desliga L2
T3 == 0? Ent�o desliga L3
T4 == 0? Ent�o desliga L4

E refaz o loop

Me fiz entender?


gostei da ideia de decrementar não tinha pensado em fazer o processo inverso fiz algo desse tipo, mais vou pegar está ideia tua fazer alguma coisa aqui no proteus rsrsrs

WHILE(true)
{

while(bt1==0)
{
cont1=1953; // 1s
if(cont == cont1)
{ output_high(led1);
while(bt1==0);
output_low(led1);
}
}
::: EDY
edybahia
Bit
 
Mensagens: 15
Registrado em: 23 Abr 2009 09:25

Mensagempor edybahia » 14 Mai 2012 16:35

Xultz

Conseguir fazer a programação no código que conseguir construir...
Mais fiquei intrigado com o teu código.... mais tive problemas em implementá-lo no proteus, pois não consigo decrementar a variável dentro do loop.
huahauaha utilizando tua exemplificação...
::: EDY
edybahia
Bit
 
Mensagens: 15
Registrado em: 23 Abr 2009 09:25


Voltar para PIC

Quem está online

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

cron

x