Guia CNC Brasil - Tudo sobre CNC, Router, Laser, Torno e 3D Print

ELETRÔNICA / ELÉTRICA => Eletrônica Básica => Microcontroladores => Tópico iniciado por: Meca2010 em 29 de Maio de 2010, 14:43

Título: Usando Timer do PIC
Enviado por: Meca2010 em 29 de Maio de 2010, 14:43
Boa Tarde a Todos!
Gostaria de saber se alguem poderia me ajudar com uma parte de um programa que eu nao estou conseguindo.

Eu preciso fazer um temporizador do pic contar 30 segundos....
do tipo

Se uma saida for ativada o temporizador vai começar a contar o tempo, se esta saida for desativada deve parar o tempo e seguir o programa...
Mas se continuar ativada e der os 30 segundos programados vai ativar outra saida...
a partes da saidas eu sei, soh nao sei fazer a configuraçao do timer...
se alguem puder me ajudar agradeço..
Att
Título: Re: Usando Timer do PIC
Enviado por: minilathe em 29 de Maio de 2010, 15:07

Seguem algumas rotinas que parte eu aproveitei e parte eu desenvolvi (costumo manter e usar alguns comentários em inglês), para o PIC16F628, mas pode ser usadas por outros. Os valores devem ser ajustados conforme o clock que voce usar.

Se quiser 1 segundo, é só chamar 4 vezes a rotina de 250ms e se quiser 30s, é só chamar 30 vezes a rotina de 1 s. Atente que cada registrador vai até 255.

É necessário criar duas variáveis em RAM, definidas em "cblock".


;*******************************************************************
;
;   file register declarations: uses only registers in bank0
;   and at 0x20 in the 16F628
;
;*******************************************************************

   cblock   0x20

   ld_loop_ex
   ld_loop_in

   endc


;
;**********************************************************
;
;   Delay for about 400x cycles
;
;    Se w=1, temporiza 1ms @ fck = 4MHz
;
waitx400:
       movwf   ld_loop_ex
ld_loopex:
   movlw   (400-4)/4
   movwf   ld_loop_in
ld_loopin:
       decf    ld_loop_in,F
       skpz
       goto    ld_loopin
   decf    ld_loop_ex,F
       skpz
       goto    ld_loopex
   return
   
;**********************************************************
;
;   Delay for about 2 ms
;
delay2ms
       movlw   2
   goto   waitx400

;**********************************************************
;
;   Delay for about 250 ms
;
delay250ms
       movlw   250
   goto   waitx400
Título: Re: Usando Timer do PIC
Enviado por: Meca2010 em 29 de Maio de 2010, 15:14
Mas, esta nao seria a linguagem Ccs?

Estou precisando em Linguagem C para MikroC
msmo assim agradeço por ajudar =)
Título: Re: Usando Timer do PIC
Enviado por: minilathe em 29 de Maio de 2010, 17:01
Mas, esta nao seria a linguagem Ccs?

Estou precisando em Linguagem C para MikroC
msmo assim agradeço por ajudar =)

O programa está em linguagem "assembly", também conhecida como linguagem de máquina.

O CCS é um compilador (um programa ou um ambiente de programação que gera o código ASM=assembly e/ou em HEX), e não possui, ou não é uma linguagem.

Título: Re: Usando Timer do PIC
Enviado por: robedany em 29 de Maio de 2010, 21:57
Boa noite Gil
Por acaso vc. tem algum programa ou rotina em ASM para o 12f629/12f675, com osc 4mhz e comando atravez de pot numa porta, possa sair em outra porta uma frequencia variavel aprox. de 100 a 1000hz, onda quadrada?
Equivalente ao temporizador 555

Grato Roberto
Título: Re: Usando Timer do PIC
Enviado por: minilathe em 01 de Junho de 2010, 05:43
Olá Roberto,

Por acaso vc. tem algum programa ou rotina em ASM para o 12f629/12f675, com osc 4mhz e comando atravez de pot numa porta, possa sair em outra porta uma frequencia variavel aprox. de 100 a 1000hz, onda quadrada?
Equivalente ao temporizador 555

Não tenho pronto, mas dá pra fazer facilmente, usando o potenciômetro conectado aos comparadores do PIC, mas não seria melhor usar o 555?
Título: Re: Usando Timer do PIC
Enviado por: robedany em 01 de Junho de 2010, 14:26
Grato pela resposta Gil
Normalmente uso o 555, mas quando uso oscilador variavel, as vezes a onda não é simetrica.
Tenho um programinha de telegrafia no pic. mas não varia a frequenci, e a quantidade de componentes é muito menor.

Acredito que quando a gente fica mais velho, acho que tenta achar alguma coisa mais pronta, não sei se é preguiça ou a cabeça que não ajuda tanto.

Mas agradeço a gentileza, de repente vc. tinha alguma rotina já pronta e ficava mais facil. Mas não se preocupe.

Abraço
Roberto

Título: Re: Usando Timer do PIC
Enviado por: FB em 17 de Julho de 2010, 18:37
Estou precisando em Linguagem C para MikroC ...

Olá à todos. Se me permitem e o tópico não for antigo demais, posso ajudar com o mikroC na config do timer.
Abraço.
Título: Re: Usando Timer do PIC
Enviado por: HSamuel em 04 de Agosto de 2010, 19:29
Boa noite a todos,

      FB, também utilizo o MikroC, e estou tendo problemas com TIMER e interrupção no PIC. Se vc ou alguém puder ajudar ficarei muito grato. Estou me dirigindo a vc, pq vc disse que tb programa com o MikroC e pode ajudar com TIMER, mas se alguém tb souber, tiver algumas dicas, se possível, por favor me ajudem.

Estou programando o PIC 16F627A, como disse antes utilizo o MikroC. O que precisso fazer é o seguinte:

Quando uma determinada entrada receber um pulso, iniciar um contador, e quando essa mesma entrada receber outro pulso, parar o contador, fazer os cálculos necessários e zerar o contador para que o processo se repita. Resumidamente, tenho uma entrada e preciso do tempo entre os pulsos que chegam a ela. Deu pra intender +/-?

Se alguém puder ajudar... qualquer ajuda é bem vinda! Grato desde já.


Abraço a todos.
Título: Re: Usando Timer do PIC
Enviado por: FB em 04 de Agosto de 2010, 21:27
Boa noite a todos ...
      FB, também utilizo o MikroC, e estou tendo problemas com TIMER e interrupção no PIC...
Abraço a todos.

Amigo, depois de iniciada a contagem, o incremento da variável será a cada 1 segundo?
Outra coisa, envie um esquema do seu circuito, e como deve saber, bases de tempo estão intimamente ligadas ao clock do sistema. Portanto, preciso saber exatamente qual é o cristal utilizado para calcular o timer.
Se as contagens não excederem 255, podemos utilizar o timer0.
Poste também quais calculos o programa deverá executar, ou o código que está trabalhando, desde que não seja para aplicação profissional  = )
Aguardo.
Abraço.
Título: Re: Usando Timer do PIC
Enviado por: HSamuel em 05 de Agosto de 2010, 01:08
Bom dia FB,

       Primeiramente já quero agradecer pela atenção...

       O circuito é bem simples, está em anexo. Fiz o circuito no Proteus Isis. Estou utilizando crystal de 1MHz. O sensor que vai dar os pulsos na entrada é um reed switch, este vai estar preso em uma peça redonda, e como sei o diâmetro da peça, preciso do tempo gasto pra dar uma volta para assim calcular a velocidade da peça, por isso a necessidade de conseguir o tempo entre os pulsos (cada pulso uma volta). É praticamente um velocímetro né... Na verdade é um velocímetro. O cálculo é: V = (2 * pi * R) / T. R é o raio da peça em metros e T o tempo de uma volta em segundos. Depois preciso mostrar essa velocidade em dois displays de 7 segmentos. No Proteus não tem o reed switch, então liguei um botão para simular os pulsos.

A princípio estou usando um cristal de 1MHz mas pode ser que tenha que usar um de 4MHz. Por isso gostaria de aprender direito como configurar o PIC.

Novamente, muito obrigado pela atenção, fico realmente grato. Será que grande ajuda!


Até mais...
Título: Re: Usando Timer do PIC
Enviado por: C N C N o w ! em 05 de Agosto de 2010, 08:38
Na verdade é um velocímetro.

Qual é o raio da peça ? Qual a faixa de velocidades esperada ?
Título: Re: Usando Timer do PIC
Enviado por: HSamuel em 05 de Agosto de 2010, 11:42
Bom dia,

       O raio da peça é de 0,33m, aproximadamente 13'. A velocidade máxima é aproximadamente 60km/h. Tanto o raio como a velocidade máxima podem variar um pouco, mas nesse projeto quero fazer com essas medidas. Por isso preciso aprender como configurar o PIC certinho pra se precisar fazer alguma alteração eu mesmo saber fazer. Procurei na internet, em apostilas e livros mas não achei muita coisa, e mesmo assim, o pouco material que achei estava em assembler, e não sei nada de assembler.

Sempre programei em C/C++ e C#. A alguns anos comecei com PIC mas nunca fiz curso sobre o assunto, o que eu sei aprendi "na raça" mesmo. Já fiz vários projetos com PIC mas nunca precisei utilizar interrupções ou TIMER. Vou começar a ver a matéria de microcontroladores nesse semestre na faculdade. Estou no 6º período de Engenharia de Controle e Automação.

Desde já agradeço pela atenção! Abraço...
Título: Re: Usando Timer do PIC
Enviado por: C N C N o w ! em 05 de Agosto de 2010, 12:09
O raio da peça é de 0,33m, aproximadamente 13'. A velocidade máxima é aproximadamente 60km/h.

O que corresponde a uma bicicleta com rodas de 26" ... poderia usar um desses "computadores de bordo" baratos que há por aí ... são ajustáveis ...

Citar
Sempre programei em C/C++ e C#.

Olha, eu sempre tento incentivar o povo a aprender assembly ... claro que as linguagens de alto nível são excelentes, mas sempre há uma coisinhas que são mais fáceis de resolver em nível mais baixo ...

Mas algo como vc quer é quase trivial pra quem usa C ... dê uma espiada no site da Microchip, vc vai encontrar um punhado de rotinas enlatadas ...
Título: Re: Usando Timer do PIC
Enviado por: HSamuel em 05 de Agosto de 2010, 12:15
Obrigado pelas dicas, mas já tive a idéia de usar um computador de bordo para bicicletas, mas infelizmente não posso usar um desses. Terei que fazer o meu mesmo. Realmente reconheço que é importante saber assembler, mas nunca tive aula sobre essa linguagem e nunca conseguir parar um tempo, pegar um livro e estudar. Já havia ido no site da Microchip mas não achei praticamente nada, talvez não tenha achado o lugar certo, vou voltar lá agora e ver se acho as rotinas que vc mencionou.

Grato!
Título: Re: Usando Timer do PIC
Enviado por: FB em 05 de Agosto de 2010, 14:40
Obrigado pelas dicas .. Terei que fazer o meu mesmo. Realmente reconheço que é importante saber assembler, mas nunca tive aula sobre essa linguagem ...
Herbert, Jorge e demais. Saudações.
Quanto às dúvidas do nosso amigo, vamos por partes. Herbert, você quer o projeto pronto ou realmente aprender configurar o pic para este e muitos outros projetos?
Pelo que vi nas mensagens, vc quer trabalhar com velocidade baixa, algumas voltas por segundo. É possível implementar em C, mas não descarto o que o Jorge disse. Apesar de não ter conhecimento, serei obrigado aprender o assembly também.
Se aprender é sua resposta para continuar com mais projetos, recomendo que comece aqui (http://rapidshare.com/files/266798722/PIC_Microcontrollers_-_Programming_in_C.rar)
Use o código seguinte para descompactar: robo3001
É um excelente material (em inglês), que vai te ensinar como funciona os periféricos internos de um pic com desenhos ilustrativos. Grandioso trabalho da mikroe. Apesar dos exemplos serem para um pic maior, para seu projeto, terá que ler atentamente o datasheet do pic no esquema.
Outra coisa, sugiro não multiplexar os displays, pois pode perder pulsos na contagem do tempo.
(http://img580.imageshack.us/img580/18/01aug051431.gif)
A imagem acima é um projeto que terminei. A saída que pude encontrar, foi colocar os decodificadores BCD pois entre uma leitura e outra no sensor, um delay de 600ms é necessário, e a cintilação nos displays foi reprovada.
Com isso tenho um briho forte nos displays e o programa apenas se preocupa em monitorar a temperatura, escrevendo no display a cada 1seg.
Seu projeto só necessita de uma fonte de interrupção que é a do timer0.

Título: Re: Usando Timer do PIC
Enviado por: FB em 05 de Agosto de 2010, 15:03
Seu projeto só necessita de uma fonte de interrupção que é a do timer0.

Na imagem abaixo, o esquema do timer0 em detalhe:
(http://img440.imageshack.us/img440/2576/02aug051449.gif)
Qualquer pino pode ser usado para disparar seu evento. Se usar o RA4 como no esquema, o timer1 obrigatoriamente deverá ser utilizado.
Ao detectar um pulso no RA4, o programa deverá ativar o timer0 e timer1. Enquanto o Timer0 é incrementado pelos pulsos em RA4, o timer1 conta um intervalo de tempo e quando ele terminar, corta o timer0. Uma variável recebe o valor do timer0 e um comando simples se encarrega de separar as unidades e dezenas. Outro comando coloca os dois nibbles no portB. Isso foge do seu pedido, pois disse "que uma porta ativa a contagem do tempo ao receber um primeiro pulso e quando ela receber outro pulso termina a contagem, efetua os calculos e mostra a velocidade calculada.
Não sou perito em matemática e mecânica, solicito aos mais entendidos, qual das duas formas seria mais conveniente: Contar pulsos em um periodo de tempo ou contar o tempo entre dois pulsos?
Aguardo.
Abraço.
Título: Re: Usando Timer do PIC
Enviado por: C N C N o w ! em 05 de Agosto de 2010, 15:39
qual das duas formas seria mais conveniente: Contar pulsos em um periodo de tempo ou contar o tempo entre dois pulsos?

Esta é uma questão interessante, pedra de tropeço para incautos ... eu pretendia comentar isto e acabei esquecendo ...

A resposta é: depende da frequência do sinal. Para sinais de frequências razoavelmente elevadas, é preferível medir a frequência, ou seja, contar o número de eventos dentro de um intervalo de tempo definido. Para frequências muito baixas, é preferível medir o período, ou seja, o tempo decorrido entre dois eventos consecutivos.

No que se refere à aplicação discutida aqui, temos que:

raio: 0,33 m ==> perímetro: 2,07 m

velocidade: 60 km/h

velocidade tangencial: 60.000 / 3.600 = 16,66 m/s

16,66 / 2,07 = 8,04 Hz

Frequência bastante baixa, o que recomenda a mensuração pelo período.
Título: Re: Usando Timer do PIC
Enviado por: minilathe em 05 de Agosto de 2010, 16:10
Outra coisa, sugiro não multiplexar os displays, pois pode perder pulsos na contagem do tempo.
(http://img580.imageshack.us/img580/18/01aug051431.gif)
A imagem acima é um projeto que terminei. A saída que pude encontrar, foi colocar os decodificadores BCD pois entre uma leitura e outra no sensor, um delay de 600ms é necessário, e a cintilação nos displays foi reprovada.
Com isso tenho um briho forte nos displays e o programa apenas se preocupa em monitorar a temperatura, escrevendo no display a cada 1seg.
Seu projeto só necessita de uma fonte de interrupção que é a do timer0.

Pode ser feito sem decodificadores!! É uma questão de encadear as tarefas na interrupção de tempo, pois são tarefas de curta duração (atualizar o display e ler o Timer) executadas num intervalo regular, a cada 1/24 s ou menos. Cada tarefa consome bem menos que 1/24 s, o que torna o procedimento viável, sem perda de luminosidade ou ocorrência de cintilação do display.

Eu já fiz isso num projeto de fotoplestimógrafo (medidor de pulsação cardíaca através de sensor óptico) com display de LCD LEDs de 7 segmentos, medindo o batimento através do cálculo do período médio de 6 pulsos e também atualizando o display. Usando aritmética de 16 bits e um clock de 4MHz apenas.
Título: Re: Usando Timer do PIC
Enviado por: FB em 05 de Agosto de 2010, 16:33
... Eu já fiz isso num projeto de foto...

Olá Gil. No projeto acima, tentei a multiplexação. No período de leitura do sensor DS1820, um dos displays chegava a apagar, pois eu era obrigado a desligar o bit de interrupções globais.
Como o pic possui o latch para o portB (configurados como digitais), o valor da última leitura é sempre exibido, mesmo durante a leitura do sensor, atualizado após esta rotina. O CD4511 ficou perfeito nesta combinação. Com LCD também concordo, uma vez que ele só vai mostrar novos parametros, quando receber comandos. Neste caso, pode-se até utilizar qualquer pino ligado ao lcd para receber os pulsos de entrada, basta apenas mudar a direção do tris durante a execução do código (entrada quando lê os pulsos, saída quando escreve no lcd).
Quanto à multiplexar, aí apóio o Jorge com assembly, mas neste caso fico limitado, pois aprendi somente C
Vou me dedicar ao assembly, em algumas aplicações, é melhor colocar códigos direto em asm dentro de um programa em C. Já faço isto, mas não tenho domínio.
Abraço.
Título: Re: Usando Timer do PIC
Enviado por: minilathe em 05 de Agosto de 2010, 19:10
Retificando, já mudei acima...

Com LCD também concordo, uma vez que ele só vai mostrar novos parametros, quando receber comandos.

Usei LEDs, mas como faz muito tempo e hoje quase só uso LCD, escrevi LCD por força do hábito  :)

(Já alterei aí em cima no meu Post anterior)

Foi na década de 90, usei um 8751 da Intel e linguagem assembly. Mas também daria para fazer em C (e um bom compilador), é só atentar para o que eu disse antes...

A opção de uso do C ou assembly nesse caso é uma questão de atentar para o tamanho do código gerado. No caso do C, se for grande (o que depende do compilador), o problema é não tornar o programa excessivamente lento. O que acho pouco provável pela simplicidade do código.

Considere também que, dependendo da qualificação do programador, experiência e de como este escreve seus programas, até códigos em assembly podem ficar lentos....  :)
Título: Re: Usando Timer do PIC
Enviado por: minilathe em 05 de Agosto de 2010, 22:29

Com relação a cintilação, é importante ressaltar que os displays (todas as posições) devem ser atualizados a cada 1/24 s ou menos. Pois o olho humano pode ser enganado nessas taxas (como no cinema, na TV analógica, ...). Se forem 4 algarismos, entre um digito e outro devem ser gastos menos do que 1/96 s!!! O que dá 1/24 para os 4 algarismos...

 
Título: Re: Usando Timer do PIC
Enviado por: pedrorose em 25 de Setembro de 2010, 23:58
Olá, estou com um pequeno problema, quero usar um temporizador no MikroC, para fazer as seguinte função, quando um pino é acionado, o temporizador inicia a contagem, o PIC faz a verificação de mais 2 pinos, e se as mudanças ocorrerem em 15s, aciona uma saída, se não permanece como está. Alguém sabe como fazer?
Título: Re: Usando Timer do PIC
Enviado por: Beto_s em 26 de Setembro de 2010, 00:23
è muito facil de fazer no miKroC , dê mais detalhes sobre os dois pinos a serem controlados , se será uma logica E por exemplo .

Depois que aciona a saída , como irá resetar ?

Sempre coloque o máximo de detalhes e entao a ajuda vêm mais rápido ...

Beto.
Título: Re: Usando Timer do PIC
Enviado por: pedrorose em 26 de Setembro de 2010, 00:50
è muito facil de fazer no miKroC , dê mais detalhes sobre os dois pinos a serem controlados , se será uma logica E por exemplo .

Depois que aciona a saída , como irá resetar ?

Sempre coloque o máximo de detalhes e entao a ajuda vêm mais rápido ...

Beto.

os pinos podem ser quaisquer um, RB0 e RB1 por exemplo, mas será uma comparação lógica, será a leitura de dois sensores digitais, assim que o RB0 for acionado, ele iniciará o temporizador, e incrementará 1 em uma variável relacionada ao RB0, e também verificará o RB1, que se estiver em 1, também incrementara 1, mas em uma variável diferente, assim que ambas as variáveis estiverem em 4, o temporizador deve parar, e o PIC deve verificar se os sensores atuaram 4 vezes dentro de 15 segundos, se for, acionara o RC0, por exemplo, e se não for, zerará as variáveis e voltará ao inicio da programação, pretendo usar um goto para voltar ao inicio, e para resetar, usarei a seguinte função

if(PORTB.F3==0) //no caso estou utilizando um push button, que está mandando 5v direto pro pino
{
"variável do RB0"=0;
"variável do RB1"=0;
goto inicio;
}
Título: Re: Usando Timer do PIC
Enviado por: Beto_s em 26 de Setembro de 2010, 22:24
Então pedrorose acho que isso deve dar pra começar alguma coisa...
Fiz um esboço usando um PIC 16f877A em 4MHz , já que vc não definiu qual Pic está usando .
Rb0 e Rb1 são as duas entradas , considerando ligadas quando são colocadas a nivel zero , ou seja , use resistores de Pull up .
 
Rc0 terá um led que liga quando as duas entradas forem pulsadas quatro vezes dentro de 15 segundos .

Rc1 terá um led que liga quando o tempo chega a 15 segundos , mesmo nao acionando nenhuma entrada , só para monitorar o funcionamento do temporizador .

Ficou faltando um reset da saída , pois nao ficou muito claro como vai fazer isso , apenas coloquei um reset dos contadores de pulsos de entrada caso chegar a 15 segundos e as entradas nao totalizarem os quatro pulsos cada . Para reset desligar e ligar o simulador ou o circuito.

Ainda :  a interrupção do timer 1 fica continuamente ligada , apenas criei um flag que é ligado ao primeiro pulso tanto na entrada 1 ou 2 que habilita o contador de 15 segundos.

Espero que sirva de ponto de partida .
MP com  arquivo que simulei no proteus , se vc usar aí .
Também o .hex e o .cof necessários para simularno proteus



// programa MikroC

unsigned short in1 = 0;   //flags das entradas
unsigned short in2 = 0;   // flags das entradas
unsigned counter, tmp;
unsigned T1_count=0;                      // counter variable, temporary variable
unsigned short f_inc;        // Timer1 counter, Usart Send flag
unsigned short f_temporizador ;// flag liga temporizador
unsigned  contador_in1=0;      // inicializa os contadores
unsigned contador_in2=0;
unsigned  temporizador=0; // inicializa temporizador

void interrupt() {

  if (PIR1.TMR1IF) {
    T1_count++;                              // increment T1_count
     TMR1H = 11;                            // write values to Timer1 registers
      TMR1L = 220;
    if (T1_count == 2) {                  // valor original =4 !!!!!!!!! para  clock 8 Mhz
      T1_count = 0;
    if (f_temporizador)
      f_inc = 1;              // se o temporizador estiver ligado seta f_inc
      }
    PIR1.TMR1IF = 0;
    }

  PIE1.TMR1IE = 1;            // Enable Timer1 interrupt
  INTCON = 0xC0;              // Enable GIE, PIE
}//~

void main() {
  ADCON1   = 0;               // Set AN pins to digital I/O
  TRISA    = 0;               // PORTA is output
  TRISD    = 0;               // PORTD is output
  TRISB    = 0XFF;               // PORTB.0 IN
  TRISC    = 0;                //PORTC OUT
  PORTC    = 0;

  T1_count = 0;
           // initialize T1_count

  TMR1H = 23;                 // Values are calculated for 8MHz
  TMR1L = 184;
  T1CON = 0b00110001;               // Set internal clock, start timer, prescaler 1:8


  PIE1.TMR1IE = 1;            // Enable Timer1 interrupt
  INTCON = 0xC0;              // Enable GIE, PIE

      do {


//  TESTE BOTOES PORT B DE 1 A 2
     if (Button(&PORTB, 0, 1, 0))  {

     in1 = 1;
     }
      if (Button(&PORTB, 0, 1, 1))
      if (in1) {
      f_temporizador=1 ; // liga flag temporizador
      contador_in1= contador_in1+1;    // incrementa o contador se rbo acionado
      in1 = 0;
      }
      if (Button(&PORTB, 1, 1, 0)) {

        in2 = 1;
        }
         if (Button(&PORTB, 1, 1, 1))
         if (in2) {
         f_temporizador=1; // liga  temporizador
         contador_in2=contador_in2+1;    // incrementa o contador se rb1 acionado
         in2=0;
         }
 // se os contadores das entradas ja chegaram a quatro
 
    if (contador_in1>=4 && contador_in2>=4) {
    PortC.F0 = 1   ;  // liga a saida indicando que os dois contadores
                      // chegarama quatro antes dos 15 segundos
    temporizador=0 ; // zera o contador de temporizador
    f_temporizador=0 ; // desliga o temporizador
    contador_in1=0 ; // zera o contador de entrada 1
    contador_in2=0 ; // zera o contador de entrada 2
    }
   
 // incrementando o contador
         
    if (f_inc) {
    temporizador=temporizador+1; // incrementa os segundos
    f_inc=0 ; // limpa o flag que foi foi setado na interuupçao
    if (temporizador==15) {
    PortC.F1 =1 ; // liga um led só pra saber que totalizou  os 15 segundos
    f_temporizador=0;  // desliga a temporizaçao até uma das entradas ser acionada novamente
    temporizador=0;    // reinicializa o contador do temporizador
    contador_in1=0;
    contador_in2=0;
                   }
    }
   
   
   
                                         // negates value on PORTD
    } while (1);                         // endless loop
 }
Título: Re: Usando Timer do PIC
Enviado por: pedrorose em 26 de Setembro de 2010, 23:53
vlw cara, testei aqui e é quase isso que eu quero
só faltam alguns ajustes

só me fala, como eu chego nos valores dos TMR1?
Título: Re: Usando Timer do PIC
Enviado por: Beto_s em 27 de Setembro de 2010, 01:10
O timer 1 tem mais recursos que o timer 0 , pois opera com dois registradores
TMR1H - registrados do byte alto
TMR1L - registrador do Byte baixo
Totalizando 16 bits no contador ( contra 8 bits do timer0 ).

Para setar estes dois registradores de maneira correta devemos levar alguns pontos em consideração .
O cristal utilizado ou a frequencia do oscilador interno.
O preescaler selecionado em T1CON
Outros divisores que tenham sido implementados dentro ou fora da prórpia interrupção.

Utilizando o exemplo que escrevi:

Xtal utilizado no PIC = 4 Mhz
Lembrando que o ciclo de máquina devido a arquitetura interna do Pic é igual Fosc/4 .
Ciclo de máquina = 1us ( 0,000001s)

Preescaler selecionado em T1CON = 1:8 ou seja (T1CON = 0b00110001;    // Set internal clock, start timer, prescaler 1:8)

O nosso timer1 sera incrementado a cada 8 ciclos de máquina = 0,000008 = 8us.

Como a interrupção se dá no estouro dos registradores de TMR1 , na passagem de 65535 para 0 , ou de FFFF em hexadecimal
para 0000 , temos mais uma conta para fazer.
O valor que temos que escrever nos registradores será a diferença entre o valor total possível e o tempo que queremos medir.

Como ainda criei um outro divisor dentro da interrupçao ( T1_count==2) , a interrupçao ocorrerá duas vezes para que o flag f_int seja setado.
Isto é útil quando queremos colocar um led piscando a cada 0,5 segundos , por exemplo, mas queremos ter um temporizador com a unidade em segundos.

O valor a ser escrito nos registradores será :

ciclo desejado =  1 segundo
ciclo desejado / t1_count= 0,5 segundos
como nosso preescaler é de 1:8 o nosso Timer 1 será incrementado a cada 8us.
0,5 s / 8us =   62500

Aqui temos que prestar atenção , pois devemos escrever a DIFERENÇA nos registradores :

65536 - 62500 = 3036

Temos que escrever 3036 ( numero decimal) , em dois registradores separados( que juntos formam um hexadecimal de 16 bits)  .
Então :

3036 ( decimal)  = BDC (hexadecimal )

TMR1H = 0X0B 
TMR1L = 0XDC 

transformando novamente em decimal ,
TMR1H = 11 ( decimal)   
TMR1L =   220 (decimal)

Poderiamos escrever os valores diretamente em hexadecimal no compilador, mas acredito que assim fica mais fácil de fixar estas informações. Bastaria observar a sintaxe 0X00 ...
Ficou meio extenso , mas servirá para aqueles que estão iniciando também.

 
Título: Re: Usando Timer do PIC
Enviado por: pedrorose em 27 de Setembro de 2010, 18:34
certo, mas e os TMR1H = 23;  TMR1L = 184;? que são valores diferentes dos anteriores
Título: Re: Usando Timer do PIC
Enviado por: Beto_s em 28 de Setembro de 2010, 00:46
Falha minha, bem observado.
Aproveitei uma rotina que já tinha pra outra função, outro cristal etc...
Esse valores sao carregados na inicialização do PIC , seria o config  numa rotina ASM .
Vão servir apenas até ocorrer a primeira interrupção .
A partir da primeira interrupção os valores carregados são 11(dec) e 220 (dec) , dentro da propria interrupçao . 
No seu caso poderia alterar para os valores acima já na inicialização e a partir do momento que a interrupçao é habilitada , ela passa a ocorrer de 0,5s em 0,5s .

 
Título: Re:Usando Timer do PIC
Enviado por: liniker em 15 de Julho de 2012, 13:12
olá desculpem voltar a este topico antigo mas estou precisando de ajuda
 a todos programadores,
tenho realizado um projeto de tcc, estou tendo algumas dificuldades .
Preciso criar um temporizador por timer a executar determinada funcao.
exemplo:
está executando hora();
depois de um tempo
chama funcao
data();

segue o codico
Código:

#include <16f627A.h>

#fuses intrc_io, nowdt, noprotect, put, nobrownout, mclr, nolvp, nocpd
#use delay(clock=4000000)
#use fast_io(b)

#define BOTAO1 PIN_a0                   //Boto de escolha de ajuste das funes.
#define BOTAO_INCREMENTO PIN_a1         //Boto incremento de variveis.
#define BOTAO_DECREMENTO PIN_a2
int conta_pulsos=0;
#byte porta = 0x05
#byte portb = 0x06

//Boto de decremento das variveis.
int  apagado = 0; //apagado
int a;
int n,i=0,valor;
int h=12;
int m=5;
int s=14;
int dezena, unidade, digito;
int seg=0,q;
int contador=0;
int dia=29;               //Variável dos dias do mês. 0 a 31.
int mes=6;
int ano=12;
//Tabela com os digitos
const unsigned char table[11][5] = {
0b01111110,0b01000010,0b01000010,0b01000010,0b01111110,//0
                  0b00000010,0b00100010,0b01111110,0b00000010,0b00000010,//1
                  0b01011110,0b01010010,0b01010010,0b01010010,0b01110010,//2
                  0b01010010,0b01010010,0b01010010,0b01010010,0b01111110,//3
                  0b01110000,0b00010000,0b00010000,0b00010000,0b01111110,//4
                  0b01110010,0b01010010,0b01010010,0b01010010,0b01011110,//5
                  0b01111110,0b01010010,0b01010010,0b01010010,0b01011110,//6
                  0b01100000,0b01000000,0b01000000,0b01000000,0b01111110,//7
                  0b01111110,0b01001010,0b01001010,0b01001010,0b01111110,//8
                  0b01110010,0b01010010,0b01010010,0b01010010,0b01111110,//9
                         0x00, 0x36, 0x36, 0x00, 0x00, // :
                                   
#int_TIMER1
void temp1s(void)
{
   q++;
   seg++;
   if(seg==4){
   seg=0;
   i++;
   }
   if(i==4){
   i=0;
   }
   set_timer1 (3036);    //Preload do Timer1
}


void caracter(digito) { //chr contem  2 digitos (hh,mm o ss)
   dezena = (digito/10); // dezenas
   unidade = (digito-(dezena*10)); //e as unidades
   
   for (n=0;n<5;n++) { //preparar a tabela para primeiro digito
      output_b(table[dezena][n]);
output_high(pin_b0);
output_high(pin_b7);

      delay_us(900) ;//160useg cada pixel horizontal
   }
  delay_us(700); //pausa entre digitost
output_high(pin_b0);
output_high(pin_b7);
   output_b(0x00);
output_high(pin_b0);
output_high(pin_b7);
   delay_us(700); //pausa entre digitos*/
   
   for (n=0;n<5;n++) {
      output_b(table[unidade][n]);
output_high(pin_b0);
output_high(pin_b7); //unidades
      delay_us(700);
output_high(pin_b0);
output_high(pin_b7);
   }
   delay_us(700); //pausa entre digitos
   output_b(0x00);
   delay_us(700); //pausa entre digitos*/
output_high(pin_b0);
output_high(pin_b7);
}

void doispontos()

{
   for (n=0;n<5;n++) { //preparar tabela para primeiro digito
      output_b(table[10][n]);
output_high(pin_b0);
output_high(pin_b7);
      delay_us(400); //160useg cada pixel horizontal
   }
   delay_us(400); //pausa entre digitost
   output_b(0x00);
output_high(pin_b0);
output_high(pin_b7);
   delay_us(400); //pausa entre digitos*/
}

void barra()

{
   for (n=0;n<5;n++) { //preparar tabela para primeiro digito
      output_b(table[32][n]);
      delay_us(100); //160useg cada pixel horizontal
   }
   delay_us(600); //pausa entre digitost
   output_b(0x00);
   delay_us(600); //pausa entre digitos
}




void hora()
{
caracter(h);
               doispontos();
               caracter(m);
               doispontos();
               caracter(s);
}

void data()
{
               caracter(dia);
               barra();
               caracter(mes);
               barra();
               caracter(ano);
}
void main() {  //bucle principal
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8);   //Configurao do Timer1 para clock interno = 1E6 dividido por 8
   set_timer1 (3036);
   enable_interrupts(INT_TIMER1);               //Habilita interrupo timer1
   enable_interrupts(global);                   //habilita interrupco global
   set_tris_b(0);
   
   a=0;

   while (1) {
     
      output_high(pin_b0);
output_high(pin_b7);
      if (!input(BOTAO1))        //Teste do boton.
      {
         delay_ms (300);        //Para evitar retorno.
         if (contador>2)       //Se maior q 11, zera o contador.
         {
            contador=0;
         }
         
         contador++;             //Incremento da varivel contador.
      }
     
      switch (contador)          //Depois de incrementada, a varivel CONTADOR
      {                          //assume um dos casos a seguir:
         case 1:                 //Menu de ajuste da HORA.
         {
            output_low(pin_b7);
           
            if (!input (BOTAO_INCREMENTO)) //Incrementa a varivel H(hora).
            {
               delay_ms (300);
               h++;
               
               if (h>23)                  //Se a hora for maior que 23, reset.
               {
                  h=0;
               }
            }
           
            if (!input (BOTAO_DECREMENTO)) //Decrementa a varivel H(hora).
            {
               delay_ms (300);
               h--;
               
               if (h==255)                //H  uma varivel inteira de 8 bits.
               {                          //Quando  decrementada para um valor
                  h=23;                   //menor que zero, se torna 255. Ou seja,
               }                          //deve voltar para 23.
            }
           
            q=0;                   //Quando se est em algum menu, Q  resetada.                            //Mantenha na tela.
           
            break;
         }
         
         case 2:                 //Menu de ajuste do MINUTO. Idem ao anterior.
         {
            output_high(pin_b7);
            output_low(pin_b7);
            output_high(pin_b7);
           
            if (!input (BOTAO_INCREMENTO))
            {
               delay_ms (300);
               m++;
               
               if (m>59)                     //Diferente aqui.
               {
                  m=0;
               }
            }
           
            if (!input (BOTAO_DECREMENTO))
            {
               delay_ms (300);
               m--;
               
               if (m==255)                   //Igual aqui.
               {
                  m=59;
               }
            }
           
            q=0;
           
            break;
         }
         
         default:                //Menu principal. Mostra todas as informações.
         {
            s=q/2;            //A variável Q incrementa a 2Hz, então os segundos
                             //devem ser a metade.
            if (s==60)        //Se for igual a 60, reset em Q e S. M incrementa.
            {
               q=0;     
               s=0;
               m++;
               
            }
         
           
            if (m>59)
            {
               m=0;
               h++;
            }
         
            if (h>23)         //Se H(horas) for maior q 23, reset. DIA DA SEMANA
            {                 //e DIA DO MÊS incrementam.
               
             
               h=0;
            }

           
           
           


while(input(pin_a3))  { //so rodoa se pinoa3 =1
               delay_ms(10);
output_high(pin_b0);
output_high(pin_b7);
  hora();

 
 
 
            }
         }

      }
   }
}

Título: Re:Usando Timer do PIC
Enviado por: minilathe em 15 de Julho de 2012, 14:37
Liniker,

Eu não uso o compilador CCS, apenas o que vem com o IDE da Microchip. Seria necessário estudar o manual do CCS.

Título: Re:Usando Timer do PIC
Enviado por: liniker em 15 de Julho de 2012, 15:05
entendo amigo
mas se puder me da uma idea de como faria a logica em C poderia ser em qualquer ambiente.
Título: Re:Usando Timer do PIC
Enviado por: minilathe em 15 de Julho de 2012, 15:28
entendo amigo
mas se puder me da uma idea de como faria a logica em C poderia ser em qualquer ambiente.

Parece simples, mas não é...

O que o programa faz? Onde o PIC está ligado ?(teclado, display, ...). Só para começar...
Título: Re:Usando Timer do PIC
Enviado por: liniker em 15 de Julho de 2012, 16:03
bom, este é o "propeller Clock" relogio holografico, creio que ja deve ter visto a respeito... o port B esta ligado aos leds,
port a3 ao encoder  sempre k o encoder for interrompido uma sequencia binaria sera enviada aos leds.
Título: Re:Usando Timer do PIC
Enviado por: liniker em 17 de Julho de 2012, 20:50
alguem ai para me ajudar?
Título: Re:Usando Timer do PIC
Enviado por: Beto_s em 18 de Julho de 2012, 00:57
Caro liniker,

Creio que a medida que forneça mais detalhes sobre a sua aplicação , a ajuda aparecerá...
Debugar o código pra vc vai ser mais difícil e não é muito justo... concorda?

Vamos dar um empurrãozinho....

Já fiz um propeller aqui, tipo "varinha mágica " , em assembly , mas o princípio é o mesmo.

Supondo , já que isso não ficou claro, que ser programa já está funcionando na parte do disparo do acendimento dos leds, através da interrupção externa no portA , acionado pelo encoder, correto ?
Você precisa alternar o que será mostrado nesse propeller , sendo um dado a data outro a hora , após intervalos de tempo.
Vem a questão :
Precisa ser por interrupção por tempo ? Isso está descrito no seu TCC ?
Pode ser por uma simples contagem ?
Se não for uma exigência do projeto , eu faria de uma maneira mais simples, criando um contador , pois vc já tem uma interrupção externa como referencia.
Por exemplo :  Se seu propeler tem uma rotação de 1800 RPM e você utiliza o zero do encoder para interrupção , contaria até 180 incrementado pela interrupção externa e mudaria o dado , isso daria aproximadamente 6 segundos entre cada valor apresentado nos leds.

Coloca mais detalhes se possível.  ;)

Beto. 
Título: Re:Usando Timer do PIC
Enviado por: liniker em 18 de Julho de 2012, 09:15
Bom dia querido amigo!
Voce está correto
e nao teria a necessidade de ser o interrupcao nao especifiquei no meu TCC
porem tentei varias vezes usar por delay mas so piorou
pensei na interrupcao que ficaria mais facil, ja que estou usando uma.
chegue ate fazer uma logica mas tambem nao funcionou dee uma olhada e veem se funciona
#int_TIMER1
void temp1s(void)
{tempo++;
   q++;
   seg++;

   if(seg==4){
   seg=0;
   i++;
   }
   if(i==4){
   i=0;
   }
if (tempo==2)
{
tempo=0;
j++;
}
if (j>10)
{
}
   set_timer1 (3036);    //Preload do Timer1
}

/////////////////////////////////////////////////////////////////////////////////////////////////

'while(input(pin_a3))  { //so rodoa se pinoa3 =1
switch (j)
{
case 0:
{
hora();
break;
}
case 10:
{
data();
break;
}
      j=0;
          }
         }

      }
  }
}
}




E concorco plenamente com voce, nao quero que me de o peixe quero que me ensine a pescar, pois quem sabe um dia poderei pescar um bem maior sozinho.
desde ja obrigado!
Título: Re:Usando Timer do PIC
Enviado por: liniker em 18 de Julho de 2012, 09:23
Bom dia querido amigo!
Voce está correto
 nao teria a necessidade de ser por interrupcao, nao especifiquei no meu TCC
porem tentei varias vezes usar por delay mas so piorou
pensei na interrupcao que ficaria mais facil, ja que estou usando uma.
chegue ate fazer uma logica mas tambem nao funcionou dee uma olhada e veem se acham um erro!

#int_TIMER1
void temp1s(void)
{tempo++;
   q++;
   seg++;

   if(seg==4){
   seg=0;
   i++;
   }
   if(i==4){
   i=0;
   }
if (tempo==2)
{
tempo=0;
j++;
}
if (j>10)
{
}
   set_timer1 (3036);    //Preload do Timer1
}

/////////////////////////////////////////////////////////////////////////////////////////////////

'while(input(pin_a3))  { //so rodoa se pinoa3 =1
switch (j)
{
case 0:
{
hora();
break;
}
case 10:
{
data();
break;
}
      j=0;
          }
         }

      }
  }
}
}




E concorco plenamente com voce, nao quero que me de o peixe quero que me ensine a pescar, pois quem sabe um dia poderei pescar um bem maior sozinho.
desde ja obrigado!
Título: Re:Usando Timer do PIC
Enviado por: liniker em 18 de Julho de 2012, 09:34
Mas desculpe pois nao intende esta maneira mais simples que tu disse a respeito da rotacao do motor,estou usando um cooler
basicamente com esta rotacao, mas creo que ela nao e estatica por causa do peso da blaca se o meu programa que lhe enviei a cima nao for conveniente poderia me dar mais sugestoes sobre esta maneira simples?
Título: Re:Usando Timer do PIC
Enviado por: Beto_s em 18 de Julho de 2012, 11:24
Olá Liniker...

Onde você trata a interrupçao do pino portA que dispara os inicio da ligação dos leds ?
Não encontrei isso no que vc postou .

Seria esta parte aqui ?
Não é uma interrupção mas sim o  "main"... 


         
           
           


while(input(pin_a3))  { //so rodoa se pinoa3 =1
               delay_ms(10);
output_high(pin_b0);
output_high(pin_b7);
  hora();

 
 
 





A interrupção do timer 1 me parece estar relacionada ao relogio



Faz tempo que não programo nada em C ... MikroC na verdade ...

Vou te dizer o que eu faria em assembly nessa rotina ai acima ...


seto uma variavel com um numero que será o numero de voltas que eu quero contar

N=180
Cada vez que passar dentro dessa rotina decremento 1
Quando N=0 inverto um flag definido anteriormenre  TipoDado e recarrego a variavel com 180
Se TipoDado= 0 mostrar hora
Se TipoDado=1 mostar data

Captou ?

Vou dormir...hehehe


 

 



Título: Re:Usando Timer do PIC
Enviado por: liniker em 18 de Julho de 2012, 11:38
sim e nesta parte mesmo
while(input(pin_a3))  { // o programa so ira enviar a sequencia binaria se o encoder for =1 (interrompido seu feixe de luz)
se a3 =0 ;
nao acontece nada
a interrupcao e apenas para incrementar os segundos
eu cheguei a fazer aqui e deu certo porem ficou meio extenso por switch
mas queria um modo mais simples, pois se eu colocar varias interfaces o programa ficara muito grande sem precisao
segue o codigo:

#int_TIMER1
void temp1s(void){
 tempo++;
 q++;
 
if (tempo>2)// passou 1 segundo
{
j++; //incrementa variavel de controle
if (j>15){
 j=0;
}
tempo=0;
}

   set_timer1 (3036+(get_timer1()));   //recarrega  Timer1
}           

 while(input(pin_a3))  { //so rodoa se pinoa3 =1
switch (j)
{
case 0:
{
hora();
break;
}
case 1:
{
hora();
break;
}
case 2:
{
hora();
break;
}
case 3:
{
hora();
break;
}
case 4:
{
hora();
break;
}
case 5:
{
hora();
break;
}
case 6:
{
hora();
break;
}
case 7:
{
hora();
break;
}
case 8:
{
hora();
break;
}
case 9:
{
hora();
break;
}

case 10:
{
data();
break;
}
case 11:
{
data();
break;
}
case 12:
{
data();
break;
}
case 13:
{
data();
break;
}
case 14:
{
data();
break;
}
   
          }
         }

      }
  }
}
}


captei sim.
mas...
Quando N=0 inverto um flag definido anteriormente?
como faria isto? Seria exemplo: led=!led;//mudando o estado ?
estou usando (ccs)
Título: Re:Usando Timer do PIC
Enviado por: liniker em 18 de Julho de 2012, 15:46
realmente esta comando case  esta ocupando todo espaco da memoria do MC, impedindo de colocar mais funcoes(interface)
oque farei??
Título: Re:Usando Timer do PIC
Enviado por: minilathe em 18 de Julho de 2012, 17:25
Pra que essa sequência de cases que fazem todos a mesma coisa?? Chamar a rotina hora()?? Dá pra fazer isso de maneira mais compacta e eficiente...


switch (j)
{
case 0:
{
hora();
break;
}
case 1:
{
hora();
break;
}
case 2:
{
hora();
break;
}
case 3:
{
hora();
break;
}
case 4:
{
hora();
break;
}
case 5:
{
hora();
break;
}
case 6:
{
hora();
break;
}
case 7:
{
hora();
break;
}
case 8:
{
hora();
break;
}
case 9:
{
hora();
break;
}

case 10:
{
data();
break;
}
case 11:
{
data();
break;
}
case 12:
{
data();
break;
}
case 13:
{
data();
break;
}
case 14:
{
data();
break;
}
   
          }
         }

      }
  }
}
}

Exemplo, use a seguinte linha (faz a mesma coisa):

if(j >= 0 && j <=14) data();
Título: Re:Usando Timer do PIC
Enviado por: liniker em 18 de Julho de 2012, 18:25
Desculpe pela minha falta de compreensao
mas nao intendi o tua logica.
Esta sequencia de case seria o intervalo de segundos para hora e data
cada case seria 1 segundo
incrementado por j
foi a unica maneria que conseguir de mudar estas funcoes!.
Teria como ter mais um pouco de paciencia e me explicar novamente esta tua logica?
Tipo,assim que ligasse o circuito aparecesse hora ();
depois de 9 segundos esta funcao saia
e entrava data();
depois de 5 segundos hora();
sendo assim intermitente

Esta tua logica seria a seguinte?
 while(input(sensor))  { //so dispara os leds se pinoa3 =1
if(j >= 0 && j <=9)
hora();
if (j>=10 && j<=14)
data();

Título: Re:Usando Timer do PIC
Enviado por: minilathe em 19 de Julho de 2012, 09:16
Liniker,

Esta faltando uma sequência lógica nesse projeto. Sugestão:

1- Elabore e envie um esquema elétrico.
2- Defina uma lógica de funcionamento, do tipo: o rotor gira e a cada interrupção o PIC aciona alguns LEDs, conforme .... Outra maneira de fazer seria acionando um motor de passo, nesse caso a interrupção seria desnecessária e o programa seria mais simples.
3- Elaborar o programa.
 
Minha impressão é que você indo direto ao passo 3 sem saber direito os passos  1 e 2.
Título: Re:Usando Timer do PIC
Enviado por: liniker em 23 de Julho de 2012, 17:07

Obrigado a ajuda de todos por aqui neste topico como esta parte do timer eu "concluir" ate onde queria. Mas depois tive outra idea e resolvi criar este topicoonde postei um video:
 http://www.guiacnc.com.br/eletronica/%28i%29%28i%29como-fazer-o-pic-contar-horas-estando-com-circuito-desligado/ (http://www.guiacnc.com.br/eletronica/%28i%29%28i%29como-fazer-o-pic-contar-horas-estando-com-circuito-desligado/)
 caso queiram participar e me ajudar.
Continuo agradecendo ao minilathe por se dispor a continuar me ajudar
Obrigado!