HOME      PROJETOS      PROGRAMAÇÃO     
  1. INTRODUÇÃO
  2. RECURSOS
  3. ARQUITETURA
  4. ENDEREÇAMENTO
  5. INTERRUPÇÕES
  6. NÍVEIS DE INTERRUPÇÕES NA FAMÍLIA 18F
  7. RESETS DO MICROCONTROLADOR
  8. MODO SLEEP
  9. WATCHDOG TIMER
  10. O STACK
  11. A LINGUAGEM ASSEMBLER
  12. MPLAB - Criando Projetos
  13. LIBRARIES - Usando Bibliotecas de Funções


MPLAB - criando projetos


Vamos iniciar o processo de criação de um projeto usando o programa MPLAB. Para seguir os passos deste exemplo o MPLAB já deve estar instalado no seu computador.

Essa página server somente para quem esta começando agora e nunca usou o MPLAB anteriormente.

O projeto que desenvolveremos aqui será apenas um exemplo de como fazer piscar um LED ligado a uma porta de I/O de um microcontrolador PIC16F628A. Não será necessário montar o hardware do projeto para testar no mundo real. Apenas desenvolveremos o programa.



ABRINDO O MPLAB

Abra o MPLAB clicando no ícone desse programa na área de trabalho.
A interface do programa abrirá como mostrado na figura ao lado. Notar que sempre haverá duas janelas dentro da intercafe. A inferior que servirá para mostrar os resultados das saídas das funçoes (Output) e a superior que serve para selecionar os arquivos que farão parte do projeto que, por enquanto, esta nomeada como "untitled.mcw".

No MPLAB sempre trabalharemos com projetos porque assim fica mais fácil reunir os vários módulos que fazem parte de um projeto. Sendo assim, abra um diretório para que nele sejam guardados todos os projetos.
Neste exemplo vamos trabalhar no diretório C:\temp.









ENTRANDO NO Project Wizard

Para iniciar um novo projeto, vamos usar a opção "Project Wizard".
Clique no menu "Project" e, em seguida na poção "Project Wizard", conforme mostrado na figura ao lado, para entrar no gerenciador de criação de projetos.






BEM-VINDO AO Project Wizard

Ao entrar no "Wizard" a tela de bem-vindo será mostrada.

Clique em "Avançar".                                                                                                                                                                                                        






SELECIONANDO O MICROCONTROLADOR

Esta tela permite a seleção do microcontrolador que iremos usar no projeto.
Neste projeto usaremos o microcontrolador PIC16F628A, portanto, abra lista de seleção de dispositivos e selecione o microcontrolador PIC16F628A.
Em seguida clique em "Avançar".









SELECIONANDO A LINGUAGEM

Nesta janeja, pode-se escolher a linguagem em que se deseja trabalhar.
No case deste exemplo selecionaremos o "MPASM assembler".
Apenas clique em "Avançar" nesta tela.                                                                                                                                                                                                        









CRIANDO O PROJETO

Aqui vamos indicar o diretório e o nome do arquivo que abrigará o nosso projeto.
Clique em "Browse" e navegue até o diretório que você reservou para seus projetos.
Neste exemplo o diretório será o "C:\temp".

                                                                                                                                                                                                       









NOMEANDO O ARQUIVO DE PROJETO

Ao chegar no diretório desejado, digite um nome de arquivo que conterá o projeto, neste exemplo "piscaLED" e, em seguida, clique em "Salvar".









SEGUINDO EM FRENTE...

Nesta tela simplesmente clique em "Avançar".

                                                                                                                                                                                                       









ADICIONANDO ARQUIVOS AO PROJETO

Todo projeto no MPLAB é composto inicialmente de dois arquivos: um arquivo especial com extensão .LKR, cujo conteúdo depente do microcontrolador utilizado e um arquivo com o programa fonte, cuja extensão é .ASM

Para incluir o arquivo .LKR devemos, em primeiro lugar, navegar até o diretório Arquivos de Programas -> Microchip -> MPASM Suite -> LKR e selecionar o arquivo 16f628a.LKR. Em seguida, clicar em "Add>>"".

Notar que o nome do arquivo foi colocado na janela do lado direito marcado com "A".









MARCANDO O ARQUIVO PARA SER COPIADO

O arquivo selecionado deve ser copiado para o diretório do projeto.

Para marcá-lo, mova o cursor para cima da letra "A" e vá clicando até aparecer a letra "C" conforme mostrado na figura ao lado.









ADICIONANDO O ARQUIVO .ASM

Para incluir o arquivo .ASM devemos:

  • navegar até o diretório
    Arquivos de Programas -> Microchip -> MPASM Suite -> template -> code
  • selecionar o arquivo 16F628ATEMP.ASM
  • clicar em "Add>>"
    note que o nome do arquivo foi colocado na janela do lado direito marcado com "A"
  • coloque o cursor em cima da letra "A" e vá clicando até aparecer a letra "C" conforme mostrado na figura ao lado.
  • em seguida clique em "Avançar"





FINALIZANDO

A janela "Summary" encerra a criação do projeto.

Clique em "Concluir" para finalizar.

                                                                                                                                                                                                       






PROJETO CRIADO

Nessa fase o gerenciador de criação de projetos é fechado e verificamos que a janela de projetos foi completada com as informações e arquivos carregados no projeto. Podemos ver o nome do arquivo de projetos "piscaLED.mcw" na barra de título, a pasta de projeto "piscaLED.mcp", o arquivo .ASM "16F628ATEMP.ASM" na pasta "Source Files" e o arquivo "16f628a.LKR" na pasta "Linker Script".
O arquivo "16F628ATEMP.ASM" é somente um modelo para que possamos iniciar a programação do microcontrolador escolhido. Para abrir esse arquivo, clique duas vezes sobre o nome do arquivo.






ABRINDO O CÓDIGO FONTE

Ao clicar duas vezes sobre o nome do arquivo "16F628ATEMP.ASM" ele abrirá em uma janela de editor de texto como na figura ao lado. Essa janela permite modificar o arquivo durante a fase de desenvolvimento desse programa.








ANÁLISE DO MODELO DO CÓDIGO FONTE

O arquivo "16F628ATEMP.ASM" contem o modelo de código fonte em linguagem assembler fornecido pelo MPLAB que usaremos para desenvolver o nosso programa.
Para abrir esse arquivo, clique duas vezes sobre o nome do mesmo na janeja de projetos sob o dirertório "Souce Files".

A figura abaixo mostra o modelo de código fonte fornecido pelo MPLAB para o microcontrolador PIC16F628A.
Para desenvolvermos o projeto "piscaLED" será necessário modificarmos o código modelo até que ele faça o que desejamos, isto é, fazer um LED piscar. Mas antes de modificar o modelo vamos dar uma olhada para ver como ele é formado.

Notamos, que as primeiras 30 linhas do programa começam com ponto-e-vírgula. Isso significa que todas essas linhas são comentários feitos pelo programador para documentar seu programa.Portanto, uma linha iniciada com ponto-e-vírgula sempre será ignorada pelo compilador.

As linhas 31, 34, 36 e outras foram deixadas em branco. Isso foi feito somente por uma questão de estética de quem escreveu o programa. As linhas em branco também são ignoradas pelo compilador.

Na linha 32 temos uma diretiva para o compilador. A diretiva "list p=16f628A" habilita a listagem de saída do compilador. e seleciona o microcontrolador PIC16F628A.

Na linha 33 temos a diretiva "#include <pic16f628a.inc>". Essa diretiva carrega o arquivo "pic16f628a.inc" nesse ponto do programa. O arquivo "pic16f628a.inc" contem símbolos e variáveis apropriadas para esse microcontrolador que serão referenciadas por instruções assembler durante o programa.

Na linha 35, a diretiva "errorlevel -302" solicita ao compilador que elimine a mensagem de erro número 302. Essa mensagem não é importante mas é emitida muitas vezes durante a compilação, o que polui muito a listagem de saída.

A linha 37 apresenta uma das diretivas mais importantes para o compilador. A diretiva __CONFIG é a diretiva de configuração do hardware do microcontrolador e seus parâmetros especificam entre outros:



          
  • _CP_OFF ..................... o programa gravado no microcontrolador não será protegido contra leitura
  • _DATA_CP_OFF ................ os dados gravados não serão protegidos contra leitura
  • _LVP_OFF .................... desligar o modo de programação de baixa voltagem
  • _INTOSC_OSC_NOCLKOUT ........ usar o clock interno do microcontrolador



As linhas de 38 a 46 têm somente linhas em branco e comentários.

Nas linhas 47 e 48 temos a definição de valores para dois símbolos: w_temp e status_temp. As definições do tipo EQU atribuem valores aos símbolos definidos, isto é, toda vez que uma instrução assembler do programa se referir ao símbolo w_temp, essa referência será substituida pelo valor 0x7E que é um número binário escrito em notação hexadecimal. Do mesmo modo, toda vez que uma instrução assembler do programa se referir ao símbolo status_temp, essa referência será substituida pelo valor 0x7F. O motivo para se definir um nome como w_temp ou status_temp ao invés de se usar diretamente um número, é que sempre é mais fácil lembrar um nome do que um número.

Na linha 55 temos um comando ORG. Esse comando informa o compilador a localização de memória onde a próxima instrução assembler será colocada. No caso, ORG 0x000 faz com que a próxima instrução seja colocada no endereço zero da memória de programa. Além disso, a localização de memória 0x000 é a localização para onde o controle é desviado sempre que o microcontrolador é ligado ou sofre um reset. Essa localização é chamada de reset vector.

Na linha 56 temos a primeira instrução assembler do progama goto main. Geralmente, na posição 0x000 da memória teremos somente uma instrução de desvio para o início real do programa (main) porque não podemos escrever muitas instruções nas posições que seguem por serem essas posições as localizações do vetor de interrupção do microcontrolador. Assim a instrução goto main desvia o controle para a linha 74.

Alinha 59 tem outro comando ORG cuja função é definir em que posição de memória será colocada a instrução que o segue.
ORG 0x004 define a posição de memória onde inicia o vetor de interrupção. Nessa posição deve ser escrito o código de tratamento de interrupção o então deve ser colocada uma chamada para esse código (goto inter). As instruções das linhas 60, 61, 62, 67, 68, 69 e 70 pertencem a rotina de interrupção. Note que a última instrução da rotina de tratamento da interrupção, na linha 71, é retfie que sempre é usada para retornar de uma interrupção. Para maiores detalhes veja a página que trata das interrupções.

Na linha 74 temos o rótulo (label) main na coluna 1. Aqui deve começar o programa propriamente dito mas como esse arquivo é somente um modelo, foi colocada na linha 78 somente uma instrução (goto main ) que desvia para ela mesma. Essa instrução deve ser apagada e o nosso programa deve ser escrito a partir daqui.

O programa modelo ainda nos fornece uma dica de como escrever dados na memória EEPROM durante a compilação do programa. Na linha 83, ORG 0x2100 nos da um pseudo endereço de onde inicia a memória EEPROM e na linha 84 a definição de dado      DE 0x00, 0x01, 0x02, 0x03     define os valores que serão gravados na memória EEPROM.

Finalmente, na linha 87, encontramos o comando END que informa ao compilador que este é o fim do código fonte.










CODIFICANDO UM PROGRAMA PARA PISCAR UM LED

Vamos, agora, desenvolver nosso programa "piscaLED" cujo objetivo é fazer um LED (diodo emissor de luz) piscar intermitentemente. Mas antes de começarmos a programar, vamos aprender como energizar o microcontrolador analisando a figura ao lado. Esse esquema elétrico mostra somente como alimentar um microcontrolador PIC16F628A. Na figura, podemos notar que o microcontrolador possui 18 pinos.

O pino 14 esta ligado ao pólo positivo da fonte (+5V) e o pino 5 esta ligado ao pólo negativo. Os microcontrolador da série PIC16F podem ser alimentados com tensões que variam de 2,5v a 5,0v, por isso, se você não dispuser de uma fonte de 5,0V pode usar 3 pilhas de 1,5v ligadas em série que vão fornecer 4,5v, mais do que suficiente para operar esse circuito.

O circuito ainda mostra que o pino 4 do microcontrolador esta ligado por um lado ao pólo positivo (5v) através de um resistor de 1K e por outro lado a uma chave de contato momentâneo que conduz ao pólo negativo. O pino 4 é o MLCR (master clear) do microcontrolador, isto é, para que o microcontrolador funcione, esse pino tem que estar em nível alto. Se, durante o funcionamento normal do circuito, a chave de contato momentâneo for pressionada, isso vai levar o pino 4 ao nível baixo (0v). O microcontrolador é então reiniciado, ou seja, volta a processar a partir da localização zero (0x000) da memória (reset vector).

A figura ao lado mostra o esquema elétrico do circuito que vamos programar.

Observe que somente um LED foi ligado ao pino 11 do microcontrolador. O LED poderia ser ligado a qualquer pino de I/O do microcontrolador. O pino 11 foi escolhido aleatoriamente.

O uc PIC16F628A possui dois registradores, cada um com 8 pinos de entrada e saída (I/O). Um dos rergistradores chama-se PORTA e fazem parte dele os pinos 17, 18, 1, 2, 3, 4, 15 e 16 que correspondem aos bits RA0, RA1, RA2, RA3, RA4, RA5, RA6 e RA7 respectivamente. Com exceção do bit RA5 (pino 4) todos os pinos podem enviar e receber dados.

O outro rergistrador se chama PORTB e fazem parte dele os pinos 6, 7, 8, 9, 10, 11, 12, e 13 que correspondem aos bits RB0, RB1, RBA2, RB3, RB4, RB5, RB6 e RB7 respectivamente. Todos os pinos de PORTB podem enviar e receber dados.

Vamos escrever o programa "piscaLED" usando o modelo fornecido pelo MPLAB. Abra o arquivo "16F628ATEMP.ASM" no edidor de texto do MPLAB como explicado anteriormente.

Praticamente não vamos precisar de todas as linhas do modelo. Para começar, apague tudo e escreva o trecho de programa abaixo. Esse trecho é simplesmente a configuraçao inicial conforme explicado anteriormente. Atenção especial deve ser dada a linha 8, que define as características do microcontrolador para este projeto. Nela, opção _INTOSC_OSC_NOCLKOUT indica que usaremos o clock interno de 4MHz que elimina a necessidade de construirmos um clock externo.

01 ; ----------------------------------------------------------
02 ; PROGRAMA piscaLED
03 ; ----------------------------------------------------------
04   list      p=16F628A              ; list directive to define processor
05   #include <p16F628A.inc>          ; processor specific variable definitions
06   errorlevel  -302                 ; suppress message 302 from list file
07 ;
08   __CONFIG   _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT
09 ;

A seguir vamos definir alguns campos na memória para uso do programa. O comando UDATA na linha 13 indica que os campos serão colocados a partir da localização 0x20 da memória de dados. Os comandos RES definem os campos "aux1" e "aux2" com tamanho de 1 byte cada um.

10 ; ----------------------------------------------------------
11 ;  DEFINICAO DE MEMORIA DE DADOS
12 ; ----------------------------------------------------------
13                 UDATA        0x20
14 aux1            RES          1
15 aux2            RES          1
16 ;

A seguir, definiremos os vetores de reset e interrupção. Este trecho de programa introduz o comando CODE que identifica a posição da memória de programa onde serão colocadas as instruções que o seguem. O reset vector, identificado pelo label RESET_VECTOR, é definido na localização 0x00 da memória de programa onde há apenas a instrução "goto leds", na linha 21, que desvia o controle para a instrução da linha 27.

Na linha 22, o comando CODE coloca o interrupt vector, identificado pelo label INT_VECTOR, na localização 0x004 da memória de programa. Como não usaremos interrupções neste programa, apenas codificaremos a instrução retfie na linha 23. O controle jamais passará por esta instrução mas, por convenção, vamos manter essa instrução nesta posição.

17 ; ----------------------------------------------------------
18 ; RESET E INTERRUPT VECTOR
19 ; ----------------------------------------------------------
20 RESET_VECTOR    CODE    0x000
21                 goto    leds
22 INT_VECTOR      CODE    0x004
23                 retfie

Como foi dito antes, o PIC16F628A possui dois registradores de 8 bits: RA e RB. É através desses registradores, que o microcontrolador se comunica com o mundo externo e vice-versa.
Mas como o microcontrolador pode saber se, num determinado momento, é para ele pegar um dado no mundo externo e trazê-lo para dentro ou enviar um dado, que possui, para o mundo externo? Essa tarefa é controlada por dois registradorers especias chamados TRISA e TRISB. O registrado TRISA controla como se comportarão os bits do PORTA e o registrado TRISB controla como se comportarão os bits do PORTB.
A cada bit do registrador PORTA (RA7, RA6, RA5, RA4, RA3, RA2, RA1, RA0) corresponde um bit no resgistrador TRISA.
Para dizer ao microcontrolador que um bit é uma entrada, o bit correspondente em TRISA deve ser ligado.
Para dizer ao microcontrolador que um bit é uma saída, o bit correspondente em TRISA deve ser desligado.
O mesmo vale para o resitrador PORTB.

Assim, se quisermos que o bit 3 do registrador PORTB funcione como entrada, fazemos o bit correspondente de TRISB igual a 1.

             PORTB
       ----------------------
BIT    7  6  5  4  3  2  1  0
TRISB  .  .  .  .  1  .  .  .

Se quisermos que o bit 5 do registrador PORTA funcione como saída, fazemos o bit correspondente de TRISA igual a zero.

             PORTA
       ----------------------
BIT    7  6  5  4  3  2  1  0
TRISA  .  .  0  .  .  .  .  .

Com a explicação acima podemos prosseguir com o próximo trecho de programa que esta logo abaixo.
Na linha 27 e 28 temos duas instruções de movimentação: a primeira, na linha 27, movlw 0x07 carrega o valor 7 no registrador W e a segunda, movwf CMCON move o conteúdo do registrador W para o registrador especial CMCON. O propósito dessas duas instruções é desativar os comparadores que ficam ativados quando o microcontrolador é ligado ou sofre um reset.

Na linha 29, a instrução bsf STATUS,RP0 chaveia para o banco de memória número 1 a fim de poder acessar os registradores TRISA e TRISB que se encontram nesse banco.
As linhas 30 e 31 contêm as instruções clrf TRISA e clrf TRISB que zeram esses registradores fazendo com que todos os bits de PORTA e PORTB sejam saídas.
Na linha 32, a instrução bcf STATUS,RP0 volta o acesso ao banco zero da memória de dados.
Na linha 33, a instrução clrf PORTB move zeros para todos os bits de PORTB.

24 ; ----------------------------------------------------------
25 ; CONFIGURACAO INICIAL
26 ; ----------------------------------------------------------
27 leds            movlw   0x07
28                 movwf   CMCON
29                 bsf     STATUS,RP0
30                 clrf    TRISA
31                 clrf    TRISB
32                 bcf     STATUS,RP0
33                 clrf    PORTB

A seguir, temos a rotina principal do nosso programa.
Na linha 37, a instrução bsf PORTB,5 liga o bit 5 do registrador PORTB que faz acender o LED conectado ao pino 11.
A instrução da linha 38, call tempo faz uma chamada à subrotina tempo na linha 45.
A linha 39 apaga o LED com a instrução bcf PORTB,5 que leva o bit 5 ao nível baixo (zero volt).
A instrução da linha 40, call tempo faz uma nova chamada à subrotina tempo na linha 45.
A instrução na linha 41, goto loop, desvia o controle para o label loop na linha 37 fazendo processo se repetir indefinidamente.

34 ; ----------------------------------------------------------
35 ; ROTINA PRINCIPAL
36 ; ----------------------------------------------------------
37 loop            bsf     PORTB,5
38                 call    tempo
39                 bcf     PORTB,5
40                 call    tempo
41                 goto    loop

Aqui cabe uma explicação sobre a chamada da subrotina tempo. O microcontrolador pode trabalhar com clock cuja frequência máxima atinge até 20MHz, porém, neste programa, ele esta trabalhando com um clock interno definido pelo parâmetro _INTOSC_OSC_NOCLKOUT na linha 8 do programa. O clock interno do PIC16F628A tem uma frequência de 4MHz que, devido a arquitetura do microcontrolador, é dividido por 4, dando uma frequência final de 1MHz. Como cada instrução é executada durante um ciclo de clock, exceto as instruções call, goto, return e retfie que consomen 2 ciclos, elas levam 1us (micro segundo) para serem executadas. Não seria possível um ser humano ver o LED acender e apagar num tempo tão curto consumido pela rotina principal do programa da linha 37 a 41 que leva aproximadamente 8us (micro segundos) para executar. Sendo assim, não há outra maneira de permitir que o LED seja visto ora aceso ora apagado a não ser que se faça com que o microcontrolador perca tempo executando uma subrotina de consumo de tempo. A subrotina tempo é usada justamente para cumprir esse requisito.

A subrotina tempo leva aproximadamente 200ms (mili segundos) para ser executada, tempo suficiente para o olho humano perceber que o LED ora esta aceso ora apagado.

42 ; ----------------------------------------------------------
43 ; ROTINA DE TEMPO
44 ; ----------------------------------------------------------
45 tempo           movlw   0x3E
46                 movwf   aux1
47                 movlw   0x9D
48                 movwf   aux2
49 tempo1          decfsz  aux1,f
50                 goto    $+2
51                 decfsz  aux2,f
52                 goto    tempo1
53                 goto    $+1
54                 nop
55                 return

END, na linha 57, encerra o programa informando o compilador que após essa linha não há mais instruções.

56 ;
57                 END




  1. INTRODUÇÃO
  2. RECURSOS
  3. ARQUITETURA
  4. ENDEREÇAMENTO
  5. INTERRUPÇÕES
  6. NÍVEIS DE INTERRUPÇÕES NA FAMÍLIA 18F
  7. RESETS DO MICROCONTROLADOR
  8. MODO SLEEP
  9. WATCHDOG TIMER
  10. O STACK
  11. A LINGUAGEM ASSEMBLER
  12. MPLAB - Criando Projetos
  13. LIBRARIES - Usando Bibliotecas de Funções

H P S P I N

Desde 04 de Março de 2010

Atualização: 18 de Apr de 2024