Beruflich Dokumente
Kultur Dokumente
PIC - Microchip
Introdução
A partir do registro do TMR0 é possível produzir bases de tempo bastante precisas (dependendo do tipo de
oscilador empregado), elaborar contagens com pré-determinação e outras aplicações que dependem apenas da
imaginação do programador.
Princípio de Funcionamento
- registro de 8 bits, permite contagens de 0 até 255 (ou até 256 incrementos).
- opera como temporizador (clock interno) ou contador (clock externo ou fonte de sinal para contagem),
selecionável por meio do código_fonte.
- registro permite leitura (verifica o valor dentro do registro e comparação com outro valor) e escrita (é
possível iniciar a contagem a partir de qualquer valor entre 0 e 255, isto é, o registro conta o restante dos
incrementos disponíveis).
- seleção da transição (positiva ou negativa) no modo contador externo.
- prescaler programável pelo código_fonte controlando a velocidade que o registro incrementa uma
unidade.
- requisição de interrupção quando o valor do registro exceder 255 (FFh) e retornar para 0 (00h) - overflow
- utilizável ou não através de alteração dos bits correspondentes ao controle de interrupções no registro
INTCON durante a execução do código_fonte.
Diagrama de Blocos
A fonte de incrementos do TMR0 pode ser selecionada a partir da chave T0CS entre fonte interna (Fosc/4), ou
fonte externa (T0CKI pin - normalmente multiplexado com outras funções). A forma como o TMR0 vai
incrementar pela fonte externa pode ser selecionada a partir do nível lógico de T0SE (para incrementar no
flanco de subida ou descida do sinal externo). A velocidade que o TMR0 incrementa pode ser determinada pelo
uso de um divisor de frequencia (Programmable Prescaler), cuja divisão pode ser determinada por PS2, PS1 e
PS0. A utilização do Prescaler pode ser selecionada pela chave PSA. O sinal de saída do Prescaler (Psout) é
entregue a um circuito que se encarrega de sincronizar os pulsos com os sistemas internos (Sync with internal
Bento Alves Cerqueira Cesar Filho - R 1.0 - FEV/08
2/21
clocks) do processador para o caso de o valor contido no registro TMR0 seja modificado pelo código_fonte
(Data bus). A conexão do registro com o Data-Bus permite que os valores contidos sejam lidos ou escritos
através do código_fonte e, ao mesmo tempo, quando houver “overflow”, ocorre o desvio para o vetor de
interrupção (quando habilitado), colocando 1 (um - set) automáticamente no bit T0IF (Set interrupt flag bit T0IF
on overflow).
Configuração
A configuração de uso do TMR0 é feita a partir dos bits de controle existentes nos dois registros especiais:
OPTION: permite estabelecer a origem do sinal de contagem, a forma de incremento e com qual
velocidade o registro será incrementado (Prescaler).
INTCON: permite utilizar o recurso da interrupção sempre que o registro TMR0 retornar a zero (0) -
overflow.
O endereço e a descrição da função dos bits de configuração estão detalhados (realçado) abaixo:
000
1:2
1:1
001
1:4
1:2
010
1:8
1:4
011
1:16
1:8
100
1:32
1:16
101
1:64
1:32
110
1:128
1:64
111
1:256
1:128
Os bits são do tipo Leitura/Escrita (R/W – Read/Write) e podem ser modificados durante a execução do
código_fonte (on-the-fly) de acordo com as necessidades de uso e operação dos recursos disponíveis.
T0CS (TMR0 Clock Source): Seleção da fonte de sinal de incremento para o TMR0 – bit 5
Este bit permite selecionar a fonte de sinal que o registro TMR0 utiliza como incremento, de acordo com as
duas opções:
T0CS = 1 → a origem do sinal de incremento é a transição do nível lógico no pino externo RA4/T0CKI
- o TMR0 funciona como um contador. Nesta opção as funções I/Odo bit RA4 e CMP1
do comparador ficam desligadas.
T0CS = 0 → a origem do sinal de incremento é o ciclo de máquina (CM) interno - o TMR0 funciona
como um temporizador (timer), que depende da frequencia do oscilador escolhido (Fosc)
pelo projeto. Nesta opção as funções I/Odo bit RA4 e CMP1 do comparador estão ativas.
A fig.2 mostra o diagrama lógico do circuito de seleção da fonte do sinal de incremento dot TMR0,
onde o bit T0CS aciona a chave seletora entre o sinal externo (entrada RA4) e o sinal interno (Fosc). A
fig.3 mostra um exemplo da localização física da entrada RA4 – pino 3 do microcontrolador modelo
P16F628A, encapsulamento PDIP (plastic, dual in line, 18 pins). O projetista deve consultar a folha de
dados (data sheet) do dispositivo escolhido antes da aplicação.
Fig.2 – Circuito Lógico Fonte de Sinal Fig.3 – Pino RA4/T0CKI no modelo P16F628A
O projetista pode empregar as duas fontes (interna ou externa) de acordo com a necessidade de
aplicação mudando os valores do bit T0CS por meio do código_fonte. Observar que não é possível o
uso simultaneo das duas opções.
T0SE (TMR0 Source Edge): Seleção da transição do sinal de incremento para o TMR0 – bit 4
O projetista pode selecionar com qual tipo de transição do sinal de entrada externo que o TMR0 realiza um
incremento de contagem, de acordo com as opções:
O projetista pode empregar as duas transições (negativa ou positiva) de acordo com a necessidade de aplicação
mudando os valores do bit T0SE por meio do código_fonte. Para que não ocorram erros de execução do
código_fonte, as instruções das duas transições devem ser separadas por um período de tempo não menor que
10 CM, suficiente para que a ALU atualize os valores internos dos registros. Portanto, a frequencia do sinal de
entrada determina a possibilidade de uso das instruções encadeadas. Observar que não é possível o uso
simultaneo das duas opções.
O Pre Scaler é um registro divisor de frequencia cuja função é diminuir a velocidade de incrementos do registro
TMR0. Como pode ser visto no diagrama lógico da fig.6, a chave seletora PSA determina o emprego do divisor
do Pre Scaler.
CM
0 t
1 CM
TMR0
0 t
1 INCREMENTO
SELEÇÃO
PS2 PS1 PS0 TMR0 Incremento do TMR0
0 0 0 1:2 Incrementa após 2 pulsos externos ou 2CM
0 0 1 1:4 Incrementa após 4 pulsos externos ou 4CM
0 1 0 1:8 Incrementa após 8 pulsos externos ou 8CM
0 1 1 1:16 Incrementa após 16 pulsos externos ou 16CM
1 0 0 1:32 Incrementa após 32 pulsos externos ou 32CM
1 0 1 1:64 Incrementa após 64 pulsos externos ou 64CM
1 1 0 1:128 Incrementa após 128 pulsos externos ou 128CM
1 1 1 1:256 Incrementa após 256 pulsos externos ou 256CM
CM
0 t
4 CM
TMR0
0 t
1 INCREMENTO
A análise do mecanismo de contagem do registro pode ser feita a partir de dois exemplos práticos indicando o
comportamento dos valores contidos no registro.
Primeiro Exemplo: incremento do valor contido no registro é feito a cada 1CM - Prescaler 1:1.
1 0 0 0 1 0 0 0
A fig.9 mostra o diagrama de tempo da operação do registro TMR0 de acordo com esta configuração:
Primeira linha: mostra os ciclos de pipeline Q1, Q2, Q3 e Q4 - o intervalo de tempo de cada ciclo depende da
frequencia do oscilador interno ou externo.
Segunda linha: mostra a posição do registro PC (Program Counter), iniciando em PC-1 (o valor de PC menos a
unidade) até PC+6, totalizando 6 CM - o valor do registro PC é atualizado sempre no final do ciclo Q4.
Terceira linha: mostra o conjunto de instruções para colocar um novo valor dentro do registro TMR0 e sua
leitura conforme o código-fonte abaixo - a instrução é executada sempre no final do ciclo Q1:
1 0 0 0 0 0 0 0
A fig.10 mostra o diagrama de tempo da operação do registro TMR0 de acordo com esta configuração:
Primeira linha: mostra os ciclos de pipeline Q1, Q2, Q3 e Q4 - o intervalo de tempo de cada ciclo depende da
frequencia do oscilador interno ou externo.
Segunda linha: mostra a posição do registro PC (Program Counter), iniciando em PC-1 (o valor de PC menos a
unidade) até PC+6, totalizando 6 CM - o valor do registro PC é atualizado sempre no final do ciclo Q4.
Terceira linha: mostra o conjunto de instruções para colocar um novo valor dentro do registro TMR0 e sua
leitura conforme o código-fonte abaixo - a instrução é executada sempre no final do ciclo Q1:
Quarta linha: mostra o valor contido no registro TMR0 - atualizado sempre no final do ciclo Q3:
1 - o valor contido no TMR0 pode ser modificado pelo código_fonte a qualquer momento - o programador
pode colocar qualquer valor (entre 0 e 255) no TMR0 - o registro incrementa a partir deste novo valor
de acordo com as configurações feitas.
2 - existe um atraso (latency - latencia) entre o ciclo em que o registro TMR0 é modificado pelo
código_fonte e o início dos incrementos a partir do CM. De acordo com a fig.9 e fig.10, o atraso é
equivalente ao ajuste do divisor do Prescaler (bits PS2:PS0) e igual a 2 x PSA (duas vezes o divisor
PSA), ou seja:
PSA ATRASO (CM)
1:1 2
1:2 4
1:4 8
1:8 16
1:16 32
1:32 64
1:64 128
1:128 256
1:256 512
O programador deve ficar atento a este atraso que afeta contagens de tempo ou eventos - se o atraso
provocar erros de contagem, o código_fonte deve conter os ajustes necessários para prevenção do
atraso.
3 - o valor contido no TMR0 pode ser lido e transferido para o registro W, mas o programador deve levar
em conta a constante atualização do valor do TMR0 de acordo com o CM e a divisão do Prescaler
sempre que utilizar o valor encontrado no TMR0 para tomada de decisões.
O endereço e a descrição da função dos bits de configuração estão detalhados (realçado) abaixo:
Os bits são do tipo Leitura/Escrita (R/W – Read/Write) e podem ser modificados durante a execução do
código_fonte (on-the-fly) de acordo com as necessidades de uso e operação dos recursos disponíveis.
GIE (General Interrupt Enable): Chave Geral de Habilitação das Interrupções – bit 7
Este bit permite utilizar as interrupções (qualquer uma, desde que habilitada), de acordo com as duas opções:
GIE = 1 → o uso das interrupções está habilitado. A interrupção do TMR0 só será empregada se o bit
correspondente à habilitação do TMR0 (T0IE) estiver com valor 1 (um).
GIE = 0 → o uso das interrupções não está habilitado. A interrupção do TMR0 não será empregada
mesmo que o bit correspondente à habilitação do TMR0 (T0IE) esteja com valor 1 (um).
Este bit permite utilizar a interrupção do TMR0, desviando o código_fonte da posição que se encontrar na
memória de programa sempre que o registro retornar a zero, para o Vetor de Interrupção (endereço da memória
de programa 0x04), de acordo com as duas opções:
T0IE = 1 → o uso da interrupção do TMR0 está habilitado. A interrupção do TMR0 só será empregada
se o bit correspondente à habilitação geral (GIE) estiver com valor 1 (um).
T0IE = 0 → o uso da interrupção do TMR0 não está habilitado. A interrupção do TMR0 não será
empregada mesmo que o bit correspondente à habilitação geral (GIE) esteja com valor 1
(um).
Este bit sinaliza a ocorrencia ou não da interrupção do TMR0, de acordo com as duas opções:
T0IF = 1 → sinaliza que a interrupção do TMR0 foi requisitada indicando que o registro retornou a
zero e o código_fonte foi desviado da posição que se encontra na memória de programa
para o Vetor de Interrupção (endereço 0x04),
T0IF = 0 → sinaliza que a interrupção do TMR0 não foi requisitada. O registro TMR0 ainda não
retornou a zero.
O bit T0IF é automaticamente colocado no valor 1 (um) - “setado” - pela Unidade Lógica-Aritmética (ULA)
quando o registro TMR0 retorna a zero (overflow).
NOTA: É possível “forçar” uma requisição de interrupção colocando o valor 1 (um) no bit T0IF, obrigando o desvio automático para o
endereço do Vetor de Interrupção (endereço 0x04 da Memória de Programa). Pode ser bastante útil durante a realização de um
programa para iniciar ou reiniciar um contador ou temporizador.
O retorno a 0 (zero) do bit T0IF deve ser feito pelo manualmente pelo código_fonte, principalmente antes de
sair de uma rotina de tratamento de interrupção (antes da execução da instrução RETFIE), caso contrário a ULA
considera a existencia de uma IRQ (requisição de interrupção) pendente e provoca novo desvio para o Vetor de
Interrupção.
O uso da interrupção por excesso (overflow) do registro TMR0 depende da configuração dos bits
correspondentes no registro INTCON. Como o registro é acessível pelo código_fonte, é possível modificá-lo
sempre que necessário durante a execução do programa.
O uso da interrupção exige alguma atenção por parte do programador, uma vez que o simples excesso do TMR0
não acarreta a chamada da interrupção de forma imediata (desde que devidamente configurada).
Para análise da forma como a interrupção é requisitada, vamos fazer a execução de um exemplo com o arranjo
do registro INTCON abaixo:
1 0 1 0 0 0 0 0
Nestas condições:
1 0 0 0 1 0 0 0
Primeira linha: mostra os ciclos de pipeline Q1, Q2, Q3 e Q4 - o intervalo de tempo de cada ciclo depende da
frequencia do oscilador interno ou externo.
Terceira linha: valor contido no registro TMR0, iniciando com o valor 254 (FEh).
Sétima linha: Program Counter (PC) - Contador do Programa - endereço na memória de programa onde a
instrução é extraída da memória (instruction fetched) e executada (instruction executed).
A análise da requisição da interrupção por excesso (overflow) do registro TMR0 pode ser feita, passo a passo,
de acordo com a descrição abaixo:
Execução de Instrução:
- busca da instrução Inst(PC) no endereço PC da memória de
programa (Instruction fetched).
- execução da instrução Inst(PC-1) (Instruction executed).
PC Transição posição de Memória PC → PC+1:
↓ - o registro TMR0 mantém o valor 255 (FFh).
PC+1 - o bit de flag T0IF muda de estado de 0 → 1 no final do ciclo Q4
indicando que o TMR0 atingiu o valor limite (overflow) - aqui
inicia o processo do desvio para tratamento da interrupção.
- o bit de controle GIE permanece igual a 1 (uso das interrupções
habilitado)
- contador de programa avança de PC → PC+1
Bento Alves Cerqueira Cesar Filho - R 1.0 - FEV/08
19/21
Observação:
- com a mudança de estado do bit T0IF de 0 → 1, o processo de
desvio para o Vetor de Interrupção é iniciado, desde que o bit de
GIE esteja habilitado (igual a 1).
Execução de Instrução:
- busca da instrução Inst(PC+1) no endereço PC+1 da memória de
programa (Instruction fetched).
- execução da instrução Inst(PC) (Instruction executed).
Transição posição de Memória PC+1 → PC+1 (Dummy Cycle -
PC+1 Ciclo Perdido):
↓ - o registro TMR0 mantém o valor 0 (00h).
PC+1 - o bit de flag T0IF permanece no estado 1 no início do ciclo Q1.
(Dummy - o bit de controle GIE permanece igual a 1 (uso das interrupções
Cycle) habilitado)
- contador de programa permanece igual a PC+1
Posição de Memória PC+1 (Dummy Cycle - Ciclo Perdido):
- o registro TMR0 contém o valor 0 (00h) até o final do ciclo Q3,
quando é atualizado para o valor 1 (01h)
- o bit de flag T0IF permanece no estado 1 no início do ciclo Q1.
- o bit de controle GIE muda de estado 1 → 0 (uso das interrupções
não habilitado) para impedir que a ocorrencia de qualquer outra
interrupção provoque novo desvio de endereço.
PC+1
(Dummy Execução de Instrução:
Cycle) - nenhuma instrução é buscada na memória ou executada - o ciclo é
perdido.
Observação:
- neste ciclo o valor PC+1 é armazenado no Stack para retorno a esta
posição quando ocorrer a execução da instrução RETFIE - o desvio
é realizado pela ALU.
Execução de Instrução:
- busca da instrução Inst(0005h) no endereço 0005h da memória de
programa (Instruction fetched).
- execução da instrução Inst(0004h) (Instruction executed).
O processo de desvio para o Vetor de Interrupção (endereço 0004h da memória de programa) é iniciado quando
o valor do registro TMR0 é igual a 255 (FFh) e a ALU altera o valor do flag T0IF de 0 → 1, indicando a
ocorrencia de requisição de interrupção. No ciclo seguinte a ALU não executa nenhuma operação (Dummy
Cicle - Ciclo Perdido) enquanto a ALU armazena o valor do PC (Program Counter) no Stack para retorno
posterior (execução da instrução RETFIE). No ciclo seguinte, a instrução armazenada no endereço 0004h é
chamada da memória e executada no ciclo 0005h - que deve ser a primeira instrução para o tratamento da
requisição de interrupção.