Vous êtes sur la page 1sur 11

SM1 - Parobé

Sistemas Microcontrolados 1 – Parobé É nela que vamos escrever os codigos e compila-los


Introdução a Programação para PIC18F4550 para que depois possamos testa-lo no PIC.

1. O microcontrolador: 4. O Compilador:
Um microcontrolador (também denominado MCU) é O nome "compilador" é usado principalmente para os
um computador-num-chip, contendo um processador, programas que traduzem o código fonte de
memória e periféricos de entrada/saída. uma linguagem de programação de alto nível para
É um microprocessador que pode ser programado para uma linguagem de programação de baixo nível.
funções específicas, em contraste com outros Utilizamos o XC8, também da Microchip, por ser
microprocessadores de propósito geral (como os gratuito e de fácil utilização.
utilizados nos PCs). Eles são embarcados no interior
de algum outro dispositivo (geralmente um produto 5. Arquivos de Cabeçalho ou Bibliotecas:
comercializado) para que possam controlar as funções São arquivos .h com codigos criados para implementar
ou ações do produto. Um outro nome para o algumas funções ou ativa-las no microcontrolador.
microcontrolador, portanto, é controlador embutido. Muitos destes arquivos ja estão disponíveis quando
instalamos o compilador, mas podemos criar funções e
2. O microcontrolador PIC: utilizalas como arquivos de cabeçalho.
Os PIC são uma família Uma destas funções é a de configuração do PIC para
de microcontroladores fabricados pela Microchip utilização. Esta função foi disponibilizada pelo
Technology, que processam dados de 8 bits, de 16 bits professor da disciplina e encontra-se disponível em seu
e, mais recentemente, de 32 bits. Seu nome é oriundo blog e também no meu.
de "Programmable Interface Controller" (Controlador de #include "C:\headers\fuses\config_PIC18F4550.h"
Interface Programável). Contam com extensa //configura os fuses do pic
variedade de modelos e periféricos internos. Deve ser indicado o endereço onde se encontra a
função.
3. A IDE: #include <stdio.h> // entradas e saidas padrão do C
Utilizamos na disciplina a IDE MPLAB X, da Microchip, #include <stdlib.h> // não lembro quais funções são
que podemos obter gratuitamente atravez do site da liberadas
propria fabricante. Estas outras duas bibliotecas são mais conhecidas
IDE significa Integrated Development Evironment, ou pois também as utilizamos em Informática Básica.
seja Ambiente de Desenvolvimento Integrado. #include <p18f4550.h>// header especifico do 4550
#include <pic18.h>// header da familia 18
IC Salgado
SM1 - Parobé

Já estas são bibliotecas especificas para que o Sintaxe:


compilador indentifique qual o modelo de #define apelido PORTXbits.RXY
microcontrolador estamos utilizado e aplique as Onde X indica o PORT desejado (A, B, C, D ou E) e Y
configurações necessárias, além de disponibilizar indica o terminal deste PORT (varia de 0 a 7)
algumas funções que utilizaremos. Neste caso estou atribuindo a palavra apelido ao
terminal Y do PORTX
6. PORTs: Exemplo:
O PIC18F4550 possui 5 ports, que são blocos de #define power PORTCbits.RC0 //define RC0
terminais destinados a entradas e saidas, podendo ser como led indicador de maquina ligada
digitais ou analógicas, conforme a necessidade e a
configuração desejada. 8. Definindo entradas e saidas - TRIS:
Os PORTs são divididos sequencialmente em ordem Chamamos de entradas todas as informações que o
alfabetica: microcontrolador irá receber de um meio externo, como
PORTA – 7 terminais utilizáveis; por exemplo um botão que pode enviar nivel lógico alto
PROTB – 7 terminais utilizáveis; ou baixo.
PORTC – 6 terminais utilizáveis; As saidas são informações que o microcontrolador
PORTD – 8 terminais utilizáveis; processa e emite por meio de seus terminais, como por
PORTE – 3 terminais utilizáveis; exemplo um Led que pode receber nivel lógico alto ou
baixo.
Na verdade podemos reparar no Datasheet que estes Precisamos informar ao nosso compilador quais
PORTs possuem mais terminais do que eu indiquei terminais ou PORTs desejamos configurar como
porém, alguns destes terminais ja são utilizados para entradas ou saidas.
outras funções em nossa placa, então é melhor deixa- Definindo todo o PORT como entrada ou saida:
los de fora. TRISA = 0x00; //saida
TRISB = 0xFF; //entrada
7. Definindo ‘apelidos’ para os terminais: No primeiro exemplo configuramos todo o PORTA
O compilador ja define um nome para cada terminal de como saida, ou seja, ele não recebe informações,
nosso PIC, mas para facilitar a programação e apenas as emite. E no segundo exemplo configuramos
leiturado codigo e uma possível alteração de terminais, o PORTB como entrada, ou seja, recebe informações.
utilizaremos a função #define que define um apelido Nestes dois exemplos utilizamos a configuração em
para o terminal que podemos utilizar em todo nosso hexadecimal (0x00).
programa. Definindo terminais específicos como entrada ou saida:
IC Salgado
SM1 - Parobé

TRISA = 0b00000000; While(1)


TRISAbits.RA0 = 0x00; {
TRISB = 0b11111111; //sequencia de comandos
TRISBbits.RB0 = 0xFF; }
Nos dois primeiros exemplos temos maneiras de
configurar os terminais como saidas. O primeiro Quando o PIC for iniciado o programa entrará neste
exemplo indica em binário, bit a bit, a configuração de while e verificará se 1 é verdadeiro, como não existe
cada um e no segundo configuramos o terminal RA0 nenhum outro parametro para ser verificado, o
do PORTA como saida. Nos outros dois exemplos resultado será sempre verdadeiro, obrigando o
configuramos o PORTB e o terminal RB0 de forma programa a executar infinitamente os camandos dentro
semelhante, porém, os definimos como entrada. do bloco.
Para definir os terminais de um PORT como entrada ou Estrutura do programa até agora
saida usando a configuração em binário (0b00000000),
devemos considerar a sequencia do bit menos #includes
significativo até o bit mais significativo. #defines

9. Loop Infinito: int main()


A linguagem C trabalha de forma sequencial, ou seja, {
executa as funções linha por linha de cima para baixo, TRISxxxxxxxx;
e no fim do codigo ela encerra a excução. Para while(1)
utilizarmos a linguagem de forma eficiente no {
microcontrolador devemos escrever nosso codigo
dentro de um loop infinito, para que o PIC possa }
executar todas as funções e no fim voltar ao inicio e }
executa-las novamente.
O loop infinito é um comando de repetição que verifica 10. Criando um novo projeto:
uma condição que sempre dará verdadeira. A maneira Vamos a prática:
mais comum de implementarmos este loop é utilizando Para criar um novo projeto no MPLAB X devemos
o comando while() da seguinte forma: seguir os seguintes passos, alem de abrir o programa
claro:

IC Salgado
SM1 - Parobé

File>New Project>Microchip Embedded>Standalone Eu costumo fazer algumas alterações iniciais e ja


Project>Advanced 8-bit MCUs incluo alguns arquivos de cabeçalho que talvez
(PIC18)>PIC18F4550>ID3>XC8>”nome”>finish. precise.
/*
Vou colocar no blog e junto com a pasta compactada * File: tutorial.c
os prints deste processo. * Author: ICSalgado
Agora vamos criar, dentro deste projeto o nosso *
programa principal, onde vamos escrever nosso * Created on 16 de Novembro de 2013, 04:38
codigo. */

Source Files>New>C Main File #include <stdio.h> // entradas e saidas padrão do C


#include <stdlib.h> // não lembro quais funções são
Clicar com o botão direito do mouse em Source Files. liberadas

Esta é a cara inicial do programa #include <p18f4550.h>// header especifico do 4550


/* #include <pic18.h>// header da familia 18
* File: tutorial.c
* Author: ICSalgado #include <delays.h>//Aciona a biblioteca de delay real
*
* Created on 16 de Novembro de 2013, 04:38 #include "adc.h" //conversor analógico digital
*/ #include "C:\headers\fuses\config_PIC18F4550.h"
//configura os fuses do pic
#include <stdio.h> #include "C:\headers\lcd\biblioteca_lcd_2x16.h"
#include <stdlib.h> //biblioteca padrão do lcd no PORTD

/* #include <xc.h> //não sei pq, mas tava no exemplo do


* professor de interrupções
*/
int main(int argc, char** argv) { #define Fosc 20 //define frequencia do oscilador

return (EXIT_SUCCESS); /*
} * Tentativa de ajuda
IC Salgado
SM1 - Parobé

*/ 11. Prática 1 – Liga Led:


Criei o seguinte codigo para ser compilado e testado
posteriormente. O objetivo é ligar um LED no pino RA0
int main() do PORTA:
{ OBS: Como não vamos utilizar entradas analógicas
OpenADC (0x00, 0x00, ADC_0ANA);//Algo do nesta disciplina devemos desligar esta função par que
conversor analógico digital possamos utilizar os pinos AN como entradas e saidas
CloseADC ( );//só consigo usar os pinos AN com digitais. Observe os comentarios nos codigos:
isso /*
while(1) * File: tutorial.c
{ * Author: ICSalgado
*
} * Created on 16 de Novembro de 2013, 04:38
*/
return (EXIT_SUCCESS);
} #include <stdio.h> // entradas e saidas padrão do C
Podemos perceber que o MPLAB facilita um pouco a #include <stdlib.h> // não lembro quais funções são
nossa vida, abrindo e fechando os blocos de funções e liberadas
com cores diferentes.
#include <p18f4550.h>// header especifico do 4550
Bom este é o incio e todo programa que eu faço para #include <pic18.h>// header da familia 18
PIC segue este mesmo roteiro com este codigo, vem
dando certo até agora. #include <delays.h>//Aciona a biblioteca de delay real

Outra mania que tenho, e que acho válida é compilar o #include "adc.h" //conversor analógico digital
programa toda hora, para saber se tem algo errado no #include "C:\headers\fuses\config_PIC18F4550.h"
codigo que escrevi, fica mais facil de achar um erro se //configura os fuses do pic
você precisar verificar menos alterações entre cada #include "C:\headers\lcd\biblioteca_lcd_2x16.h"
compilação. //biblioteca padrão do lcd no PORTD
Para compilar um programa no MPLAB podemos clicar
no martelinho na barra superior de ferramentas ou no #include <xc.h> //não sei pq, mas tava no exemplo do
martelinho com a vassoura, ao lado do anterior. professor de interrupções
IC Salgado
SM1 - Parobé

12. Simulação:
#define Fosc 20 //define frequencia do oscilador Para simularmos esse programa na prática usaremos o
Software ISIS – PROTEUS, esse programa não é
#define led PORTAbits.RA0 //atribui a palavra led ao gratuito então é preciso compra-lo ou procurar
pino RA0 ‘soluções’ na internet.
- Em ‘devices’ clicamos no botão ‘P’ e procuramos pelo
/* PIC18F4550 e um LED – BLUE, ou de outra cor
* Tentativa de ajuda qualquer;
*/ - Clique duas vezes no componente encontrado e ele
aparecerá na barra de ferramentas lateral, depois
feche a janela de busca de componentes;
int main() - Clique em cima do componente desejado e depois
{ clique na area quadriculada o componente ira aparecer
TRISAbits.RA0 = 0x00; //define o pino RA0 como como sombra e com mais um clique ele fica onde for
saida desejado;
OpenADC (0x00, 0x00, ADC_0ANA);//Algo do - Posicione os componentes dentro do bloco quadrado
conversor analógico digital que aparece;
CloseADC ( );//só consigo usar os pinos AN com - Em ‘Terminals’ selecione ‘POWER’ e coloque proximo
isso do pino 1 do PIC (MCLR) e ‘GROUND’ proximo do
while(1) catodo do LED;
{ - Agora ligue os pontos entre os terminais;
led = 1; //atribui o valor 1 ao led que esta - Após, clique com o botão direito no POWER e em
conectado no pino RA0, este valor significa nivel alto string digite +5v;
} - Na simulação não é necessário o uso de resistores
limitadores de corrente para o led, mas na prática é
return (EXIT_SUCCESS); obrigatório o uso.
} - Agora vamos colocar o codigo HEX compilado dentro
do PIC clicando com o botão direito em cima do PIC,
Agora tente alterar os pinos e os ports para ligar este em Edit Properties, na pastinha ao lado de Program
led. File, depois encontre o programa com extensão .hex,
selecione e pronto, é só dar OK;
- Clique no Play e o LED deverá Acender.
IC Salgado
SM1 - Parobé

13. Função de Tempo:


O compilador XC8 traz uma biblioteca que trabalha #include <p18f4550.h>// header especifico do 4550
com os ciclos de funcionamento do PIC, que podemos #include <pic18.h>// header da familia 18
utilizar como delay.
Esta biblioteca é a <delays.h>. #include <delays.h>//Aciona a biblioteca de delay real
Criei a segunte função que gera 1 segundo de delay:
#include "adc.h" //conversor analógico digital
int tempo(int t)// função gera delay de t segundos #include "C:\headers\fuses\config_PIC18F4550.h"
{ //configura os fuses do pic
int i;//variavel de controle #include "C:\headers\lcd\biblioteca_lcd_2x16.h"
for(i=0;i<t;i++)//contador de vezes de execução //biblioteca padrão do lcd no PORTD
{
Delay10KTCYx(500); // gera 1 segundo de delay #include <xc.h> //não sei pq, mas tava no exemplo do
} professor de interrupções
}
#define Fosc 20 //define frequencia do oscilador
Ao chamar a função mandamos o parametro t
indicando quantos segundos desejamos para delay. #define led PORTAbits.RA0 //atribui a palavra led ao
pino RA0
14. Prática 2 – Pisca Led:
O seguinte codigo faz piscar o led na mesma /*
simulação anterior: * Tentativa de ajuda
/* */
* File: tutorial.c int tempo(int t)// função gera delay de t segundos
* Author: ICSalgado {
* int i;//variavel de controle
* Created on 16 de Novembro de 2013, 04:38 for(i=0;i<t;i++)//contador de vezes de execução
*/ {
Delay10KTCYx(500); // gera 1 segundo de delay
#include <stdio.h> // entradas e saidas padrão do C }
#include <stdlib.h> // não lembro quais funções são }
liberadas
IC Salgado
SM1 - Parobé

int main() #include <stdio.h> // entradas e saidas padrão do C


{ #include <stdlib.h> // não lembro quais funções são
TRISAbits.RA0 = 0x00; //define o pino RA0 como liberadas
saida
OpenADC (0x00, 0x00, ADC_0ANA);//Algo do #include <p18f4550.h>// header especifico do 4550
conversor analógico digital #include <pic18.h>// header da familia 18
CloseADC ( );//só consigo usar os pinos AN com
isso #include <delays.h>//Aciona a biblioteca de delay real
while(1)
{ #include "adc.h" //conversor analógico digital
led = 1; //atribui o valor 1 ao led que esta #include "C:\headers\fuses\config_PIC18F4550.h"
conectado no pino RA0, este valor significa nivel alto //configura os fuses do pic
tempo(1); //gera um delay de 1 seundo #include "C:\headers\lcd\biblioteca_lcd_2x16.h"
led = 0; //desliga o led //biblioteca padrão do lcd no PORTD
tempo(1); //gera um delay de 1 seundo
} #include <xc.h> //não sei pq, mas tava no exemplo do
professor de interrupções
return (EXIT_SUCCESS);
} #define Fosc 20 //define frequencia do oscilador

15. Prática 3 – Liga led com botão: #define led PORTAbits.RA0 //atribui a palavra led ao
O seguinte codigo liga o led quando o botão está pino RA0
ligado. Lembrando que o LED deve ser configurado #define botao PORTAbits.RA1 // atribui a palavra botão
como saida e o botão deve ser configurado como ao pino RA1
entrada. /*
/* * Tentativa de ajuda
* File: tutorial.c */
* Author: ICSalgado
* int main()
* Created on 16 de Novembro de 2013, 04:38 {
*/ TRISAbits.RA0 = 0x00; //define o pino RA0 como
saida
IC Salgado
SM1 - Parobé

TRISAbits.RA1 = 0xFF; // define RA1 como entrada * Created on 16 de Novembro de 2013, 04:38
OpenADC (0x00, 0x00, ADC_0ANA);//Algo do */
conversor analógico digital
CloseADC ( );//só consigo usar os pinos AN com #include <stdio.h> // entradas e saidas padrão do C
isso #include <stdlib.h> // não lembro quais funções são
while(1) liberadas
{
while(botao == 1) #include <p18f4550.h>// header especifico do 4550
{ #include <pic18.h>// header da familia 18
led = 1; //atribui o valor 1 ao led que esta
conectado no pino RA0, este valor significa nivel alto #include <delays.h>//Aciona a biblioteca de delay real
}
led = 0; // desliga o led #include "adc.h" //conversor analógico digital
} #include "C:\headers\fuses\config_PIC18F4550.h"
//configura os fuses do pic
return (EXIT_SUCCESS); #include "C:\headers\lcd\biblioteca_lcd_2x16.h"
} //biblioteca padrão do lcd no PORTD

16. Interrupções: #include <xc.h> //não sei pq, mas tava no exemplo do
As interrupções são funções que tem prioridade maior professor de interrupções
do que o codigo que esta rodando, quando ela é
chamado o programa para a execução do codigo #define Fosc 20 //define frequencia do oscilador
principal e executa a rotina de interrupção, ao fim desta
o programa volta ao codigo principal. #define led PORTAbits.RA0 //atribui a palavra led ao
Elas podem ser de alta e baixa prioridade e existem pino RA0
pinos especificos para as interrupções externas. #define ledint1 PORTAbits.RA1 // atribui a palavra
O seguinte programa implementa interrupções de alta ledint1 ao pino RA1
e baixa prioridade. #define ledint2 PORTAbits.RA2 // atribui a palavra
/* ledint2 ao pino RA2
* File: tutorial.c
* Author: ICSalgado #define int1 PORTBbits.RB1 // define RB1 como botão
* de interrupção
IC Salgado
SM1 - Parobé

#define int2 PORTBbits.RB2 // define RB2 como botão {


de interrupção while(int2 == 0)
/* {
* Tentativa de ajuda //pisca led 2 quando a interrupção é ativada
*/ ledint2 = 1;
tempo(1);
int tempo(int t)// função gera delay de t segundos ledint2 = 0;
{ tempo(1);
int i;//variavel de controle }
for(i=0;i<t;i++)//contador de vezes de execução INTCON3bits.INT2IF = 0; // Limpa o flag bit da
{ interrupção externa INT1
Delay10KTCYx(500); // gera 1 segundo de delay }
}
} void config_int(void) {
RCONbits.IPEN = 1; // Habilita interrupção com nível
void interrupt int_alta(void) // interrupção de alta de prioridade. End 0x08 - alta e 0x18 - baixo
prioridade - botão liga desliga INTCONbits.GIEH = 1; // Habilita todas as
{ interrupções de alta prioridade
while(int1 == 0) INTCONbits.GIEL = 1; // Habilita todas as
{ interrupções de baixa prioridade
// pisca led 1 quando a interrupção é acionada }
ledint1 = 1;
tempo(1); void config_int1(void) {
ledint1 = 0; INTCON3bits.INT1IE = 1; // Ativa a inerrupção
tempo(1); externa INT1 (RB1)
} INTCON3bits.INT1IF = 0; // Limpa o flag bit da
INTCON3bits.INT1IF = 0; // Limpa o flag bit da interrupção externa INT1
interrupção externa INT1 INTCON3bits.INT1IP = 1; // Define como "Alta
} prioridade"
INTCON2bits.INTEDG1 = 0; // Interrupção externa
void interrupt low_priority int_baixa(void) // interrupção INT1 na borda de descida
de baixa prioridade - tampa }
IC Salgado
SM1 - Parobé

led = 0;
void config_int2(void) { tempo(1);
INTCON3bits.INT2IE = 1; // Ativa a inerrupção }
externa INT2 (RB2)
INTCON3bits.INT2IF = 0; // Limpa o flag bit da return (EXIT_SUCCESS);
interrupção externa INT2 }
INTCON3bits.INT2IP = 0; // Define como "Baixa
prioridade"
INTCON2bits.INTEDG2 = 0; // Interrupção externa
INT2 na borda de descida
}

int main()
{
TRISA = 0x00; //define PORTA como saida
TRISB = 0xFF; //define PORTB como entrada

config_int(); // configura os tipo de interrupção


config_int1(); // configura e incializa a int 1
config_int2(); // configura e incializa a int 2

ei(); // inicializa o serviço de interrupções

OpenADC (0x00, 0x00, ADC_0ANA);//Algo do


conversor analógico digital
CloseADC ( );//só consigo usar os pinos AN com
isso
while(1)
{
//pisca led
led = 1;
tempo(1);
IC Salgado

Vous aimerez peut-être aussi