Microcontroladores PIC Interrupções e Timers 1
Sumário Interrupções Timers e Contadores Contagem do Tempo no PIC Exercícios 2
Interrupções na Linguagem C do PIC Dependem do Compilador. Duas formas para o tratamento de interrupções no compilador PCHW da CCS: Automática: O compilador gera todo o código do tratamento da interrupção (flags, configuração de registradores, contexto, etc.) A única tarefa do programador é a construção das funções de tratamento dos eventos individuais de cada interrupção. Manual: O programador deverá se incumbir de tudo: verificar flags de interrupção, chamadas específicas para tratamento de cada evento, configuraçào dos registradores, salvar e recuperar contexto, etc. 3
Interrupções na Linguagem C do PIC Interrupção Automática Vantagens: Simplicidade Desvantagens: Gera programas maiores. Gera tempo extra no tratamento das interrupções, ou seja, o tempo entre a ocorrência do evento de interrupção propriamente dito e o tratamento da mesma. Uso: Aplicações simples onde o tempo não é um fator crítico. Interrupção Manual Vantagens: Adequado quando a aplicação demanda precisão de contagem. Desvantagens: Gera programas menores. Mais trabalho para o programador. (contexto, flags, registradores, etc.) Uso: Aplicações de tempo real e/ou onde pequenos atrasos são indesejáveis. Observação!! Demanda inclusão de código assembler (diretiva específica) 4
Priorização de Interrupções na Linguagem C do PIC Automática: Através da diretiva: #priority Exemplo: #priority timer1, timer0 Nesse exemplo a interrupção timer1 tem prioridade sobre a de timer0 Manual: Fica a cargo do programador. A ordem de tratamento que ele definir dita a ordem de prioridade. 5
Funções do Compilador C usadas no uso de Interrupções Enable_interrupts (valor) Habilita uma interrupção, segundo uma constante (arquivo header). Exemplo: enable_interrupts (GLOBAL INT_TIMER0); Disable_interrupts (valor) Desabilita uma interrupção, segundo uma constante (arquivo header). /// INT // Interrupt Functions: // ENABLE_INTERRUPTS(), DISABLE_INTERRUPTS(), EXT_INT_EDGE() // Constants used in EXT_INT_EDGE() are: #define L_TO_H 0x40 #define H_TO_L 0 // Constants used in ENABLE/DISABLE_INTERRUPTS() are: #define GLOBAL 0x0BC0 #define INT_RTCC 0x0B20 #define INT_RB 0x0B08 #define INT_EXT 0x0B10 #define INT_AD 0x8C40 #define INT_TBE 0x8C10 #define INT_RDA 0x8C20 #define INT_TIMER1 0x8C01 #define INT_TIMER2 0x8C02 #define INT_CCP1 0x8C04 #define INT_CCP2 0x8D01 #define INT_SSP 0x8C08 #define INT_PSP 0x8C80 #define INT_BUSCOL 0x8D08 #define INT_EEPROM 0x8D10 #define INT_TIMER0 0x0B20 6
TIMERS do PIC 16F877A Timers contam tempo. Contadores contam eventos. Esse PIC tem 3 timers/contadores com características diferentes de funcionamento: TIMER 0; TIMER 1 e TIMER 2. O que varia de um para o outro? Limite de contagem; Modo de operação (como contador/timer); Tipo de incremento; Prescales e Postscales; A geração de interrupções; Os periféricos a eles associados. 7
Contagem do Tempo no PIC 16F877A TIMER 0 (registrador TMR0) Temporizador e Contador de 8 bits. Pode ser lido e escrito, ou seja, permite ser inicializado. Funcionamento: Incremental (somente). Incremento de 2 formas distintas (OPTION_REG<TOCS>): Contador: A cada transição do pino RA4 (TOCKI: pulso de clock externo). Timer: A cada ciclo de máquina. TMR0 muda de estado, segundo o valor do Prescaler (PS). Prescaler é um registrador que permite um recurso de contagem além do limite do registrador do timer TMR0. Ex.: PS configurado como 1:4. São necessários 4 ciclos de máquinas ou 4 pulsos externos, para que o TMR seja incrementado de 1 unidade. O PS é de 8 bits, mas não está disponível para leitura nem escrita! Toda vez que se escreve em TMR0, PS é zerado! 8
Contagem do Tempo no PIC 16F877A TIMER 0 (continuação) Para a utilização do PS em TMR0: 1. Configurar OPTION_REG<PSA>: PSA = 1: Prescale aplicado ao WDT (Watch Dog Timer). PSA = 0; Prescale aplicado ao TMR0. 5. Configurar o valor do PS em OPTION_REG<PS2 PS0> Qual a forma de incrementarmos o TMR0 com uma relação 1:1? 9
Contagem do Tempo no PIC 16F877A TIMER 0 (continuação) Registradores associados ao Timer 0 10
Contagem do Tempo no PIC 16F877A Exemplo: Configurar o TMR0 (8 bits) para que gere interrupções a cada 1 segundo. Vamos considerar que o CLK da CPU = 4 MHz. O clock interno será de 1 MHz. Logo, Tcpu = 1 us, ou seja, a cada 1us TMR0 avança uma unidade. Como queremos gerar interrupções a cada 1 segundo, a freqüência de geração dessas interrupções deverá ser de 1 Hz. Entretanto o clock interno funciona em uma freqüência 1.000.000 maior que 1Hz. Usar o TMR0 sem o recurso do PRESCALER, necessitaria contar 1.000.000 / 256 = 3906,25 interrupções. 11
Contagem do Tempo no PIC 16F877A Exemplo: Configurar o TMR0 (8 bits) para que gere interrupções a cada 1 segundo (1 Hz). Vamos considerar que o CLK da CPU = 4 MHz. Logo o CLK interno é de 1 MHz. Se o PRESCALER estiver programado em 1:64, a freqüência de entrada no TMR0 será de 1 MHz : 64 = 15625 Hz. setup_timer0 (RTCC_INTERNAL RTCC_DIV_64); Se programarmos o TMR0 para dividir esse sinal 15625 por 125, teremos um sinal de saída de 125 Hz,, para isso, basta carregá-lo a cada estouro de contagem com o valor: Dessa forma após 256 (2 8 ) 125 = 131. 125 interrupções, set_timer0 (131); 1s terá passado. 12
Funções do Compilador C usadas no uso de TIMERS setup_timer (modo) Configura um TIMER de acordo com o modo (variáveis no header) set_timer (modo) Modifica o conteúdo de um TIMER interno. get_timer () Lê o conteúdo de um TIMER (registrador). // Timer 0 // Timer 0 (AKA RTCC)Functions: // SETUP_COUNTERS() or SETUP_TIMER_0(), // SET_TIMER0() or SET_RTCC(), // GET_TIMER0() or GET_RTCC() // Constants used for SETUP_TIMER_0() are: #define RTCC_INTERNAL 0 #define RTCC_EXT_L_TO_H 32 #define RTCC_EXT_H_TO_L 48 #define RTCC_DIV_1 8 #define RTCC_DIV_2 0 #define RTCC_DIV_4 1 #define RTCC_DIV_8 2 #define RTCC_DIV_16 3 #define RTCC_DIV_32 4 #define RTCC_DIV_64 5 #define RTCC_DIV_128 6 #define RTCC_DIV_256 7 13
Contagem do Tempo no PIC 16F877A Exemplo: Configurar o TMR0 para que gere interrupções a cada 1 segundo. Após 125 estouros do TMR0 (125 interrupções), teremos chegado ao tempo de 1 segundo (1Hz). #include <16F877A.h> #use delay(clock=4000000) #fuses HS,NOWDT,PUT,NOLVP #int_timer0 void trata_tmr0 () { static boolean LED; static int contador; set_timer0(131 + get_timer0()); contador++; if(contador == 125) { contador = 0; LED =!LED; output_bit(pin_b0, LED); } } void main() { // configura o TMR0 para clock interno e prescaler dividindo por 64 setup_timer_0 (RTCC_INTERNAL RTCC_DIV_64); set_timer0 (131); // inicia o timer 0 em 131 // habilita interrupções enable_interrupts (global int_timer0); while (true); // espera pela interrupção } 14
Contagem do Tempo no PIC 16F877A TIMER 1 (TMR1H e TMR1L) Temporizador e Contador de 16 bits. Podem ser lidos e escritos pelo programador. Origem do sinal: interno ou externo. Para operar com sinais externos (T1CON<TMR1CS=1>): Cristal nos pinos RC0 (T1OSO) e RC1 (T1OSI). Sinal pulsado no pino RC0 (T1CKI). Para operar com sinais internos (T1CON<TMR1CS=0>): Incremento interno através dos ciclos de máquina. Possuí um Prescaler para configurar o incremento. T1CON<T1CKPS1:T1CKPS0> 15
Contagem do Tempo no PIC 16F877A TIMER 1 (continuação) Possuí um sincronismo do CLK externo com o CLK interno T1CON<T1SYNC>. T1SYNC = 1 (sincronismo desligado); T1SYNC = 0 (sincronismo ligado). Quando o sincronismo esta desligado, permite que a contagem continue mesmo que o PIC esteja em modo SLEEP. Para ler os registradores do TIMER1 (TMR1H e TMR1L): Modo convencional: pare a contagem e leia. Modo alternativo: leia TMR1H, guarde em uma variável temporária, depois leia TMR1L. Depois da leitura de TMR1L compare TMR1H com o valor da variável temporária. Caso afirmativo: OK. Caso negativo: faça isso novamente. A escrita reseta o Prescaler. 16
Contagem do Tempo no PIC 16F877A TIMER 1 (continuação) Registradores associados ao Timer 1 17
Contagem do Tempo no PIC 16F877A TIMER 2 (TMR2) Temporizador de 8 bits. Incremento somente relacionado com o CLK interno. Possuí um Prescale; Possuí um Postscale; Diferente dos 2 Timers anteriores: Não conta de 0 até 255. Conta do conteúdo do registrador PR2 até 255. O Postscale define o número de vezes que o TMR2 irá contar. O Postscale é incrementado sempre que TMR2 = PR2. Quando o Postscale terminar a INT referente ao Timer 2 será gerada. 18
Contagem do Tempo no PIC 16F877A TIMER 2 (continuação) O ajuste do Prescale é feito com T2CON. O ajuste do Postscale é feito com o T2CON. 19
Contagem do Tempo no PIC 16F877A TIMER 2 (continuação) O Prescaler e o Postscaler serão zerados: Quando escrever em TMR2; Quando escrever em T2CON; Quando houver um RESET (diferente dos outros Timers 1 e 0). Possuí chave específica para habilitar ou desabilitar o incremento T2CON<TMR2ON>. Registradores associados ao Timer 2. 20
Contagem do Tempo no PIC 16F877A Exercícios: Calcule o limite de contagem de cada um dos Timers do PIC16F877A, supondo que todos operem com o clock interno. Configure o TMR2 para contar eventos de 1 em 1 minuto. Faça o mesmo com o TMR1. Como você configuraria os timers do PIC16F877A para fazer uma contagem regressiva? 21
Constantes referentes ao uso do TIMER 1 e 2 Arquivo Header do 16F877A (16f877a.h) // Timer 1 // Timer 1 Functions: SETUP_TIMER_1, GET_TIMER1, SET_TIMER1 // Constants used for SETUP_TIMER_1() are: // (or (via ) together constants from each group) #define T1_DISABLED 0 #define T1_INTERNAL 0x85 #define T1_EXTERNAL 0x87 #define T1_EXTERNAL_SYNC 0x83 #define T1_CLK_OUT 8 #define T1_DIV_BY_1 0 #define T1_DIV_BY_2 0x10 #define T1_DIV_BY_4 0x20 #define T1_DIV_BY_8 0x30 ////////////////////////////////////////////////////////////////// Timer 2 // Timer 2 Functions: SETUP_TIMER_2, GET_TIMER2, SET_TIMER2 // Constants used for SETUP_TIMER_2() are: #define T2_DISABLED 0 #define T2_DIV_BY_1 4 #define T2_DIV_BY_4 5 #define T2_DIV_BY_16 6 22
Onde encontrar mais informações http://www.microchip.com Desbravando o PIC Editora Erica David José de Souza Conectando o PIC 16F877A Recursos Avançados Editora Erica David José de Souza e Nicholas C. Lavínia PIC Programação em C Fábio Pereira Editora Érica John Peatman s And corresponding excellent book http://www.picbook.com/index.html http://www.piclist.com http://www.geocities.com/picmaniaco/indice.html 23
Onde encontrar mais informações Design with PIC Microcontrollers by John B. Peatman, published by Prentice Hall, ISBN 0-13- 759259-0. "The C Programming Language - Second Edition", Brian W. Kernigan & Dennis M. Ritchie, Prentice Hall, 1988. Programming Embedded Systems, in C and C++, M. Barr, publ. byo Reilly, ISBN 1-56592-354-5 The Art of Electronics by P. Horowitz and W.Hill. Published by Cambridge University Press, ISBN 0-521-37095-7 24