54
Curso Online de Microcontroladores Pic Aluno: Kaylens Lee Jhonson Lira de Souza O curso para microcontroladores PIC em linguagem C tem como base o compilador MikroC da Mikroelektronika (www.mikroe.com) e nosso kit de desenvolvimento ACEPIC40 (pode ser adquirido em nossa loja virtual, www.acepiccamp.com.br)....

Curso Online de Microcontroladores Pic 1° SEMANA

Embed Size (px)

Citation preview

Page 1: Curso Online de Microcontroladores Pic 1° SEMANA

Curso Online de Microcontroladores Pic

Aluno: Kaylens Lee Jhonson Lira de Souza

O curso para microcontroladores PIC em linguagem C tem como base o compilador MikroC da Mikroelektronika (www.mikroe.com) e nosso kit de desenvolvimento ACEPIC40 (pode ser adquirido em nossa loja virtual, www.acepiccamp.com.br)....

Page 2: Curso Online de Microcontroladores Pic 1° SEMANA

26 janeiro - 1 fevereiro

UNIDADE 1

Introdução Recurso

O compilador MikroC Recurso

Criando um projeto Recurso

Nesta primeira parte serão explicados sobre tipos e modificadores de tipos de variáveis, variáveis, operadores e também alguns comandos básicos e bastantes utilizados na programação em linguagem C.

Introdução à linguagem C Recurso

Introdução à linguagem C - Continuação Recurso

Notação Numérica Recurso

Criaremos agora o nosso primeiro projeto, onde o código será escrito, compilado e gravado no microcontrolador.Podemos gravar o microcontrolador seguindo as instruções do arquivo "Instalação da ACEPIC 40.pdf", que se encontra no CD do curso.

Primeiro projeto Recurso

Compilando e gravando o projeto Recurso

Projeto de fixação Recurso

Responda as questões referentes ao assunto da primeira semana seguindo o link abaixoEste questionário é importante para que sua média seja formada e também é um feedback para que você avalie sua participação no cursoVocê pode acompanhar sua nota e as correções clicando no link "Nota" no menu "Administração" ao lado direito.

Questões - Semana 1 Tarefa 

Linguagem C

              É uma linguagem de programação de propósito geral, estruturada, imperativa, procedural de alto e baixo nível, criada em 1972 por Dennis Ritchie no AT&T Bell Labs, para desenvolver o sistema operacional UNIX (que foi originalmente escrito em Assembly). Desde então, espalhou-se por muitos outros sistemas e tornou-se uma das linguagens de programação mais usadas influenciando muitas outras linguagens, especialmente o C++, que foi

Page 3: Curso Online de Microcontroladores Pic 1° SEMANA

desenvolvida como uma extensão para C.

 Programação de Microcontroladores em linguagem C

              Atualmente, a maioria dos microcontroladores existentes nos mercado, contam com compiladores em C para o desenvolvimento de software, pois a linguagem C permite a construção de programas e aplicações muito mais complexas do que o Assembly.

            O compilador C tem a capacidade de “traduzir” com alto grau de inteligência e velocidade o código em C para o código de máquina, portanto podemos dizer que a linguagem C possui grande eficiência.

            Essa eficiência da linguagem C faz com que o programador preocupe-se mais com a programação em si e o compilador assume responsabilidades como localização da memória, operações matemáticas e lógicas, verificação de bancos de memórias e outros.. 

O Compilador MikroC 

O compilador MikroC foi desenvolvido pela Mikroelektronika e é com ele que vamos desenvolver nossos projetos. Segue no CD do curso uma cópia de demonstração do compilador MikroC e este  também pode ser baixado no site: www.mikroe.com.

Todos os exemplos do curso poderão ser feitos na cópia de demonstração, sendo que esta é liberada para programas com tamanho até 2K.

Abaixo está a tela inicial do compilador. 

Page 4: Curso Online de Microcontroladores Pic 1° SEMANA

Quando da instalação do compilador, na primeira vez que abrir o programa, a tela deverá estar como a da figura acima.

A Interface do compilador

Nós temos na interface do compilador MikroC o editor de código (Code Editor). É aqui que o código do projeto será escrito:

Page 5: Curso Online de Microcontroladores Pic 1° SEMANA

 

É possível modificarmos a cor do fundo do editor de código clicando no menu

em “Tools -> Options” ou clicando na figura   , localizado acima do editor de código mais à direita.

Escolha a opção “Colors” dentro da chave “Editor” e altere a máscara em “Scheme”, conforme a figura abaixo:

Page 6: Curso Online de Microcontroladores Pic 1° SEMANA

 Do lado esquerdo ao editor de código temos o Code Explorer:

Page 7: Curso Online de Microcontroladores Pic 1° SEMANA

Logo abaixo está o Project Setup com as informações do microcontrolador utilizado e algumas configurações para “Debug”:

 

 

Abaixo de tudo, temos a Janela de Mensagens (Message Window). Nesta janela serão mostrados o status de compilação, e informações de erro e alertas para o nosso código:

 

OBS.: Outras janelas e ferramentas, veremos no decorrer do curso.

Criando um novo projeto

Iniciaremos um projeto somente para verificarmos o funcionamento do compilador MikroC.

Clique no Menu em “Project” e escola a opção “New Project”; 

Page 8: Curso Online de Microcontroladores Pic 1° SEMANA

 

Aparecerá a tela abaixo para inserção dos dados do projeto: 

 

Page 9: Curso Online de Microcontroladores Pic 1° SEMANA

Siga os passos abaixo:

 

-Em “Project Name”, dê o nome do projeto, que neste caso pode ser: Inicio;

-Em “Project Path”, escolha o caminho da pasta onde serão armazenados os arquivos do projeto;

-“Description” não é obrigatório o preenchimento;

-Em “Device”, escolha o microcontrolador a ser utilizado em nosso projeto, no caso, pode ser o P16F877A;

-Em “Clock”, deixe o default mesmo, ou seja, 008.000000 (8MHz);

-Em “Device Flags”, deixe o default também, por enquanto não faremos nenhuma alteração;

-Digite, no Editor de código, apenas o bloco principal, conforme abaixo:

 

void main()

{

 }

 

-Após digitar o código acima, vamos compilar o projeto clicando no menu “Project” e escolhendo a opção “Build”: 

 

Podemos também compilar a projeto com as teclas “Ctrl + F9”.

Page 10: Curso Online de Microcontroladores Pic 1° SEMANA

 

-Se tudo estiver correto, será mostrado o resultado da compilação na Janela de Mensagens, conforme abaixo: 

Introdução à Linguagem C  

Tipos de dados

 Os tipos de dados suportados pela linguagem C e utilizados no compilador MikroC são identificados pela palavras reservadas*: char, int, float, double e void.

Tipo de dado Tamanho Intervalochar 8 bits 0 a 255int 16 bits 0 a 65536

float e double 32 bits 3.4 x 10-38 a 3.4 x 1038

void 0 0

O tipo char representa caracteres ASCII de 8 bits, sendo que cada variável do tipo char pode representar somente um caracter ASCII.

O tipo int representa números inteiro de 16 bits.

O tipo float e double representam números fracionários de 32 bits, sendo que este tipo de dado deve ser evitado tendo em vista o seu tamanho.

O tipo void é normalmente  utilizado em funções para declarar que ela não deve retornar nenhum valor.

*palavra reservada = palavra utilizada pelo compilador e que não deve ser utilizada pelo usuário.

Modificadores de Tipo

Page 11: Curso Online de Microcontroladores Pic 1° SEMANA

 Além dos tipos de dados acima, podemos utilizar comandos especiais para modificá-los e são chamados de modificadores de tipo, sendo eles: signed, unsigned, short e long.

 O modificador de tipo signed pode ser utilizado para representar um número positivo ou negativo, assim um tipo de dados signed int pode representar valores de -32768 a 32767.

O modificador unsigned define um tipo de dado sem sinal, ou seja, somente a parte positiva de uma variável, então o tipo de dados unsigned int representa valores de 0 à 65536.

O modificador short é utilizada para definir um valor menor do que o tipo modificado, ou seja, ao declaramos uma variável com o tipo short, a variável tem seu tamanho reduzido para 8 bits.

O modificador long é o contrário, ou seja,  amplia o tamanho de uma variável, então uma variável declarada com o tipo de dado long int passa a ter o tamanho de 32 bits.

Temos abaixo, uma tabela com todos os tipos de dados e seus modificadores disponíveis para o compilador MikroC:

Tipo Tamanho Valores

signed char 8 bits -128 à 127

(unsigned) char 8 bits 0 à 255

(signed) short (int) 8 bits -128 à 127

unsigned short (int) 8 bits 0 à 255

(signed) int 16 bits -32768 à 32767

unsigned int 16 bits 0 à 65535

(signed) long (int) 32 bits -2147483648 à 2147483647

unsigned long (int) 32 bits 0 à 4294967295

float 32 bits (+-) 1,17549435082e-38 à (+-) 6,80564774407e38

double 32 bits (+-) 1,17549435082e-38 à (+-) 6,80564774407e38

long double 32 bits (+-) 1,17549435082e-38 à (+-) 6,80564774407e38

void 0 0

 * Palavras entre parênteses são opcionais.

Variáveis

As variáveis são uma representação simbólica onde são armazenados dados do programa ou dados externos como uma tecla pressionada ou uma tensão lida, etc. As variáveis  podem conter letras e números, sempre começando com

Page 12: Curso Online de Microcontroladores Pic 1° SEMANA

letras e não devem ter nome de palavras reservadas pelo compilador como, por exemplo, for, do, int, etc.

Declaração de Variáveis

Declarar uma variável é simplesmente informar ao compilador que uma variável chamada “X” é do tipo “Y” e é declarada da seguinte forma:

<tipo>  +  <nome da variável>;

Podemos também declarar e inicializar uma variável da seguinte forma:

<tipo> + <nome da variável> = <valor da variável>;

Exemplos:     unsigned int x = 12345;

                       int conta;

                       short x1;

Variáveis Globais -> São declaradas no início de nosso código e que podem ser acessadas em qualquer ponto do programa:

Ex.:

int conta;

unsigned int c;

void main()

{

conta = 10;

c = c + 1;

while (1);

}

Variáveis Locais -> São declaradas dentro de uma função e somente existe durante a execução da função. Elas são descartadas depois de executada a função:

void main()

Page 13: Curso Online de Microcontroladores Pic 1° SEMANA

{

int conta

conta = conta++;

while(1);

}

Operadores

Temos, na linguagem C, vários operadores e podemos verificá-los abaixo:

Operadores de Atribuição

São utilizados para atribuir valores às variáveis:

Operador Descrição Exemplo= Associa um valor à variável a = 2

Aritméticos:

Operador Descrição Exemplo

+ Soma dos argumentos a + b

- Subtração dos argumentos a - b

* Multiplicação dos argumentos a * b

/ Divisão dos argumentos a / b

% Resto da divisão (só pode ser utilizado com valores inteiros)

a % b

++ Soma 1 ao argumento a++

-- Subtrai 1 ao argumento a--

Relacionais:

São utilizados para comparação entre argumentos e retornam uma resposta verdadeira ou falsa. Como em linguagem C não existe uma variável booleana para um resultado verdadeiro ou falso, todo valor igual a 0 será considerado falso e todo valor diferente de 0 (qualquer valor) será considerado verdadeiro.

Page 14: Curso Online de Microcontroladores Pic 1° SEMANA

Operador Descrição Exemplo

== Compara se igual a a == 5

!= Compara se diferente de a != 5

>  Compara se maior que a > 5

<  Compara se menor que a < 5

>= Compara se maior ou igual a a >= 5

<= Compara se menor ou igual a a <= 5

 Operadores lógicos bit-a-bit:

Operador Descrição

& E (AND)

| OU (OR)

^ OU EXCLUSIVO (XOR)

~ Complemento (NOT)

>>  Deslocamento à direita

<<  Deslocamento à esquerda

 Operadores lógicos relacionais:

Operador Descrição

&& Comparação lógica E (AND)

|| Comparação lógica OU (OR)

! Comparação lógica Complemento (NOT)

Introdução à Linguagem C 

Declarações de controle:

Comando if (se):

O comando IF é uma comando de decisão e é utilizado para avaliar uma determinada condição e determinar se ela é verdadeira, caso seja, executa o bloco contido dentro desta condição. Sua forma geral é:

            if (exp) comando;

Se o resultado da condição referente a expressão (exp) for verdadeiro, o comando será executado, caso contrário, o programa segue sem executar o comando.

Page 15: Curso Online de Microcontroladores Pic 1° SEMANA

            if (exp)

                        {

                        comando1;

                        comando2;

                        }

Para o caso acima, a mesma explicação anterior se encaixa, sendo que agora, se a condição da expressão for verdadeira, serão executados comando1 e comando2.

Exemplos:

            if (conta>50) conta = 0;

Neste caso, se a variável conta atingir um valor maior que 50, o comando conta = 0 será executado e a variável conta será zerada.    

           if (conta>50)

                                {

                                 conta = 0;

                                 conta1++;

                                }

Neste caso, se a variável conta atingir um valor maior que 50, os comandos conta = 0 e conta1++ serão executados e assim a variável conta será zerada e a variável conta1 será incrementada em 1, respectivamente.

Comando IF-ELSE:

Neste caso, a condição IF é utilizada da mesma forma anterior, sendo que agora, se a condição da expressão for falsa a condição ELSE será executada, ou seja, neste caso existe a possibilidade de escolha de uma entre duas opções. Sua forma é:

            if (exp) comando1;

            else comando2;

Caso a expressão seja verdadeira, o comando1 será executado, caso seja falsa, o comando2 será executado.

Page 16: Curso Online de Microcontroladores Pic 1° SEMANA

Exemplo:

              if (conta>0)

                                 {

                                   conta = 0;

                                   conta1++;

                                  }

              else conta++;

Para o exemplo, se o valor da variável conta for maior que 0, então os comandos conta = 0  e conta1++ serão executados, porém caso o valor da variável conta seja 0 ou menor que 0, então o comando conta++ será executado.

Comando SWITCH-CASE:

Quando existem muitos valores para testar de uma só variável, o comando IF pode ficar meio confuso ou sem muita eficiência, para isso podemos utilizar o SWITCH-CASE. Segue sua forma:

            switch(variável)

                        {

                        case valor1: comando1;

                                            ....

                                            break;

                        case valor2: comando2;

                                             ....

                                            break;

                                            ....

                                            ....

                        default: comandoN;

                                     ....

Page 17: Curso Online de Microcontroladores Pic 1° SEMANA

                                     ....

                       }

Neste caso, a variável será testada e se o valor dela for igual a valor1, o comando1 será executado, se for igual ao valor2, o comando2 será executado e assim por diante, agora se o valor for diferente de qualquer caso (case), o comandoN será executado.

Exemplo:

               switch(conta)

                                   {

                                   case 10 : conta1++;

                                                  break;

                                   case 15:  conta2++;

                                                  break;

                                   case 20:  {

                                                  conta1++;

                                                  conta2++;

                                                  }

                                                  break;

                                   default:  conta3++;

                                   }

Neste caso, se o valor da variável conta for igual a 10, a variável conta1 será incrementado, se o valor da variável conta for igual a 15, o valor da variável conta2 será incrementado, caso o valor de conta seja igual a 20, tanto os valores de conta1 quanto de conta2 serão incrementados, para todos outros valores diferentes para a variável conta, o valor de conta3 será incrementado.

Note que após cada comando, temos a cláusula break, cuja função é encerrar o teste da variável tendo em vista já ter sido satisfeita a condição, assim, por exemplo:

Page 18: Curso Online de Microcontroladores Pic 1° SEMANA

switch(conta)

                     {

                     case 10 : conta1++;

                                    break;

                                   .

                                   .

                                   .

Se a variável conta tem seu valor igual a 10, o comando de incremento da variável conta1 será executado, ou seja, a condição já foi atendida e não é preciso testar mais vezes a variável conta. Então, a cláusula break, encerra os teste feitos por case e, assim, o programa continua na próxima instrução após a estrutura switch.     

Laço FOR:

Este é um dos comandos de laço (loop ou repetição) disponíveis na linguagem C, a sua forma é:

            for(inicialização;condição(término);incremento) comando:

            ou,

            for(inicialização;condição(término);incremento)

                 {

                  comando1;

                  comando2;

                  }

onde:

inicialização: essa seção conterá uma inicialização para a variável;

condição: responsável por contar a condição de finalização do laço;

incremento: aqui pode conter uma ou mais variáveis para incremento da variável.

Page 19: Curso Online de Microcontroladores Pic 1° SEMANA

Exemplo:

            int conta;

            int a = 0;

            for (conta=0;conta<10;conta++) a = conta;

Neste exemplo, a variável conta será iniciada com o valor 0, a expressão a = conta será executada e após isso a variável conta será incrementada novamente. Essa repetição ou laço se encerrará quando a condição conta < 10 for satisfeita, ou seja quando a variável conta for igual a 9.

Laço WHILE:

Neste laço, os comandos serão repetidos enquanto a expressão for verdadeira, sua forma é:

while (exp)

                                    {

                                    comando;

                                    }

 Exemplo:

            int x;

x = 0;

            while(x<10) x++;

A programa ficará no laço de repetição whil, enquanto a variável x for menor que 10 e o programa só continuará quando o valor de x for maior ou igual a 10.

 

Laço DO-WHILE:        

Este laço é uma variação do comando WHILE, sendo que neste caso o comando será executado antes de testar se a condição é verdadeira. Sua forma é:

Page 20: Curso Online de Microcontroladores Pic 1° SEMANA

            do       

               {

                comando;

               }

               while(exp);

O comando será executado pelo menos uma vez antes de verificar a condição da expressão.

Exemplo:

                int x;

                int y;

                do

                    {

                     x++;

                    } while(y!=1);

Introdução à Linguagem C  

Notação numérica

Em linguagem C, podemos usar as 4 formas de representação numérica, decimal, binária, hexadecimal e octal, sendo as mais comuns somente as 3 primeiras.

Notação decimal: a representação desta notação é direta, ou seja, como estamos acostumados a escrever:

Ex.:  PORTB = 10;

Notação binária: esta representação vem precedida de “0b” ou “0B”, indicando a notação:  

Page 21: Curso Online de Microcontroladores Pic 1° SEMANA

Ex.: PORTB = 0b00000010;

        ou

        PORTB = 0B00000010;

Notação Hexadecimal: esta representação vem precedida de “0x” ou “0X”, ex:

Ex.: PORTB = 0x0A;

        ou

        PORTB = 0X0A; 

Primeiro Projeto

Primeiramente, sugiro que se abra uma pasta no seu HD com o nome CURSO_PIC, para armazenarmos os nossos projetos criados durante o curso. Dentro da pasta CURSO_PIC, podemos criar outras pastas referentes ao projetos.

Vamos abrir um novo projeto, conforme explicado anteriormente, com as definições abaixo 

Definindo o projeto:

-Project Name : PiscaLed

-Project Path   : C:\CURSO_PIC\PISCA LED\

-Description    : ....

-Device           : P16F877A

-Clock             : 008.000000

-Device Flags : Clique no botão Default no lado direito dos “Device Flags”

Os bits de configuração (fuses) podem ser configurados, selecionando ou não os mesmos em “Device Flags” e quando utilizamos a opção “Default” os fuses serão configurados da seguinte forma:

_LVP_OFF;

_WDT_OFF

_HS_OSC

Page 22: Curso Online de Microcontroladores Pic 1° SEMANA

 

 Circuito:

O circuito que utilizaremos neste primeiro exemplo está logo abaixo:

 

 

Escrevendo o código:

Em linguagem C, os programas podem ter uma ou mais funções, isso faz com que tenhamos uma estrutura modular, ou seja, tenhamos blocos que podem ser acessados em qualquer parte do programa facilitando a visualização e o entendimento do programa.

Todo programa C tem uma função principal (main) e a partir dela nosso programa será inicializado.

Estrutura básica de um programa em C utilizando o compilador mikroC:

Page 23: Curso Online de Microcontroladores Pic 1° SEMANA

void main()

{   //Inicia a função.

     //Este é o bloco principal do programa e é o único que a linguagem C precisa para funcionar.

}  //Finaliza a função.

Este, como vimos anteriormente, é o menor programa escrito em linguagem C no compilador MikroC. Note a função principal void main() e logo após, abrimos a inicialização da função com uma chave, logo após vem o corpo do programa (onde ele será escrito) e em seguida fechamos o programa com outra chave.

Note também as duas barras (//) antes das explicações. Essas barras iniciam um comentário e tudo que vier após estas barras não será ‘entendido’ pelo programa, ou seja, não será compilado.

Podemos também fazer comentários de outra maneira, veja a seguir:

/*Temos aqui uma outra forma de  comentar num programa. Esta maneira é indicada quando precisamos escrever  algum comentário grande como este ou maior*/

Neste caso, o comentário tem seu início com ‘/*’ e é finalizado com ‘*/’.

Código do Projeto:

void main()

{                                              //Inicia a função main (principal)

PORTD = 0;

TRISD   = 0;                          //Configura todos os pinos da porta D como saída.

 while(1)                                //Começo do loop (infinito)

            {

            PORTD = ~PORTD;   //Troca situação dos pinos na porta D.

            delay_ms(1000);         //Tempo de atraso de 1 segundo.

            }

}                                                 //Finaliza a função main

Page 24: Curso Online de Microcontroladores Pic 1° SEMANA

Compilando o Projeto

Depois de escrevermos o código, devemos compilar o projeto para que possamos gravar no microcontrolador. A compilação se dá pressionando-se “ctrl + F9” ou clicando no menu Project e escolher a opção Build, conforme abaixo.

 

 

Estando o projeto sem erros, as informações abaixo devem ser mostradas na parte de baixo do programa.

 

Page 25: Curso Online de Microcontroladores Pic 1° SEMANA

 

Gravando o código 

Utilizaremos, para gravar o programa no microcontrolador, o programa WinPic800 como segue a figura abaixo:

Siga os procedimentos de instalação e gravação do microcontrolador no WinPic800 conforme manual “Instalação da ACEPIC 40.pdf” que segue no CD do curso.  

Page 26: Curso Online de Microcontroladores Pic 1° SEMANA

Projeto de Fixação

Projetos de fixação:

-Este projeto faz piscar o led conectado ao pino 0 da porta D

void main()

{

TRISD.F0 = 0; //Configura o pino 0 da porta D como saída.

while (1)

{

PORTD.F0 = 0; //Coloca pino 0 da porta D em nível lógico 0

delay_ms(500); //Tempo de atraso de 500ms

PORTD.F0 = 1; //Coloca pino 1 da porta D em nível lógico 1

delay_ms(500); //Tempo de atraso de 500ms

}

}

obs.: Os registradores especiais, TRISD, PORTD, PORTA, TRISA, INTCON, TMR0 e outros são tratados, pelo compilador, como variáveis, portanto, podemos atribuir valor e tratá-los exatamente como uma variável qualquer.

UNIDADE 2

Nesta segunda semana, veremos como fazer a leitura de uma tecla pressionada através da leitura direta do bit e da função do próprio compilador, trataremos do acionamento de bits individualmente e também das funções e protótipos de funções da linguagem C.  Verificaremos também a utilização do Timer 0 como contador e temporizador, assim como faremos alguns projetos para entendimento dos assuntos da semana.

Leitura das teclas Recurso

Controle individual de bits Recurso

Função Button Recurso

Funções em Linguagem C Recurso

Page 27: Curso Online de Microcontroladores Pic 1° SEMANA

Abaixo veremos a utilização do timer 0 como contador e temporizador.Seguem também exemplos de utilização e nas póximas aulas veremos os outros dois timers 1 e 2 para o PIC 16F877A.

Contador/Temporizador Timer 0 Recurso

Cálculo / Contando um tempo de 1 segundo Recurso

Timer 0 com sinal externo Recurso

Responda as questões referentes aos assuntos da segunda semana seguindo o link abaixoEste questionário é importante para que sua média seja formada e também é um feedback para que você avalie sua participação no cursoVocê pode acompanhar sua nota e as correções clicando no link "Nota" no menu "Administração" ao lado direito.

Questões - Semana 2 Tarefa

Acionamento de Botões  Projeto -Fazer um programa que, se o usuário pressionar um dos botões “1”,

“4”, “7” e “*”, um dos Led’s D1, D2, D3 e D4,respectivamente, deverá acender. 

Definindo o projeto: -Project Name : Botao -Project Path   : \ CURSO_PIC\Botoes\ -Description   : .... -Device          : P16F877A -Clock            : 008.000000 -Device Flags: Default  

Page 28: Curso Online de Microcontroladores Pic 1° SEMANA

 

Escrevendo o programa Note que os botões tem suas ligações em toda PORTA B e que os

botões “1”, “2”, “3” e “A” tem uma de sua conexões no PINO RB0, sendo assim, quando pressionarmos um desses botões, o LED D1 acenderá e se pressionarmos um dos botões “4”, “5”, “6” ou “B”, o LED D2 acenderá e assim também para o restante dos botões.

Como sabemos, os microcontroladores PIC tem resistores de PULL UP internos conectados na porta B (verificar Datasheet) e para o nosso programa deveremos habilitar estes resistores. A habilitação dos resistores de PULL UP se dá através do registrador OPTION_REG, através do Bit 7 (RBPU) e este deve estar em 0 para que os resistores sejam habilitados. 

  

Page 29: Curso Online de Microcontroladores Pic 1° SEMANA

  Ligação dos resistores de Pull Up interna

void main() { OPTION_REG.F7 = 0;                //Habilita resistores de PULL UP da porta B   TRISB   = 0X0F;                          //Configura os 4 bits menos significativos

como entrada                                                      //... e os 4 bits mais significativos como saída

para a porta B TRISD   = 0X00;                          //Configura toda a porta D como saída PORTB = 0X00;                          //Limpa porta B PORTD = 0X00;                          //Limpa portaD -> apaga os Led’s   while(1)                 {                 if (PORTB.F0 == 0)    //Se o bit 0 da porta B for igual a zero                     PORTD.F1 = 1;       //Aciona o bit 1 da porta D -> acende o LED 1                   if (PORTB.F1 == 0)    //Se o bit 1 da porta B for igual a zero                     PORTD.F2 = 1;       //Aciona o bit 2 da porta D -> acende o LED 2                 if (PORTB.F2 == 0)    //Se o bit 2 da porta B for igual a zero                    PORTD.F2 = 1;        //Aciona o bit 2 da porta D -> acende o LED 3                   if (PORTB.F3 == 0)    //Se o bit 3 da porta B for igual a zero                    PORTD.F3 = 1;        //Aciona o bit 3 da porta D -> acende o LED 4                 } }

Controle de Bits de registradores - Acionamento de um único bit 

No nosso programa, precisamos acionar somente o bit 7 (RBPU) do registrador OPTION_REG, então utilizamos a seguinte forma:

OPTION_REG.F7 = 0; Isso faz com que somente o bit 7 do registrador OPTION_REG seja

afetado, ou seja, somente ele passará a ter o valor 0 e o restante dos bits permanecem em seu estado anterior que, neste caso, estão em “default”. Podemos também atribuir das seguintes maneiras: OPTION_REG = 0, OPTION_REG = 0x00 ou ainda OPTION_REG = 0b00000000. 

Utilizamos este modo de acionamento também para verificação dos botões e para o acionamento dos LED’s, conforme abaixo:

if (PORTB.F0 == 0) Nesta condição, verificaremos somente se o bit 0 da porta B está em

nível lógico 0. Logo após temos: PORTD.F0 = 1; Com este comando, somente o LED conectado ao pino RD0, ou seja,

bit 0 da porta D será acionado. Podemos também atribuir das seguintes

Page 30: Curso Online de Microcontroladores Pic 1° SEMANA

maneiras: PORTD = 1, PORTD = 0x01 ou ainda, PORTD = 0b00000001.

Este modo de atribuição de bits é interessante quando necessitamos modificar somente um bit sem nos preocupar com os outros. Por exemplo: na porta, os LED’s 1, 2, 3 e 4, estão acionados, portanto PORTD = 15 ou PORTD = 0x0F ou ainda PORTD = 0b00001111. Queremos acionar o LED 8 que está conectado no pino RD7 e mantermos os outros como estão... então podemos simplesmente atribuir PORTD.F7 = 1.

Como foi dito anteriormente, todos os registradores são tratados como variáveis e tem seu tipo como unsigned short, ou seja, têm tamanho de 8 bits. Sendo assim, podemos acionar os bits da mesma maneira para outras variáveis do tipo unsigned short.

Ex.1: unsigned short cmd = 0;  //Aqui declaramos a variável cmd e

atribuímos a ela o valor zero. cmd.F0 = 1;  //Aqui, somente o bit 0 desta variável terá seu valor em 1,

então a variável passa a ter                       //...o valor de 1, ou seja, cmd = 1. Podemos também

atribuir assim: cmd =  0b00000001; Ex.2: unsigned short cmd = 0;  //Aqui declaramos a variável cmd e

atribuímos a ela o valor zero. cmd.F1 = 1   //Aqui, somente o bit1 desta variável terá seu valor em 1,

então a variável passa a ter                        //...o valor de 2, ou seja, cmd = 2. Podemos também

atribuir assim: cmd =  0b00000010;

Função Button  O compilador MikroC disponibiliza uma biblioteca para verificação do

acionamento de botões e esta pode ser acessada através do comando: Button(&PORTx, pino, tempo, estado de ativação) Onde: &PORTx = Porta onde está conectado o botão, Exemplo: PORTB; Pino = Pino da porta onde está conectado o botão, exemplo pino 0 da

porta B; Tempo = Período de debounce em milisegundos; Estado de ativação = Pode ser 0 ou 1 e determina se o botão é

acionado pelo nível lógico 1 ou nível lógico 0. Sintaxe da função:

unsigned short Button(unsigned short *port, unsigned short pin, unsigned short time, unsigned short active_state);

Exemplo de uso: if (Button(&PORTB,0,20,1));  //verifica se o pino 0 da porta B está em

nível lógico 1, sendo que                                                   //...estando em 1, faz um delay de 20ms

(debounce)

Page 31: Curso Online de Microcontroladores Pic 1° SEMANA

Exemplo utilizando a biblioteca Button no projeto no projeto Acionamento de Botões.

-Project Name : Button_test -Project Path   : \ CURSO_PIC\Botoes\ -Description   : .... -Device          : P16F877A -Clock            : 008.000000 -Device Flags: Default void main() { OPTION_REG.F7 = 0;                                //Habilita resistores de PULL UP da

porta B   TRISB   = 0X0F;                                         //Configura os 4 bits menos

significativos como entrada                                                                     //... e os 4 bits mais significativos

como saída para a porta B TRISD   = 0X00;                                         //Configura toda a porta D como

saída PORTB = 0X00;                                         //Limpa porta B PORTD = 0X00;                                         //Limpa portaD -> apaga os Led’s   while(1)                 {                 if (Button(&PORTB,0,20,0)        //Se o bit 0 da porta B for igual a

zero                     PORTD.F1 = 1;                      //Aciona o bit 1 da porta D -> acende

o LED 1                 if (Button(&PORTB,1,20,0)        //Se o bit 1 da porta B for igual a

zero                     PORTD.F2 = 1;                      //Aciona o bit 2 da porta D -> acende

o LED 2                 if (Button(&PORTB,2,20,0)        //Se o bit 2 da porta B for igual a

zero                    PORTD.F2 = 1;                       //Aciona o bit 2 da porta D -> acende

o LED 3                 if (Button(&PORTB,3,20,0)        //Se o bit 3 da porta B for igual a

zero                    PORTD.F3 = 1;                       //Aciona o bit 3 da porta D -> acende

o LED 4                 } } Note que no nosso caso, quando o botão for acionado, ele levará o pino

de entrada para o nível lógico 0, portanto, na biblioteca Button, o estado de ativação do botão será 0.

Obs.: Podemos atibuir um outro nome a uma constante ou a um registrador através da diretiva define conforme segue abaixo:

Definições do Projeto acima: -Project Name : Button_def

Page 32: Curso Online de Microcontroladores Pic 1° SEMANA

-Project Path   : \ CURSO_PIC\Botoes\ -Description   : .... -Device          : P16F877A -Clock            : 008.000000 -Device Flags: Default #define LED1  PORTD.F0              //Atribui o nome LED1 ao bit 0 da porta D #define LED2  PORTD.F1              //Atribui o nome LED2 ao bit 1 da porta D #define LED3  PORTD.F3              //Atribui o nome LED3 ao bit 2 da porta D #define LED4 PORTD.F4               //Atribui o nome LED4 ao bit 3 da porta D   void main() { OPTION_REG.F7 = 0;                    //Habilita resistores de PULL UP da porta B TRISB = 0X0F;                               //Configura os 4 bits menos significativos

como entrada                                                        //... e os 4 bits mais significativos como

saída para a porta B TRISD = 0X00;                               //Configura toda a porta D como saída PORTB = 0X00;                             //Limpa porta B PORTD = 0X00;                            //Limpa portaD -> apaga os Led’s   while(1)                 {                 if (Button(&PORTB,0,20,0)       //Se o bit 0 da porta B for igual a zero                     LED1 = 1;                               //Aciona o bit 1 da porta D -> acende

o LED 1                 if (Button(&PORTB,1,20,0)        //Se o bit 1 da porta B for igual a

zero                     LED2 = 1;                                //Aciona o bit 2 da porta D ->

acende o LED 2                 if (Button(&PORTB,2,20,0)         //Se o bit 2 da porta B for igual a

zero                    LED3 = 1;                                 //Aciona o bit 2 da porta D ->

acende o LED 3                 if (Button(&PORTB,3,20,0)         //Se o bit 3 da porta B for igual a

zero                    LED4 = 1;                                 //Aciona o bit 3 da porta D ->

acende o LED 4                 } }          

Funções  As funções em linguagem C são muito parecidas com as sub-rotinas da

linguagem assembly. O seu uso permite executar uma sequência de comandos sempre que necessitarmos, sem a necessidade de repetí-los.

O formato geral de uma função é: {tipo} nome_da_função ({parâmetros}) {  Comando_1;  Comando_2;  ....

Page 33: Curso Online de Microcontroladores Pic 1° SEMANA

} Onde: tipo: Especifica o tipo de dado que a função retornará para onde ela foi

chamada. nome_da_função: Identifica a função, ou seja, como ela será chamada

pelo programa. Este nome não pode ter o mesmo nome utilizado por funções próprias do MikroC.

parâmetros: Utilizados para enviar valores para a função de modo que estes sejam utilizados pela função para cálculos, atribuições, controle, etc.

Esses valores consistem em tipos de variáveis separados por vírgulas e são opcionais, portanto, podemos escrever funções sem qualquer parâmetro.

Mesmo sem a existência dos valores, os parênteses devem ser utilizados.

Exemplo:

short soma (short a, short b)

{

return a + b;

}

 

void main ()

{

short c;

c = soma (2,3);

while(1);

}

  Neste programa, definimos uma função soma que retornará o resultado

da operação dos parâmetros “a” + o parâmetro “b”.  Note que o a função é do tipo short, isso então especifica que a função retornará um valor do tipo short de 8 bits.

No corpo da função, encontramos somente o código return  a + b, onde o comando “return” é utilizado para retornar o valor da operação dos parâmetros “a + b”.

No bloco principal, encontramos a chamada da função através de c = soma (2,3), onde a variável “c” receberá o valor do retorno da função (note que a variável também foi declarada com o mesmo tipo da

Page 34: Curso Online de Microcontroladores Pic 1° SEMANA

função) e os parâmetros são os valores “2” e “3”, separados pela vírgula e dentro dos parênteses.

Então neste caso, a função soma recebe os valores “2” e “3” e estes serão atribuídos às variáveis “a” e “b”, respectivamente e a função retornará o valor da soma entre eles, portanto o valor “5” que será repassado para a variável “c” no corpo principal do programa.

Protótipo de função   Um programa em linguagem C pode ficar muito grande e muito complexo e, às

vezes, uma função pode ser chamada antes desta ter sido definida. Neste caso, o compilador gera um erro, veja o exemplo abaixo:

void main ()

{

short c;

c = soma (2,3);

while(1);

}

short soma (short a, short b)

{

return a + b;

}

 

     Veja que a função soma está definida após a função principal (main).

Neste caso, como a função soma foi definida após a sua chamada, o compilador retornará um erro dizendo que o identificador soma não foi declarado, veja a mensagens de erro na próxima figura: 

Podemos solucionar este tipo de problema se declararmos previamente a função, ou seja, informaremos ao compilador que existe uma função

Page 35: Curso Online de Microcontroladores Pic 1° SEMANA

com aquele “nome” que estamos “chamando”. Isto é conhecido como prototipagem de função.

O protótipo de função deve ser declarado obedecendo os mesmos tipos e parâmetros da função seguido do ponto e vírgula (;) e, normalmente, são declarados logo no início do programa.

Exemplo:

short soma(short a, short b);

 

void main ()

{

short c;

c = soma (2,3);

while(1);

}

 

short soma (short a, short b)

{

return a + b;

}

   

Contador/Temporizador Timer 0 O Timer 0 é um contador/ temporizado binário e pode ser utilizado para

contagem de eventos externos por meio do pino RA4/T0CKI ou como temporização quando a entrada do clock é tida do clock interno.

O Timer 0 possui um prescaler de até 256 e tem 8 bits, ou seja, se configurarmos o prescaler para 1, então haverá um overflow (estouro da contagem) a cada 256 contagens (0 à 255). Para a configuração do Timer 0, utilizam-se os registros especiais OPTION_REG e INTCON.

Registrador OPTION_REG – Endereço: 81h E 181hBit Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0

Nome /RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0

Page 36: Curso Online de Microcontroladores Pic 1° SEMANA

Obs.: Somente os pinos marcados com fundo cinza serão utilizados para a configuração do Timer  0. 

Configuração dos bits de controle do Timer 0:   T0CS = 1: Incremento a cada transição no pino RA4/T0CKI. T0CS = 0: Incremento a cada ciclo de máquina (Fosc/4).   T0SE = 1: Incremento na borda de descida. T0SE = 0: Incremento na borda de subida.   PSA = 1: Prescale aplicado ao WDT. PSA = 0: Prescale aplicado ao TMR0.   PS2, PS1 e PS0 - Configuração do Prescale.

PS2 PS1 PS0 TMR0 WDT0 0 0 1:2 1:10 0 1 1:4 1:20 1 0 1:8 1:40 1 1 1:16 1:81 0 0 1:32 1:161 0 1 1:64 1:321 1 0 1:128 1:641 1 1 1:256 1:128

 Interrupção do Timer 0  Para se utilizar a interrupção do Timer 0 (TMR0), devemos setar

(colocar em nível lógico 1) os bits do registrador INTCON, conforme a tabela abaixo.

O Registrador INTCON é o responsável pelo controle das interrupções no PIC. 

Registrador INTCON – Endereço: 0Bh, 8Bh, 10Bh E 18BhBit Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0

Nome GIE PEIE T0IE INTE RBIE T0IF INTF RBIF  

GIE = 1: Habilita a interrupção global. GIE = 0: Desabilita a interrupção global.   T0IE = 1: Habilita a interrupção do TIMER 0. T0IE = 0: Desabilita a interrupção do TIMER 0.   T0IF – Flag de sinalização da ocorrência de overflow no TIMER0, este

Flag deverá ser limpo (levado à 0) quando do tratamento da interrupção. 

T0IF = 1: Houve overflow no Timer 0. T0IF = 0: Não houve overflow no Timer 0. 

Page 37: Curso Online de Microcontroladores Pic 1° SEMANA

Trataremos da interrupção do Timer 0 mais adiante no curso.

Contanto um tempo com o Timer 0  Primeiramente, precisamos entender a função do prescale para que

possamos iniciar a contagem de um tempo com o Timer 0. O Prescale é um divisor programável utilizado para reduzir a freqüência

do clock no Timer 0, então, como dito antes, se programarmos o prescale para 1:1, estamos dizendo que o Timer 0 terá seu valor incrementado a cada ciclo de máquina, ou seja, se tivermos um ciclo de máquina de 1us, o Timer 0 terá um incremento a cada 1us. Programando o prescale para 1:2, o incremento do Timer 0 se dará a cada 2 ciclos de máquina, ou seja a cada 2us e assim por diante até o prescale de 1:256, onde o Timer 0 incrementará somente com 256 ciclos de máquina, em 256us. 

O valor da contagem do Timer 0 é acessado através do registrador TMR0 e, como dito anteriormente, este registrador tem 8 bits, então ele pode contar de 0 à 255, portanto, mais uma contagem (256), ele retorna para 0, fazendo com que o bit TOIF (bit 2 do registrador INTCON) seja ativado sinalizando o trasbordo da contagem (overflow).

Contanto um tempo de 100us  Primeiramente verifica-se que este tempo se encaixa na divisão do

prescaler 1:1, onde o tempo total com este prescaler é de 256us, então o valor que precisamos para iniciar o Timer 0 será:

256 – 100 = 156.  O Valor 156 deverá ser escrito no registrador TMR0 e devemos

selecionar o prescale de 1:1 ativando a contagem pelo WatchDog.  Para o exemplo utilizaremos o circuito abaixo:

Page 38: Curso Online de Microcontroladores Pic 1° SEMANA

   

Definições do Projeto:   -Project Name : Timer0 -Project Path   : \ CURSO_PIC\Timer0\ -Description   : .... -Device          : P16F877A -Clock            : 008.000000 -Device Flags: Default  Façamos, então um programa onde a contagem do tempo será de

100us:  void main() { TRISD = 0;                               //Direciona toda a porta D como saída PORTD = 0;                             //Limpa a porta D apagando os LED's   OPTION_REG = 0X80;       /*Configura o Registrador OPTION_REG                                                RBPU = 1 -> PULL UP's porta B

desligados                                                INTEDG = 0 Interrupção na borda de

descida do sinal                                                ...no pino RB0 (não utilizado neste

exemplo).                                                T0CS = 0 -> Incremento pelo ciclo de

máquina                                                ...0,5us para o cristal de 8MHz.                                                T0SE = 0 -> Incremento na orda de

subida.                                                PSA = 0 -> Prescale aplicado ao Timer 0

Page 39: Curso Online de Microcontroladores Pic 1° SEMANA

                                               PS2, PS1 e PS0 = 0 -> Prescale = 1:2*/ TMR0 = 156;                         //Valor Inicial para o timer 0   while(1)       {       if (INTCON.T0IF == 1)       //Se ocorrer um overflow no timer 0           {           INTCON.T0IF = 0;          //Limpa o Flag sinalizador de overflow           TMR0 = 156;                //Retoma o valor inicial para o Timer 0           PORTD = ~PORTD;       //Inverte os Bits da porta D, acendendo

ou apagando                                                //...os LED's                    }       } } Ao gravarmos este programa no microcontrolador, verificaremos que os

LED’s permanecerão todos acesos, mas na realidade, todos estão piscando numa freqüência muito alta 10KHz (100us) para o olho humano e que para verificarmos o acionamento ou não dos LED’s será necessários verificarmos com um osciloscópio conectado a qualquer um dos pinos da porta D.

Calculando o tempo Total com o Timer 0  Podemos calcular o tempo total para a contagem do Timer 0 seguindo a

seguinte fórmula:  Tempo = 256 x prescaler x ( 1 / (FOSC / 4))

  Então, se tivermos um cristal de 8MHz, teremos então em ( 1 / (FOSC /

4)) = 0,5 us e se formos utilizar o prescaler de 1:2 aplicado ao TMR0, teremos:

Tempo = 256 x 2 x 0,5u; Tempo = 256 us.

  Para um prescaler de 256, teremos: 

Tempo = 256 x 256 x 0,5u; Tempo = 32768 us ou 32,768ms

 

Contando um tempo de 1 segundo  Como sabemos, 1 segundo é o equivalente a 1000ms e o tempo

máximo que conseguimos chegar com o Timer 0 é de 32,768ms. Sendo assim, precisamos então dividir estes 1000ms para que possamos adequar à realidade do nosso PIC.

Bem, a divisão de 1000ms por 32,768ms resulta em 30,5175.... Este resultado, por ser um valor “quebrado” não nos ajudará muito, então vamos dividir o tempo de 1000ms por 25ms. O resultado agora será 40. ...Guardaremos este resultado para ser usado posteriormente. 

Page 40: Curso Online de Microcontroladores Pic 1° SEMANA

Então, precisamos que o overflow do Timer 0 ocorra a cada 25ms... Verificamos também que este tempo se “encaixa” no prescaler 1:256. Basta-nos encontrar o valor de início para o Timer 0 a fim de que o overflow ocorra conforme a nossa necessidade.

Podemos lançar mão da fórmula abaixo para definirmos este valor de início para o Timer 0: 

    Atribuindo os valores na fórmula temos: 

TMR0 = 256 – (25 ms / (0,5us x 256)) TMR0 = 60,69 

  O resultado é um valor fracionário, mas podemos aproximá-lo para 61.

Então o valor a ser atribuído ao registrador TMR0 a fim de iniciá-lo será 61.

De posse dos dados acima, podemos iniciar a escrita do código para programação do microcontrolador. O circuito será o mesmo utilizado no exemplo anterior.

  Definições do Projeto: -Project Name : Timer0_1s -Project Path   : \ CURSO_PIC\Timer0_1s\ -Description   : .... -Device          : P16F877A -Clock            : 008.000000 -Device Flags: Default void main() { short conta = 0;                     //Variável de controle para a contagem   TRISD = 0;                               //Direciona toda a porta D como saída PORTD = 0;                             //Limpa a porta D apagando os LED's   OPTION_REG = 0X87;       /*Configura o Registrador OPTION_REG                                                RBPU = 1 -> PULL UP's porta B

desligados                                                INTEDG = 0 Interrupção na borda de

descida do sinal                                                ...no pino RB0 (não utilizado neste

exemplo).                                                T0CS = 0 -> Incremento pelo ciclo de

máquina                                                ...0,5us para o cristal de 8MHz.                                                T0SE = 0 -> Incremento na orda de

subida.

Page 41: Curso Online de Microcontroladores Pic 1° SEMANA

                                               PSA = 0 -> Prescale aplicado ao Timer 0                                                PS2, PS1 e PS0 = 1 -> Prescale = 1:256*/ TMR0 = 61;                            //Valor Inicial para o timer 0   while(1)       {       if (INTCON.T0IF == 1)                //Se ocorrer um overflow no timer 0           {           INTCON.T0IF = 0;                   //Limpa o Flag sinalizador de

overflow           TMR0 = 61;                              //Retoma o valor inicial para o

Timer 0           if (conta >= 40)                        //Se a variável conta for maior ou

igual a 40              {              PORTD = ~PORTD;            //Inverte os Bits da porta D,

acendendo ou apagando os LED's              conta = 0;                              //...e zera novamente a variável

para a próxima contagem              }           conta++;                                   //incrementa a variável conta++           }       } }   Um dos erros bastante comuns é a falta das chaves que abrem e

fecham as declarações de controle, conforme abaixo:   while(1)       {                                           //Abre o laço while       if (INTCON.T0IF == 1)       //Se ocorrer um overflow no timer 0           {                                       //Abre o primeiro comando if           INTCON.T0IF = 0;          //Limpa o Flag sinalizador de overflow           TMR0 = 61;                    //Retoma o valor inicial para o Timer 0           if (conta >= 40)              //Se a variável conta for maior ou igual a

40              {                                    //Abre o segundo comando if                         PORTD = ~PORTD;  //Inverte os Bits da porta D, acendendo ou

apagando os LED's              conta = 0;                    //...e zera novamente a variável para a

próxima contagem              }                                    //Fecha o segundo comando if           conta++;                         //incrementa a variável conta++           }                                      //Fecha o primeiro comando if       }                                          //Fecha o laço while   Perceba também que temos, para o exemplo acima um comando if

dentro de outro comando if. Isso é bastante comum na linguagem C.   if (INTCON.T0IF == 1)                 //Se ocorrer um overflow no timer 0

Page 42: Curso Online de Microcontroladores Pic 1° SEMANA

          {                                            //Abre o primeiro comando if           INTCON.T0IF = 0;              //Limpa o Flag sinalizador de overflow           TMR0 = 61;                         //Retoma o valor inicial para o Timer 0           if (conta >= 40)                   //Se a variável conta for maior ou igual

a 40              {                                         //Abre o segundo comando

if                         PORTD = ~PORTD;       //Inverte os Bits da porta D, acendendo

ou apagando os LED's              conta = 0;                         //...e zera novamente a variável para a

próxima contagem              }                                         //Fecha o segundo comando if           conta++;                              //incrementa a variável conta++           }                                            //Fecha o primeiro comando if   Veja também onde foi utilizado o valor 40 que havíamos guardado

anteriormente. 40 é o número de vezes que ocorrerá o estouro da contagem do Timer 0 para que possamos apagar ou acender os LED’s.

Então temos que haverá um estouro da contagem do timer 0 a cada 25ms e multiplicando este valor por 40, temos 1000ms ou ainda 1 segundo de atraso que será o tempo de permanência dos LED’s apagados ou acesos.

Note também que logo quando condição   if (conta >= 40) é satisfeita, depois de inverter o sinal dos LED’s, temos o comando conta = 0  que faz com que a variável conta volte a sua condição inicial e recomece a contagem para a próxima condição de temporização.  

Utilizando o Timer 0 com um sinal externo  Para utilizarmos a contagem do Timer 0 por um sinal externo, devemos

configurar o registrador OPTION_REG de modo que o incremento do contador Timer 0 deverá ser pela transição do sinal aplicado ao pino RA4/T0CKI e para o nosso circuito, o incremento se dará na borda de descida do sinal, tendo em vista que o sinal aplicado ao pino RA4 está conectado diretamente aos 5V.

Sendo assim, os bits T0CS e T0SE serão colocados em 1.  

Page 43: Curso Online de Microcontroladores Pic 1° SEMANA

-Project Name : T0_Ext -Project Path   : \ CURSO_PIC\Timer0_Ext\ -Description   : .... -Device          : P16F877A -Clock            : 008.000000 -Device Flags: Default  void main() { TRISD = 0;                                           //Direciona toda a porta D como

saída PORTD = 0;                                         //Limpa a porta D apagando os

LED's   OPTION_REG = 0b10110000;      /*Configura o Registrador

OPTION_REG                                                            RBPU = 1 -> PULL UP's porta B

desligados                                                            INTEDG = 0 Interrupção na borda

de descida do sinal                                                            ...no pino RB0 (não utilizado neste

exemplo).                                                            T0CS = 1 -> Incremento na

transição do pino RA4/T0CKI                                                            T0SE = 1 -> Incremento na borda

de subida.                                                            PSA = 0 -> Prescale aplicado ao

Timer 0                                                            PS2, PS1 e PS0 = 0 -> Prescale =

1:2*/

Page 44: Curso Online de Microcontroladores Pic 1° SEMANA

TMR0 = 250;                                     //Valor Inicial para o timer 0   while(1)       {       if (INTCON.T0IF == 1)                //Se ocorrer um overflow no timer 0           {           INTCON.T0IF = 0;                   //Limpa o Flag sinalizador de

overflow           TMR0 = 250;                            //Retoma o valor inicial para o

Timer 0           PORTD = ~PORTD;               //Inverte os Bits da porta D,

acendendo ou apagando                                                             //...os LED's           }       } }   Funcionamento do projeto:  Se pressionarmos uma vez o botão conectado ao pino RA4/T0CKI,

veremos que nada acontece, portanto, se pressionarmos 12 vezes este botão, os LED’s acenderão e depois mais 12 vezes, os LED’s apagarão e assim sucessivamente.  

Analisando o código temos que definimos o prescale com 1:2, portanto a cada 2 transições no pino RA4/T0CKI acontecerá 1 incremento no contador do timer 0 e também definimos que o timer 0 (registrador TMR0) irá contar à partir de 250.

Então 256 – 250 = 6 e, sendo 1 incremento à cada2 transições, temos 6 X 2 = 12.