Fork me on GitHub

Microcontrolandos

O Blog está passando por uma fase de mudanças. Todos os posts estão sendo atualizados, códigos, links e imagens estão sendo arrumados. Conteúdos novos ainda estão por vir.

Utilizando o TIMER1 do PIC

Share:

Utlizando o TIMER1 do PIC






O módulo Timer1 é um temporizador/contador de 16 bits consistindo de dois registos de 8 bits (TMR1H e TMR1L). O par de registros TMR1 (TMR1H: TMR1L) incrementa de 0000h a FFFFh e volta para 0000h. 

A interrupção TMR1, se habilitado, é gerada por overflow, no qual o bit de flag é: TMR1IF (PIR1.0). Esta interrupção pode ser ativado/desativado através do bit TMR1IE (PIE1.0). 

Timer1 pode operar em um dos dois modos: 

1 - Como um temporizador(Sincrono e Assincrono)
2 - Como um contador 

O modo de funcionamento é determinado pela fonte de clock, selecionando o bit TMR1CS (T1CON .1). No modo Timer, o Timer1 incrementa a cada ciclo de clock. No modo de Contador, ele incrementa em cada subida da entrada do relógio externo. Timer1 pode ser ativado / desativado através do bit TMR1ON (T1CON.0). Timer1 também tem uma "entrada RESET" interno TMR1GE, este RESET pode ser gerado por qualquer um dos dois CCP módulos.

Quando o oscilador Timer1 está habilitada (T1OSCEN é definido), os pinos RC1/T1OSI/CCP2 e RC0/T1OSO/T1CKI se tornam entradas para a inserção de um cristal oscilador.



T1CKPS1/T1CKPS0 - Seleção de prescaler da fonte de clock do Timer1
00 - 1:1
01 - 1:2
10 - 1:4
11 - 1:8

T1OSCEN - Oscilador externo do Timer1 (pulso externo ou oscilador externo)
1 - Oscilador externo
0 - Pulso externo

T1SYNC - Sincronização com  o clock
Caso T1OSCEN = 1:
1 - Não há sincronia com o clock
0 - Sincronia com o clock
Caso T1OSCEN = 0:
O bit é ignorado

TMR1CS - Fonte de clock do Timer1
1 - Clock externo
0 - Clock Interno

TMR1ON - Habilida/desabilita o Timer1
1 - Habilitado
0 - Desabilitado

MODO TEMPORIZADOR

Modo de temporizador é selecionado por limpar o bit TMR1CS (T1CON.1). Neste modo, o relógio de entrada para o temporizador é FOSC / 4. O bit de controle de sincronização, T1SYNC (T1CON .2), não tem qualquer efeito, uma vez que o relógio interno é sempre em sincronia.

EXEMPLO:
void main() {
unsigned int value;
T1CON = 0b00000001;

while (1){
TMR1L=0;
TMR1H=0;                 //Inicializa o registro TMR1H e TMR1L com o valor 0.
value = TMR1H<<8;     //desloca 8 bits para a esquerda.Caso TMR1H=0x0A
                      // "value" será 0x0A00 (lembrando que "value" possui 16 bits);
value = value | TMR1L; // logica OU BIT a BIT entre a variável "value" e TMR1L. 
                      // caso TMR1L=0xFF, "value" será 0x0AFF;       
delay_ms(100);
}
}

MODO CONTADOR

Modo de contador é selecionado setando o bit TMR1CS. Neste modo, os incrementos do contador em cada borda de subida na entrada de clock no pino RC1/T1OSI/CCP2 quando o bit T1OSCEN está habilitado, ou no pino RC0/T1OSO/T1CKI, quando T1OSCEN está desabilitado.


Se T1SYNC (T1CON. 2) estiver desmarcada, a entrada de clock externo é sincronizado com os relógios de fase interna.


Se T1SYNC (T1CON. 2) é definido, a entrada externa de clock não está sincronizado.







A fórmula do tempo é:

t = ciclo de máquina * prescaler * contagem(65536 - TMR1H:TMR1L);

ciclo de máquina = 4 / Fosc;

Fosc é a freqência do clock do cristal oscilador.


EXEMPLO:
Quero um tempo de um segundo usando um cristal de 20MHz!!

Ciclo de máquina = 4 / 20Mhz = 0,2us.

t = 0,2 * 4 * 12500 = 10000us ou 10ms.

Usaremos a interrupção para podermos obter o tempo de 1 segundo.


char contagem;

void interrupt(){ 
contagem++;       //para cada interrpção do TIMER1 incrementa a variável contagem
TMR1L=0x2C;   //recarrega o TMR1L;
TMR1H=0xCF;   //recarrega o TMR1H;
PIR1.TMR1IF=0;  //limpa o overflow.
}

void main(){
INTCON.GIE=1; //habilita interrupção global;
INTCON.PEIE=1; //habilita interrupção dos perifericos;
PIE1.TMR1IE=1; //habilita interrupção do TIMER1;
// TMR1 recebe o valor 53026(65536 - 12500), que em Hexadecimal vale 0xCF2C
TMR1L=0x2C; // byte menos significativo
TMR1H=0xCF; // byte mais significativo
T1CON=0b00100001; // Modo Temporizador, prescaler 1:4, clock interno;

...
while (1){
if(contagem==100){    //quando o contagem=100, ou seja, quando o tempo chegar a
portb.RB0=~portb.RB0; // 1s(100*10ms) inverte o estado da portb, pino RB0.
}                     

}
}

7 comentários:

  1. Parabêns pelo blog!! É muito bem explicado e rico em conteúdo!Um verdadeiro tesouro para quem, assim como eu, se interessa por programação de microcontroladores pic.
    Sucessso!

    ResponderExcluir
  2. olá o blog é interessante mostrando exemplos de projetos para iniciantes. porém quero fazer uma reclamação e ao mesmo tempo uma sugestão. Nem todos os programadores utilizam o MIKROC como copilador. No meu caso eu utilizo o CCS, não só eu como vários programadores iniciantes e também experientes. minha sugestão de melhoria, colocar exemplos de códigos também utilizando o CCS. Parabéns pelo blog pelos conteúdos excelentes e nos auxiliando nos projetos e, desde já agradeço a compreensão.

    ResponderExcluir
    Respostas
    1. Já pensou passar Todos esses exemplos para CSS ?????
      É mais fácil você aprender MikroC !!
      Ou procurar um Blog que trabalhe com CSS !!
      Daqui a pouco virão outros dizendo você só trabalha com MikroC e CSS preciso com C++builder e mplab não??
      Fica a Dica!!

      Excluir
  3. Amigo por favor me ajuda, poderia me dizer como ficaria o código para funcionar como se fosse o timer0 (8 bits com estouro de 256), pois irei utilizar um sensor de fluxo e não estou conseguindo de nenhum jeito, por favor me ajude.

    ResponderExcluir
  4. Ótimo conteúdo, parabéns! Há uma nota no datasheet da maioria das MCUs de 8 bits que diz o seguinte: "The TMR1H:TTMR1L register pair and the TMR1IF bit should be cleared before enabling interrupts". Não sei no quanto isso influencia no código final, na dúvida eu faço da seguinte forma (código completo para XC8, os "...." foram propositais devido o BlogSpot não permitir a tag PRE):


    volatile unsigned char COUNT;

    void interrupt main_event() {
    ....if (TMR1IF) {
    ........TMR1IF = 0;
    ........TMR1L = 0xfe;
    ........TMR1H = 0xff;
    ........COUNT++;
    ....}
    }

    void main() {
    ....TMR1H = 0xff;
    ....TMR1L = 0xfe;
    ....TMR1IF = 0;
    ....TMR1IE = 1;
    ....PEIE = 1;
    ....GIE = 1;
    ....TMR1ON = 1;
    ....for (;;);
    }

    ResponderExcluir