Manipulação de Timers no PIC18F4520
Prof. Ilton L Barbacena
O microcontrolador PIC18F4520 tem quatro temporizadores programáveis que podem ser utilizados em muitas tarefas, como a geração de sinais de temporização, causando interrupções para ser gerada em intervalos de tempo específicos, em intervalos de medição de frequência e tempo, e assim por diante. Os bits de configurações de interrupções dos microcontroladores seguem a seguinte legenda:
Enable bit: São sufixos IE (Interrupt Enable) para representar um bit que pode hablitar ou não o atendimento a uma interrupção. Ex: Se TMR0IE =1 está habilitado atendimento a interrupção de timer0 ; Flag Bit: Estes bits que são setados automaticamente quando ocorre a condição de atendimento a interrupção. Ex: Se TMR0IF = 1, indica estouro do tempo do timer 0. Priority Bit: Existe 2 níveis de prioridades no atendimento a interrupções. Ex: TMR0IP = 1, indica que esta interrupção tem prioridade máxima no atendimento (pula p/ end. 0x0008). ◦
◦
◦
TIMER0
O Timer0 funciona similar aos pics da linha PIC16, exceto que pode operar com 8 ou 16 bits:
8 ou 16 bits
8 bits de prescaler (divisões do tempo)
Fonte de clock pode ser interna ou externa (funciona como contador de eventos)
Gera uma interrupção no overflow (estouro de contagem)
O registrador de controle é o T0CON. Neste o 6 bits menos significativos é similar a linha PIC16 que trabalha com o registrador OPTION. Os outros 2 bits são usados para selecionar contagem de 8 ou 16 bits e habilitar ou inibir a contagem. Na série PIC18 o prescaler não é compartilhado com WDT como acontece na série PIC16.
Registrador T0CON (reset: 1111 1111)
A Figura 1 e 2 ilustram o funcionamento do Timer0 no modo 16 e 8 bits.
Figura 1 – Timer0 em modo 16 bits
Figura 2 – Timer0 em modo 8 bits
Em qualquer modalidade do Timer0, uma interrupção é gerada quando o contador ultrapassar o limite de seu valor máximo (FFH para o 8-bit e FFFFH para os 16-bit) ou overflow, se o bit TMR0IE do registrador INTCON estiver habilitado. O mesmo flag
bit, TMR0IF, do registrador INTCON, é usado para indicar a ocorrência da interrupção ou estouro de contagem. Na Tabela 1 são apresentados os detalhes de configuração do registrador T0CON.
TMR0ON (Liga o timer) T08BIT TOCS (fonte do clock contagem) T0SE ( transição) PSA (prescaler) TOP (seleciona prescaler) S2:S1:S0
1: habilita ou dispara o timer0 0:desabilita 1: 8bits 0: 16bits 1:transição no pino T0CK1(pin 6 do CI) 0: contagem interna (clock/4) 1: incrementa H_L 0: incrementa L_H (no pino T0ck1 ou pino 6 do CI) 1: sem prescaler 0: habilita prescaler 111: 1/256 110: 1/128 101: 1/64 100: 1/32
011: 1/16 010: 1/8 001: 1: 4 000: 1/ 2
No Compilador PIC CCS, temos os seguintes recursos: 1 – Interface de entrada do PIC CCS
Ao escolher um projeto novo (PIC Wizard) tem-se várias abas de configurações. Na aba general, pode-se escolher o microcontrolador, o valor do clock e os fusíveis de configurações. No caso do kit Acepic, devemos escolher PIC18F4520, clock de 8MHz e configurar no mínimo o fusível referente a fonte do clock, com clock externo > 4MHz. Na aba Timers, devemos configurar o(s) timer(s) a ser escolhido(s). No caso timer0 devemos escolher o valor de overflow, ou o valor que indica o tempo de quando deve ocorrer o atendimento a interrupção. Durante a escolha do tempo de overflow pode-se mudar os valores de prescaler a direita, como também habilitar 8 ou 16 bits até obter o tempo de overflow desejado. Feito isso o compilar CCS automaticamente calcula e gera linhas de códigos que aparecem no arquivo com o código fonte, conforme ilustrado no exemplo abaixo: ENABLE_INTERRUPTS(M1); SETUP_TIMER_0(M2); SET_TIMER0(M3);
M1 é o valor a ser gravado no registrador INTCON (GIE=1, TMR0IE=1) end. 0xFF2 Exemplo: M1 = GLOBAL | INT_TIMER0 M2 é o valor a ser gravado no registrador T0CON (End. 0xFD5) Exemplo: M2 = RTCC_INTERNAL | RTCC_DIV_16 |RTCC_8_BIT M3 é o valor de contagem inicial a ser gravado no registrador TMR0 (End. 0xFD6 e 0xFD7) Exemplo: M3 = 100
A primeira linha habilita o atendimento ao pedido de interrupção em decorrência do estouro de contagem ou overflow. A segunda linha configura o modo de atuação do timer0: 8 ou 16 bits e o valor do prescaler. A terceira linha atualiza o valor inicial da contagem em TMR0: No caso de 8 bits atualiza o TMR0L e no caso de 16 bits atualiza os registradores TMR0L e TMR0H.
◦
Defines no arquivo 18F4520.h:
#define RTCC_INTERNAL #define RTCC_EXT_L_TO_H #define RTCC_EXT_H_TO_L #define RTCC_DIV_1 #define RTCC_DIV_2 #define RTCC_DIV_4 #define RTCC_DIV_8 #define RTCC_DIV_16 #define RTCC_DIV_32 #define RTCC_DIV_64 #define RTCC_DIV_128 #define RTCC_DIV_256 #define RTCC_OFF #define RTCC_8_BIT
0 32 48 8 0 1 2 3 4 5 6 7 0x80 0x40
O valor de overflow pode ser calculado com a seguinte fórmula:
Tempo de overflow = 4*Prescaler*(Tmax - TMR0) / Clock
(Equação. 1)
Onde: Clock é o valor do cristal da placa (No caso do Acepic é 8 MHz) Prescaler é o valor para divisão do clock {1, 2, 4, 8, 16, 32, 64, 128, 256} Tmax é o valor final de contagem: 256 para 8 bits e 65536 para 16 bits TMR0 é o valor de inicio de contagem (qdo 16 bits, utiliza-se 2 registradores TMR0L e TMR0H)
2 – Situação 1: overflow com valor exato (TRM0 = 0)
Na figura 3 é apresentada a tela que aparece no PIC CCS para escolha do overflow do timer0. Optando-se por um dos divisores da direita ou prescaler, e escolhendo
contagem com 8 ou 16 bits, pode-se obter até 16 valores diferentes para overflow. Neste caso, valores exatos.
Figura 3 – Tela de escolha do valor de overflow em Timer0
Exemplo: Overflow de 4mS com clock de 8 MHz para o PICF4520. Tempo de Instrução (Ti): clock / 4 = 2 MHz Logo Ti = 1/2M = 0,5 uS Prescaler 1 : 256 Prescaler 1 : 128 Prescaler 1 : 64 Prescaler 1 : 32 Prescaler 1 : 16 Prescaler 1 : 8 Prescaler 1 : 4 Prescaler 1 : 2 Prescaler 1 : 1
0.5 * 256 0.5 * 128 0.5 * 64 0.5 * 32 0.5 * 16 0.5 * 8 0.5 * 32 0.5 * 2 0.5 * 1
= 128 uS = 64 uS = 32 uS = 16 uS = 8 uS = 4 uS = 2 uS = 1 uS = 0,5 uS
Da equação1: Para: clock = 8 MHz / Prescaler = 32 / Tmax = 256 (8 bits) / TMR0 = 0; Tempo de overflow = 4*32*(256 - 0) / 8M = 4,096 mS
No compilador são gerados os seguintes códigos, correspondentes aos timers da Figura 3: setup_wdt(WDT_OFF); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32|RTCC_8_bit); // 0x00 || 0x04 || 0x40 setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1);
Também é gerada pela interface, na aba de interrupções e escolhendo Timer0, a função correspondente às habilitações de interrupções: global e do timer0: ENABLE_INTERRUPTS(GLOBAL | INT_TIMER0)
3 – Situação 2: overflow com valor não exato (TRM0 ≠ 0) ou com casas decimais
Neste é necessário o cálculo do inicial de contagem (TRM0). Para exemplificar vamos supor um overflow de 3 mS. Neste caso devemos verificar qual seria o valor acima de overflow mais próximo e pegar os valores do prescaler e verificar e 8 ou 16 bits. Em seguida substituir estes valores na equação 1, para calcular-se o valor de início de contagem. No caso de 3 mS, temos o valor de 4 ms, que tem Prescaler 32 com contagem de 8 bits Utilizando a equação 1: Adotaremos: Prescaler =32 e contagem com 8 bits em timer0 3m = 4*32*(256 - TMR0) / 8M TMR0 = 69 = 0x45 Testando o resultado: overflow = 4*32*(256 – 69)/8M = 2,99 mS No programa deve ser acrescentado, além das funções mencionadas anteriormente a função abaixo para estabelecer o valor de início de contagem (TMR0). Esta mesma
função também deve ser acrescentada na última linha da rotina de atendimento a interrupção: SET_TIMER0(69);
// programa principal
SET_TIMER0( 69 - get_timer0() ); // na última linha da rotina de atendimento a interrupção
Na situação 2, o valor incial de contagem é 0. Não havendo necessidade deste comando na rotina de atendimento a interrupção. Junto a este arquivos tem um exemplo de implementação (timer0_31ms.c)
4 – Situação 3: overflow com valor múltiplo de outros valores de overflow
Neste caso utilizam-se os códigos provenientes do overflow conhecido e uma variável na rotina de atendimento a interrupção, para contagem de estouros. Por exemplo: overflow de 24ms Neste caso, utiliza-se um overflow de 4 mS e a cada estouro uma variável é incrementada até atingir 6 estouros e quando a variável é novamente inicializada e quando é executada as rotinas decorrentes do overflow de 24 mS.
TIMER1
O Timer1 possui as seguintes características:
Contagem ou timer apenas de 16 bits com prescaler; O Timer1 é projetado para uso de cristais externos de baixas frequências (32KHz), permitindo sua utilização para relógios de precisão ou RTC, com adição mínima de componentes; Possui operação assíncrona, permitindo que o timer permaneça operando quando o chip se encontre em modo de baixo consumo; Tem 2 registradores para valor inicial: TMR1L e TMR1H; Possui modos de leitura/escrita de 8 e 16 bits; Prescaler ou divisão de clock de: 1, 2, 4 e 8; Tem também T1CON para configuração e TMR1IF para indicar estouro; Possibilidade de operar com módulo de contagem programável, quando utilizado em conjunto com um dos módulos CCP.
Os registradores associados a TIMER0 e TIMER1 são apresentados na Figura 4.
Figura 4 – Registradores associados a Timer0 e Timer1
Na Figura 5 está ilustrado o funcionamento do timer1. O bit TMR1CS seleciona a fonte de clock: 0 para modo interno e 1 para clock externo, proveniente de um oscilador no pino RC0 / T1CK1. O registrador T1CON é detalhado em seguida.
Figura 5 – Diagrama de blocos do Timer1
Registrador T1CON: TIMER1 CONTROL REGISTER TMR1ON (Liga o timer) TMR1CS: Timer1 Clock Source Select bit T1SYNC: Timer1 External Clock Input Synchronization Select bit T1OSCEN: Timer1 Oscillator Enable bit
T1CKPS<1:0>: Timer1 Prescale Select bits
Input
Clock
T1RUN: Timer1 System Clock Status bit RD16: 16-Bit Read/Write Mode Enable bit
1: habilita ou dispara o timer1 0:desabilita 1: Clock externo no pino RC0 (ativo na subida sinal) 0: Clock interno (clock / 4) 1: não sincroniza entrada de clock externa com clock interno 0: sincroniza clock externo com clock/4 1: habilita oscilador do timer1 – RC0 é saída do oscilador e RC1 entrada do oscilador 0: desligado Prescaler ={1, 2, 4 e 8} 0 0 1:1 10 1:4 0 1 1:2 11 1:8 1: clock do timer1 0: clock de outra fonte 1: habilita leitura e escrita em modo de 16 bits 0: idem, em modo de 8 bits
É possível escrever e ler o valor da contagem de duas formas: 8 e 16 bits.
Acesso em 8 bits para timer1 para leitura e escrita
Quando RD16=0, o timer1 operam em modo de leitura/escrita de 8 bits. Neste modo os registradores de inicio de contagem TMR1L e TMR1H são lidos / escritos separadamente e cada um reflete diretamente o estado da metade do contador time. A cada transbordo de TMR1L é incrementado 1 ao registrador TMR1H. A única vantagem deste modo é poder alterar a parte alta da contagem sem a necessidade de alterar a parte baixa. Muito útil na implementação de relógios. A
desvantagem é a possibilidade de transbordo dos registradores durante a leitura de uma das partes, o que pode ocasionar erros de leitura ou escrita. Isto pode ser evitado parando a contagem durante a leitura ou utilizando de uma rotina específica para evitar o erro.
Acesso em 16 bits para timer1
Quando RD16=1, o timer1 opera em modo de leitura/escrita de 16 bits. Este modo não é recomendado para utilização com clock externo assíncrono. Ao utilizar o clock externo, temos a opção de utilizar o oscilador integrado do timer1, controlado pelo bit T1OSCEN. Quando T1OSCEN=1, o pino RC0 passa a operar como T1OSO ou saída de oscilador e o pino RC1 como T1OSI (entrada de oscilador). Neste caso os bits 0 e 1 do TRISC permanecem em zero. Na figura 6 encontra-se ilustrada a conexão de um cristal de precisão de 32.768 KHz aos pinos do oscilador do timer1. Esta configuração é utilizada para relógios de precisão. Uma vez ativado, o oscilador do timer1 pode operar mesmo durante os modos de baixo consumo de energia e pode também funcionar como fonte de clock (oscilador secundário) para o restante do sistema. Caso o oscilador não seja utilizado, um sinal de clock pode ser fornecido externamente através do pino RC0. Este sinal pode ser utilizado como fonte de clock externo tanto para o timer1 quanto para o timer3. Da mesma forma que o timer0 em modo 16 bits, uma vez disparado a contagem, ao atingir 65535 é setado o flag TMR1IF (agora, no registrador PIR1), podendo gerar uma interrupção, caso esteja habilitado o flag TMR1IE (do registrador PIE1) e o flag de interrupção global GIE, no registrador INTCON. Podemos utilizar a mesma fórmula para cálculo de overflow do timer0 em 16 bits.
Figura 6 – Oscilador do timer1 (oscilador secundário)
TIMER2
O timer2 é um temporizador de 8 bits com operação bem diferente dos demais. Este timer foi projetado para viabilizar a geração de sinais PWM em conjunto com os módulos CCP e opcionalmente pode funcionar como clock para o módulo MSSP (quando opera no modo SPI), além de poder também ser utilizado como temporizador para uso geral. Na Figura 7 estão ilustrados os registradores que o timer2 trabalha.
Figura 7 - Registradores que o timer2 trabalha No timer2 o temporizador é programável. O contador inicia em zero e conta até um valor programado (não necessariamente 0xFF) no registrador de períodos ( PR2). Esta característica é extremamente útil, pois torna desnecessário todo o trabalho de recarga da contagem por software. A Figura 8 apresenta o diagrama de blocos do timer1.
Figura 8 – Diagrama de blocos do timer2
O timer2 opera apenas com clock interno (clock/4) e prescaler de 1, 2, 4 e 8. Também com um poscaler que pode ser utilizado para retardar a geração do sinal de interrupção. Os fatores de poscaler podem ser 1, 2, 3, 4, 5, ...,16, conforme configuração do registrador T2CON.
Registrador T2CON (reset = 0x00) T2CKPS1: T2CKPS0 TMR2ON T2OUTPS3: , :, : T2OUTPS0
Configuração do prescaler do timer2 00 1:1 01 1:4 10 1:16 11 1:16 1: timer2 contando 0: timer2 parado Poscaler do timer2 0000 1:1 0001 1:2 0010 0100 1:5 0101 1:6 0110 1000 1:9 1001 1:10 1010 1100 1:13 1101 1:14 1110
1:3 0011 1:4 1:7 0111 1:8 1:11 1011 1:12 1:15 1111 1:16
x
Bit 7
FTMRINT = ( clock ) / ( 4*Prescaler * (PR2 + 1) * Poscaler )
Onde: FTMRINT clock PR2
.. Frequência de interrupção (overflow) .. Clock do sistema .. Valor de fim da contagem
TIMER3
O Timer3 possui as seguintes características:
Funcionamento semelhante ao timer1, diferenciando-se apenas pelo fato de não possuir um oscilador dedicado. Entretanto pode compartilhar o mesmo oscilador dedicado do timer1; Contagem ou timer apenas de 16 bits com prescaler 1, 2, 4 e 8; O registrador de controle do timer3 é o T3CON. Não possui bits relacionados ao controle e status do oscilador, mas inclui 2 bits para seleção da conexão entre timer1 e timer3 e os módulos CCP 1 e 2. Estes bits (T3CCP2 e T3CCP1) permitem selecionar o timer que é utilizado como base de tempo para cada módulo CCP.
Registrador T3CON (reset = 0x00) RD16
(8 ou 16 bits)
T3CCP2 : T3CCP1
Conexão dos timer 1 e 3 aos CCP T3CKPS1:T3CKPS0: : Prescaler
sincronização do timer1 com clock sistema (p/ TMR3CS=1) TMR3CS: fonte do clock TMR3ON: habita timer3
1: 16 bits 0:8 bits 00 timer1 com CCP1 e CCP2 01 timer1 com CCP1 e timer3 com CCP2 10 timer3 com CCP1 e CCP2 11 timer3 com CCP1 e CCP2 00 1:1 01 1:2 10 1:4 11 1:8 1: não sincroniza (modo assíncrono) 0: sincroniza 1 clock externo (oscilador do timer1 ou em RC0) 0 clock interno (clok / 4) 1: liga ou dispara 0: para contagem