Vous êtes sur la page 1sur 39

LINGUAGEM C ANSI PARA MICROCONTROLADOR

PIC18F4550

Belo Horizonte
Março de 2010
LINGUAGEM C ANSI PARA MICROCONTROLADOR
PIC18F4550

Diego Carradi
Luiz Cláudio do Nascimento

Relatório apresentado à PICMINAS®


como requisito para conclusão de curso
de Microcontroladores PIC18F4550 em
linguagem C ANSI.

Belo Horizonte
Março de 2010
RESUMO

Este projeto tem como escopo principal, a utilização do


microcontrolador PIC18F4550 como unidade central para o
processamento e controle de transporte vertical (elevadores) com as
seguintes vantagens:
 A aplicação reduz o custo final evitando a utilização de micro
controlador específicos.
 O circuito eletrônico adicional é de baixo custo.
 O circuito eletrônico adicional é de uso geral facilmente encontrado no
mercado comercial.
 Os periféricos possuem uma rampa de mudança de estado de 23ns bem
inferior a velocidade do PIC garantindo estabilidade ao sistema.
 A programação pode ser feita on –board através de conectores USB 1.
 Para mais de um elevador pode ser feito Softwares específicos para
controle de tráfego e até mesmo funções especiais de manobras via PC 2

1
USB - Universal Serial Bus
2
PC – Computadores Compactos
SUMÁRIO
1. INTRODUÇÃO 03
2 CONSIDERAÇÕES 03
3 PLATAFORMAS DE SIMULAÇÃO 03
®
3.1 PROTEUS 7.2 SP6 03
®
3.1.1 AMBIENTE DE TRABALHO PROTEUS 7.2 SP6. 04
3.1.2 ARQUIVO DE COMANDO DE IMPRESSÃO 04
3.1.3 COMANDOS DE EXPOSIÇÃO 04
3.1.4 PRINCIPAIS COMANDOS 04
3.1.5 ICONES DO DISPOSITIVO 05
3.1.6 GRÁFICOS 2D 05
3.1.7 FERRAMENTAS DO PROJETO 05
3.1.8 EDIÇÃO DE COMANDOS 06
3.1.9 ESPELHO E GIRAR ICONES 06
3.2 INTRODUÇÃO DE OPERAÇÃO DO PROTEUS NO MODO ISIS COM
MICROCONTROLADORES 06
3.2.3 CARREGAR O PROGRAMA COM OS DADOS “. HEX”
GERADOS NO MPLAB® 11
4 PLATAFORMAS DE PROGRAMAÇÃO C ANSI. 12
4.1 MPLAB® 12
4.1.1 CARREGANDO PROJETOS NO MPLAB ® 13
4.2 MCC18® 17
5 APRESENTAÇÃO DO 74HS594 17

5.1. ESQUEMA ELETRÔNICO 17

5.2. FUNCIONAMENTO. 18

6 APRESENTAÇÃO DO PROJETO 18
7 APRESENTAÇÃO DO PROGRAMA ESCRITO EM LINGUAGEM C ANSI. 18

7.1 DEFINES 18

7.2 VARIÁVEIS 19

7.3 ZERANDO VARIAVEIS, PORTAS E REGISTRADORES PARA INICIALIZAR COMANDOS.


19

7.4 PREPARA PORTA PARA POCICIONAR CABINE DO ELEVADOR NA PRIMEIRA PARADA


21

7.5 DETECTA FALHA AO FECHAR A PORTA 22

7.6 PROCEDIMENTO PARA ASCENDER LED DE FALHA DENTRO DO WHILE 22

7.7 STOP DA CABINE NA POSIÇÃO INFERIOR 23

7.8 PROCEDIMENTO PARA ASCENDER LED DE FALHA DENTRO DO WHILE 24

7.9 STOP DA CABINE NA POSIÇÃO INFERIOR 25

7.10 NIVELA A CABINE PARA POSIÇÃO DA PRIMEIRA PARADA 25

7.11 PREPARA PARA ABRIR PORTA 25


7.12 DETECTA FALHA AO ABRIR A PORTA 26

7.13 PROCEDIMENTO PARA ASCENDER LED DE FALHA DENTRO DO WHILE 26

7.14 A EXECUTA LAÇO DE PROGRAMAÇÃO DEFININDO FUNÇÃO PARA IDENTIFICAÇÃO DE


ANDAR 27

7.15 A FAZ VARREDURA NOS BOTÕES DE CHAMADA 27

7.16 TRANFERE ESPELHO DE CHAMADAS PARA VARIÀVEL DADOS 28

7.17 REGISTRA CHAMADAS DE CABINE 28

7.18 IDENTIFICA DIREÇÃO DE CHAMADAS SUBIDA OU DESCIDA 29

7.19 COMANDO DE ALTA VELOCIDADE 29

7.20 PREPARA PARADA COM REVERSÃO DE DIREÇÃO DESCIDA OU SUBIDA 30

7.21 PREPARACAO_DE_PARADA NA MESMA DIREÇÃO 31

7.22 PARADA 31

7.23 CANCELANDO CHAMADA 31

7.24 ABRE PORTA 32

7.25 FECHA PORTA 32

7.26 CONFIGURA SISTEMA 32


8 CONSIDERAÇÕES FINAIS OU CONCLUSÃO 33
9 REFERÊNCIAS BIBLIOGRÁFICAS 34
1. INTRODUÇÃO

O uso de microcontroladores específicos com grandes números de saídas e


entradas com gravação do programa off-board vem sendo largamente utilizado na
área de transporte vertical, no entanto é possível obter o mesmo efeito com
qualidade , confiabilidade e significativa redução de custo, utilizando o PIC18F4550,
além da possibilidade de gravação on-board.
A idéia central é realizar pequenos protocolos de comunicação serial de forma a
manter a velocidade de processamento vantajosa do PIC que mesmo com atrasos
de leituras seriais ainda é superior aos que hoje são utilizados.
O projeto final apresentará recursos técnicos capaz de comunicar e interagir com as
portas do PIC de forma a multiplicar a sua gama de monitoramento e comando.

2 CONSIDERAÇÕES

Para melhor apresentação deste relatório as figuras serão apresentadas conforme


desenvolvimento do documento e não em anexo conforme norma.

3 PLATAFORMAS DE SIMULAÇÃO

O projeto será simulado e processado com as seguintes ferramentas

3.1 PROTEUS® 3 7.2 SP6

Esta plataforma permite a simulação de uma gama de circuitos eletrônicos com uma
precisão de até 98% de confiabilidade depois de calculado as faixas de tolerância
dos componentes empregados.
Em anexo 1 encontra-se passo a passo a utilização do Proteus ® neste projeto.

3
Plataforma de simulação eletrônica ISIS
4

3.1.1 AMBIENTE DE TRABALHO PROTEUS® 7.2 SP6.

3.1.2 ARQUIVO DE COMANDO DE IMPRESSÃO

Novo Abrir Salvar Imprimir Área de Seção de Seção de


Impressão Importação Exportação

3.1.3 COMANDOS DE EXPOSIÇÃO

Refazer Grade Origem Cursor Bandeja Aumentar Diminuir Visualizar Lupa

3.1.4 PRINCIPAIS COMANDOS

Componente Ponto de Etiqueta Certificado Barra de Circuito Edição


Junção Transporte Secundário
5

3.1.5 ICONES DO DISPOSITIVO

Terminais Pino Gráfico Fita Adesiva Gerador Ponta de Ponta de Multímetro


Dispositivo Prova Voltagem Prova Corrente

3.1.6 GRÁFICOS 2D

Linha Caixa Circulo Arco Trajeto 2D Texto Símbolo

3.1.7 FERRAMENTAS DO PROJETO

Tempo Real Snap Fio Roteador Busca Pesquisa Propriedade de Ferramentas

Nova Folha Deletar Folha Anterior Desfazer Ação Impossível Desfazer

Valor do Material Verificação Elétrica das Trilhas Lista Líquida Ares


6

3.1.8 EDIÇÃO DE COMANDOS

Estes afetam todos os objetos atualmente etiquetados.

Cópia Bloco Movimenta Deletar Bloco Girar o Bloco Seleção Dispositivo Fazer o Dispositivo Decompor
Bloco Símbolo

Pacote de Ferramentas Undo Redo Recortar Cópia Pasta

3.1.9 ESPELHO E GIRAR ICONES

Girar no Sentido Horário Girar Anti-Horário Linha central de X linha central da aleta Y

3.2 Introdução de operação do Proteus no modo ISIS com


microcontroladores

Com o programa instalado vá até o menu iniciar e clique sobre o ícone ISIS
7

Depois do programa aberto clique em file e escolha a opção “New design”

Nesta tela selecione o formato da pagina ideal ao seu projeto e clique em OK.
8

As margens da área de trabalhos serão delineadas com as medidas selecionadas

Obs.: Pode-se aumentar à visibilidade da área de trabalho alterando o zoom com a


movimentação do botão rotativo do mouse.

Selecione “Component Mode” através do ícone localizado na barra lateral direita da


tela do programa para trabalhar em modo de manipulação de componentes e
clique em “P”
9

Neste instante aparecerá a seguinte tela:


Nela digite o componente a ser utilizado, usando o campo “Keywords” (indicação 1),
observe que o programa identificará o componente da biblioteca e o mostrará no
campo “Results” (indicação 2) e entre parênteses na frente deste aparecerá a
quantidade de resultados encontrados (indicação 3), no PAD abaixo será indicado a
especificação detalhada dos componentes encontrados (indicação 4),.
Neste momento identifique o componente a ser utilizado usando o campo quatro (4)
e de dois clique sobre o mesmo.

1 2 3 4

Neste campo poderá existir mais de um


componente de acordo com a sua biblioteca

Observe agora que o componente selecionado ocupou o campo “DEVICE” e esta


disponível para ser utilizado.
Repita os passos para adicionar ao “DEVICE” os outros componentes a serem
utilizados durante a construção do projeto, em seguida clique em “OK” para retornar
a tela de trabalho.
10

Já na tela de trabalho sobre o campo “DEVICE” selecione com o mouse o


componente a ser colocado na área de trabalho

Logo em seguida dê apenas um clique no botão direito do mouse sobre a área de


trabalho (figura acima). Observe que o escopo do componente aparecerá na cor
rosa e poderá ser movimentado para qualquer lugar dentro desta área, escolha o
local e dê mais um clique para fixá-lo no ponto escolhido.

Obs.: Para girar ou inverter os lados de um componente use os comandos


localizados no rodapé inferior direito do programa antes de colocá-lo na área de
trabalho, observando sua posição mostrada na caixa de visualização
11

3.2.3 Carregar o programa com os dados “. HEX” gerados no MPLAB ®

Dê dois clique sobre o microcontrolador que está na área de trabalho e a seguinte


tela será aberta:
1

4
2

5 3

3.3 MPLAB®
7

1 Indica a nomenclatura do componente no projeto


2 Indica o modelo do microcontrolador utilizado
3 Indica o tipo de invólucro utilizado para confecção do circuito impresso no
ARES
4 Indica o endereço da USB utilizada na simulação
5 local para selecionar o arquivo “HEX” a ser rodado na simulação
6 Campo para escolha da freqüência de simulação
7 Barra de rolagem para configuração extras do microcontrolador caso
utilizadas no programa
12

8 Local para configuração de funcionamento do microcontrolador

Para carregar o programa no microcontrolador clique sobre o ícone de pasta


no campo 5 ; da figura acima e dê dois clique sobre o arquivo escolhido.

Nesta hora a tela anterior voltará a ser apresentada então configure a


freqüência de operação do microcontrolador no campo 6 e clique em “OK”

Pronto você já pode montar o restante do circuito e simular o funcionamento


do seu programa.

4 PLATAFORMAS DE PROGRAMAÇÃO C ANSI.

4.1 MPLAB®

O MPLAB® é um ambiente integrado para o estudo e desenvolvimento com a


família PIC de microcontroladores.Sua principal característica é a total integração de
seus módulos com o ambiente Windows®, permitindo a fácil cópia de arquivos e
trechos de arquivos de um aplicativo para outro.
Esta poderosa ferramenta e capaz de transformar linguagem de baixo e alto
nível, juntamente com compiladores específicos para o código Hexadecimal usado
na gravação final do PIC.
13

4.1.2 Carregando projetos no MPLAB ®

Passo 1- Abra o bloco de nota e o salve como “main.c” em uma pasta onde será aberto o
novo projeto.

Passo 2- Depois de abrir o programa selecione “project wizard” para carregar um projeto no
MPLAB

Passo 3- A seguinte tela se apresentará clique em avançar

Passo 5- Nesta pagina escolha o tipo de


compilador e linguagem e clique em avançar
Passo 4- Escolha o microcontrolador a ser
no nosso caso MCC18 para linguagem C
utilizado e clique em avançar
ANSI
14

Passo 6

1- Clique em browse
2- Escolha a pasta
onde foi criado main.c 3- Digite um nome
para o projeto

4- Clique em salvar

Passo 7- O caminho do projeto é criado, clique em avançar.

Passo 8- Esta tela permite inserir o main.c ao


projeto no entanto faremos isto posteriormente
apenas clique em avançar

Passo 10- clique com o botão direito do mouse e vá em


Passo 9- clique em concluir Add Files para inserir o main.c criado anteriormente
15

Passo 11- Na tela que se abrirá selecione


“Project Directory” e clique duas vezes sobre
“ícone main” no pad Pronto o arquivo main foi adicionado
ao projeto

Obs : Se o seu projeto conter um programa de boot-loader carregue-o usando o


mesmo procedimento que foi usado no main.

Passo 12- Dê dois clique sobre o ícone main e digite o programa a ser rodado

Digite aqui seu programa


16

Passo 13- Depois de escrito o programava em “Project” depois em Build All. Se o programa estiver sem erro o arquivo .H

Mensagem de compilação
com sucesso

NOTA:
Existe a possibilidade de simular o programa no ambiente MPLAB ® mas não
abordaremos este tópico pois nossa simulação acontecerá no PROTEUS ®
17

4.2 MCC18®

Também conhecido como MPLAB® C18 é uma compilador C ANSI compatível para a
família PIC18 na plataforma Windows e um componente totalmente integrado a
Microchip, permitindo a depuração da linguagem de nível com MPLAB ®.
Os Projetos, opções do compilador e vinculador personalizações podem ser
controladas completamente dentro do MPLAB IDE.

5 Apresentação do 74HS594

O circuito integrado 74HS595 é um deslocador de movimento que utiliza oito flip-


flops que são responsáveis pela memorização de dados inseridos e manipulados de
posição em posição através de duas entradas de clock’s .Seu datasheet esta no
anexo 2 (dois).
Estes dispositivos cotem imunidade a ruídos e baixo consumo de energia são de
tecnologia CMOS e podem movimentar cargas TTL-LS.
Todas as entradas são protegidas de dano devido à descarga estática interna
Com barreiras de diodo para VCC
Freqüência mudança Garantida: DC a 30 MHz.

5.1. Esquema eletrônico


18

5.2. funcionamento.

O Programa trabalha com o deslocamento do dado inserido na entrada “DS” para


isto ele colocará as duas entradas de clock’s em nível zero.
Partindo deste momento a primeira entrada clock “SH-CP” será levada em nível
alto com isto acontecerá o deslocamento deste dado para o primeiro Flip-Flop ,no
entanto cada saída e composta de dois flip-flop’s em serie e um buffer controlado
pela entrada “OE” ,o que indica que o dado ainda não foi transferido para a saída
com mais um clock agora em “ST-CP” o dado e transferido para a saída.
Nota :
Se a entrada “OE” estiver em nível baixo o dado será visualizado na saída, se caso
o mesmo pino esteja em nível alto esta leitura será inibida.

6 Apresentação do projeto
Anexo três (3)

7 Apresentação do programa escrito em linguagem C ANSI.

7.1 DEFINES

/** I N C L U D E S ************************************************************************************/
#include <p18cxxx.h> // Necessário para que o compilador adicione a biblioteca
// com as definições do PIC selecionado no projeto, neste
//caso, o modelo 18F4550.
#include <delays.h> // Biblioteca padrão de rotinas de atraso do C18 Microchip

/** D E F I N E S **************************************************************************************/

#define SH_CP PORTCbits.RC0 // VARIÁVEL DE COMUNICAÇÃO SERIAL


#define INSERE_DADOS PORTCbits.RC1 // VARIÁVEL DE COMUNICAÇÃO SERIAL
#define ST_CP PORTCbits.RC2 // VARIÁVEL DE COMUNICAÇÃO SERIAL
#define LIBERA_DADOS PORTCbits.RC6 // VARIÁVEL DE COMUNICAÇÃO SERIAL
#define SH_CP2 PORTAbits.RA0 // VARIÁVEL DE COMUNICAÇÃO SERIAL
#define INSERE_DADOS2 PORTAbits.RA1 // VARIÁVEL DE COMUNICAÇÃO SERIAL
#define ST_CP2 PORTAbits.RA2 // VARIÁVEL DE COMUNICAÇÃO SERIAL
#define LIBERA_DADOS2 PORTAbits.RA3 // VARIÁVEL DE COMUNICAÇÃO SERIAL
#define SH_CP3 PORTBbits.RB0 // VARIÁVEL DE COMUNICAÇÃO SERIAL
19

#define INSERE_DADOS3 PORTBbits.RB1 // VARIÁVEL DE COMUNICAÇÃO SERIAL


#define ST_CP3 PORTBbits.RB2 // VARIÁVEL DE COMUNICAÇÃO SERIAL
#define LIBERA_DADOS3 PORTBbits.RB3 // VARIÁVEL DE COMUNICAÇÃO SERIAL
#define CHAMADAS PORTAbits.RA4 // VARREDURA PARA REGISTRO DAS CHAMADAS DE
//CABINE, SUBIDA E DESCIDA
#define PARADA PORTAbits.RA5 // SINAL DE PARADA
#define PREPARA_PARADA PORTBbits.RB5 // DEFINE ONDE SERA INICIADO A PARADA
#define PORTA_ABERTA PORTBbits.RB6 // INDICAÇÃO DE PORTA ABERTA
#define PORTA_FECHADA PORTBbits.RB7 // INDICAÇÃO DE PORTA FECHADA
#define ABRE_PORTA PORTCbits.RC7 // ACIONA CIRCUITO PARA ABRIR PORTA
#define FECHA_PORTA PORTEbits.RE2 // ACIONA CIRCUITO PARA FECHAR PORTA
#define POSICAOA PORTDbits.RD0 // SINAL DOS SENSORES DE POSICIONAMENTO
#define POSICAOB PORTDbits.RD1 // SINAL DOS SENSORES DE POSICIONAMENTO
#define POSICAOC PORTDbits.RD2 // SINAL DOS SENSORES DE POSICIONAMENTO
#define POSICAOD PORTDbits.RD3 // SINAL DOS SENSORES DE POSICIONAMENTO
#define SINAL_DESCE PORTBbits.RB4 // INDICA EXISTENCIA DE CHAMADAS DE DESCIDA
#define SINAL_SOBE PORTDbits.RD5 // INDICA EXISTENCIA DE CHAMADAS DE SUBIDA
#define SINAL_ALTA PORTDbits.RD6 // ACIONA A BAIXA VELOCIDADE DO ELEVADOR
#define SINAL_BAIXA PORTDbits.RD7 // ACIONA A ALTA VELOCIDADE DO ELEVADOR
#define LIMITE_DESCIDA PORTEbits.RE0 // LIMITE DE POSICIONAMENTO MAXIMO INFERIOR DA
//CABINE
#define LIMITE_SUBIDA PORTEbits.RE1 // LIMITE DE POSICIONAMENTO MAXIMO SUPERIOR DA
//CABINE
#define NIVELAMENTO PORTDbits.RD4 // INDICA NIVELAMENTO DA CABINE COM O ANDAR

7.2 VARIÁVEIS

/** P R O T O T I P O S P R I V A D O S **************************************************************************************/

void ConfiguraSistema (void);

/** VARIAVEIS AUXILIARES *******************************************************************************************************/

unsigned char chamadas_cab[10], chamadas_sub[10],AUX_CHAM_CAB_SOB ,AUX_CHAM_CAB_DES ,AUX_CHAM_SUB , AUX_CHAM_DES,


i, chamadas_des[10],DADOS[32], ANDAR, FALHA_FECHAR_PORTA, FALHA, FALHA_ABRIR_PORTA , MAIOR, MENOR, AD, AS;
unsigned long int INDEX, INDEX2;

7.3 ZERANDO VARIAVEIS, PORTAS E REGISTRADORES PARA


INICIALIZAR COMANDOS.

/** FUNCAO PRINCIPAL ***********************************************************************************************************/


20

void main(void)
{

ConfiguraSistema(); //Configura quem são as entradas e saídas no PIC

/** ZERA SAIDAS DE COMANDOS ********************************************************************************************CORRETO*/

SH_CP2 = 0;
INSERE_DADOS2 = 0;
ST_CP2 = 0;
LIBERA_DADOS2 = 0;
PARADA = 0;
SINAL_DESCE = 0;
PREPARA_PARADA = 0;
SH_CP = 0;
INSERE_DADOS = 0;
ST_CP = 0;
LIBERA_DADOS = 0;
ABRE_PORTA = 0;
SINAL_SOBE = 0;
SINAL_ALTA = 0;
SINAL_BAIXA = 0;
FECHA_PORTA = 0;

/** ZERA CHAMADAS ******************************************************************************************************* /

for(i = 0; i < 10; i++)


{
chamadas_cab[i] = 0;
chamadas_sub[i] = 0;
chamadas_des[i] = 0;
}

/** ZERA DADOS *******************************************************************************************************/

for(i = 0; i < 32; i++)


DADOS[i] = 0 ;

/** ZERA VARIAVEIS DE COMANDOS ************************************************************************************/

FALHA_FECHAR_PORTA = 0;
ANDAR = 0;
INDEX = 0;
FALHA = 0;

/** LIMPA REGISTROS DAS SAIDAS DOS 74HC595 ********************************************************************/

for(i = 0; i < 32; i++)


{
LIBERA_DADOS = 1; // INIBE A VISUALIZAÇÃO DAS SIDAS DO CI 74HC595 BLOCO 1
21

// Delay10KTCYx(18);
SH_CP = 0;
//Delay10KTCYx(18);
ST_CP = 0; //ZERA OS CLOCK'S DE DESLOCAMENTO DO 74HC595 BLOCO 1
INSERE_DADOS = 0; //ISERE VALOR DO BIT QUE IRA SE DESLOCAR NAS PORTA DO 74HC595 BLOCO 1
SH_CP = 1;
//Delay10KTCYx(18); //delay de 15ms
ST_CP = 1; // DESLOCA BIT ATE A ULTIMA PORTA DO 74HC595 BLOCO 1
//Delay10KTCYx(18); //delay de 15ms
}

7.4 PREPARA PORTA PARA POCICIONAR CABINE DO ELEVADOR NA


PRIMEIRA PARADA

A primeira manobra que se realiza quando se liga o comando de um elevador é


garantir o fechamento das portas para que o mesmo se desloque dentro do poço.
Nesta parte do programa é utilizado uma técnica diferente parecida com o delay ,
mas que cria um contador de ciclos (INDEX) dentro de uma função “do” que permite
um estouro de contagem ou a conclusão da função na ordem do que acontecer
primeiro, ela é utilizada para manter o motor ligado no menor intervalo de tempo
possível atrazando seu aquecimento durante a operação.

/** PREPARA ESTADO DE PORTA PARA REPOSICIONAMENTO DA CABINE **************************************/

ABRE_PORTA = 0;
do
{
FECHA_PORTA = 1;
INDEX ++; //EXECUTA TIPO UM DELAY QUE TERÁ "off" QUANDO "do" FOR SATISFEITO OU FALHA NO ESTOURO DA
//CONTAGEM
if(INDEX == 150000)
{
FECHA_PORTA = 0;
//Delay10KTCYx(240); //delay
}

/** TENTATIVA 2 DE FECHAR A PORTA ********************************************************************************/

if(INDEX == 300000) // EXECUTA TIPO UM DELAY QUE TERÁ "off" QUANDO "do" FOR SATISFEITO OU FALHA NO ESTOURO
//DA CONTAGEM
22

{
FALHA_FECHAR_PORTA = 2;
FECHA_PORTA = 0;
//Delay10KTCYx(240); //delay
}

/** TENTATIVA 3 DE FECHAR A PORTA ***********************************************************************************/

if(INDEX == 450000) // EXECUTA TIPO UM DELAY QUE TERÁ "off" QUANDO "do" FOR SATISFEITO OU FALHA NO ESTOURO
//DA CONTAGEM
{
FALHA_FECHAR_PORTA = 3;
FECHA_PORTA = 0;
//Delay10KTCYx(240); //delay
}

7.5 DETECTA FALHA AO FECHAR A PORTA

Se durante o comando ocorrer o não fechamento da porta a mesma será desligada


por um intervalo de tempo (ajustado na obra de acordo com o operador de porta)
tentando fechar novamente em seguida.

/**FALHA DETECTADA AO FECHAR A PORTA ****************************************************************************/

if(INDEX == 600000) // EXECUTA TIPO UM DELAY QUE TERÁ "off" QUANDO "do" FOR SATISFEITO OU FALHA NO ESTOURO
//DA CONTAGEM
{
FALHA_FECHAR_PORTA = 4;
FECHA_PORTA = 0;
while(1) // LAÇO INFINITO DE FALHA DETECTADA
{
FECHA_PORTA = 0;
ABRE_PORTA = 0;
SINAL_SOBE = 0;
SINAL_DESCE = 0;
SINAL_ALTA = 0;
SINAL_BAIXA = 0;
DADOS[31] = 1;
23

7.6 PROCEDIMENTO PARA ASCENDER LED DE FALHA DENTRO DO


WHILE

A tentativa para fechar a porta se repetira por três vezes ao final de todas as
tentativas o elevador ira para um loop infinito que mantêm um LED de falha acesso
até a intervenção técnica no equipamento.

/**PROCEDIMENTO PARA ASCENDER LEDS DE FALHA DENTRO DO WHILE ******************************************* */


for(i = 0; i <= 32; i++)
{
LIBERA_DADOS = 1; // INIBE A VISUALIZAÇÃO DAS SIDAS DO CI 74HC595 BLOCO 1
// Delay10KTCYx(18);
SH_CP = 0;
//Delay10KTCYx(18);
ST_CP = 0; //ZERA OS CLOCK'S DE DESLOCAMENTO DO 74HC595 BLOCO 1

if ( DADOS[i] == 1) // CONDIÇÃO
INSERE_DADOS = 1; // INSERE VALOR DO BIT QUE IRÁ SE DESLOCAR NAS PORTA DO 74HC595 BLOCO 1
else // OU
INSERE_DADOS = 0; // INSERE VALOR DO BIT QUE IRA SE DESLOCAR NAS PORTA DO 74HC595 BLOCO 1
SH_CP = 1;
//Delay10KTCYx(18);
ST_CP = 1;
//Delay10KTCYx(18); // DESLOCA BIT ATÉ A ULTIMA PORTA DO 74HC595 BLOCO 1
}

LIBERA_DADOS = 0; // LIBERA INFORMAÇÃO DAS PORTAS DO 74HC595 BLOCO 1

//Delay10KTCYx(18);

}
}
}while (PORTA_FECHADA == 0);

FECHA_PORTA = 0;

//** ZERA INDEX ***************************************************************************************************************** */

INDEX = 0 ; // PREPARA VARIAVEL "INDEX" PARA NOVA CONTAGEM.


do
{
INDEX ++;
24

7.7 STOP DA CABINE NA POSIÇÃO INFERIOR

Depois que as portas são fechadas o elevador deve se dirigir para o curso inferior do
poço, no intuito de se posicionar para inicio de atendimento das chamadas.
A técnica utilizada aqui é idêntica ao do fechamento de porta a criação da variável
(INDEX) Conta o número de ciclos dentro do “do” para o estouro ou a satisfação da
função, visando proteger o motor de tração na ordem do que acontecer primeiro e
terá que ser regulado de acordo com o tamanho do percurso maximo do poço do
elevador.

//** DESLOCA CABINE PARA POSIÇÃO INFERIOR ************************************************************************************/


SINAL_DESCE = 1;
SINAL_BAIXA = 1;

if( INDEX == 4000000) // EXECUTA TIPO UM DELAY QUE TERÁ "off" QUANDO "do" FOR SATISFEITO OU FALHA NO ESTOURO
DA CONTAGEM
while(1)
{ // ESTE TIPO DE DELAY GARANTE A MANUTENÇÃO DO COMANDO CONTRA
FECHA_PORTA = 0; //FALHAS QUE PODEM OCORRER COM TRANSIENTES INDUZIDOS PELA FIAÇÃO DE POÇO
ABRE_PORTA = 0;
SINAL_SOBE = 0;
SINAL_DESCE = 0;
SINAL_ALTA = 0;
SINAL_BAIXA = 0;
DADOS[21] = 1;

7.8 PROCEDIMENTO PARA ASCENDER LED DE FALHA DENTRO DO


WHILE

/**PROCEDIMENTO PARA ASCENDER LED DE FALHA DENTRO DO WHILE ************************************************************ */

for(i = 0; i <= 32; i++)


{
LIBERA_DADOS = 1; // INIBE A VISUALIZAÇÃO DAS SIDAS DO CI 74HC595 BLOCO 1
//Delay10KTCYx(18);
SH_CP = 0;
//Delay10KTCYx(18);
ST_CP = 0; //ZERA OS CLOCK'S DE DESLOCAMENTO DO 74HC595 BLOCO 1
if(DADOS[i] == 1)
INSERE_DADOS = 1; //ISERE VALOR DO BIT QUE IRA SE DESLOCAR NAS PORTA DO 74HC595 BLOCO 1
else // OU
INSERE_DADOS = 0; //ISERE VALOR DO BIT QUE IRA SE DESLOCAR NAS PORTA DO 74HC595 BLOCO 1
//Delay10KTCYx(18);
25

SH_CP = 1;
//Delay10KTCYx(18);
ST_CP = 1; // DESLOCA BIT ATÉ A ULTIMA PORTA DO 74HC595 BLOCO 1
}

LIBERA_DADOS = 0; // LIBERA INFORMAÇÃO DAS PORTAS DO 74HC595 BLOCO 1


//Delay10KTCYx(18);
}
}while (LIMITE_DESCIDA == 1);

7.9 STOP DA CABINE NA POSIÇÃO INFERIOR

//** STOP DA CABINE NA POSIÇÃO INFERIOR *************************************************************************/

SINAL_DESCE = 0;
SINAL_BAIXA = 0;

7.10 NIVELA A CABINE PARA POSIÇÃO DA PRIMEIRA PARADA

Depois de atingido o limite inferior do curso da cabine dentro do poço, o mesmo


deve parar e contar um tempo para reverter a direção do motor de tração sem
causar impacto sobre o mesmo.
É importante perceber que o elevador passou do nível da porta do primeiro andar
por isto é necessário subir a cabine e nivela-la sem que haja formação de degraus
ao abrir a porta

//** NIVELA A CABINE PARA POSIÇÃO DA PRIMEIRA PARADA **************************************************** */


//Delay10KTCYx(180); //delay de 150ms

do
{
SINAL_SOBE = 1;
SINAL_BAIXA = 1;
}while(NIVELAMENTO == 0);

SINAL_SOBE = 0;
SINAL_BAIXA = 0;
//Delay10KTCYx(100); //delay

7.11 PREPARA PARA ABRIR PORTA


26

Nesta parte do programa é utilizado novamente a técnica do contador de ciclos


(INDEX) dentro de uma função “do” que permite um estouro de contagem ou a
conclusão da função na ordem do que acontecer primeiro, ela é utilizada para
manter o motor ligado no menor intervalo de tempo possível atrazando seu
aquecimento durante a operação.
/** PREPARA ESTADO DE PORTA PARA REPOSICIONAMENTO DA CABINE ***************************************************/

FECHA_PORTA = 0;

do
{
ABRE_PORTA = 1;
INDEX++; // CONTA TEMPO ENCREMENTANDO INDEX PARA INDENTIFICAR FALHA DE PORTA FECHANDO

if(INDEX== 150000)
{
FALHA_ABRIR_PORTA = 1;
ABRE_PORTA = 0;
Delay10KTCYx(240); //delay
}
/** TENTATIVA 2 DE FECHAR A PORTA ******************************************************************************/

if(INDEX == 300000)
{
FALHA_ABRIR_PORTA = 2;
ABRE_PORTA = 0;
//Delay10KTCYx(240); //delay
}

/** TENTATIVA 3 DE FECHAR A PORTA ******************************************************************************/

if(INDEX == 450000)
{
FALHA_ABRIR_PORTA = 3;
ABRE_PORTA = 0;
//Delay10KTCYx(240); //delay
}

7.12 DETECTA FALHA AO ABRIR A PORTA

/**FALHA DETECTADA AO FECHAR A PORTA ***********************************************************************/

if(INDEX == 600000)
{
27

FALHA_ABRIR_PORTA = 4;
ABRE_PORTA = 0;

while(1)
{
FECHA_PORTA = 0;
ABRE_PORTA = 0;
SINAL_SOBE = 0;
SINAL_DESCE = 0;
SINAL_ALTA = 0;
SINAL_BAIXA = 0;
DADOS[32] = 1;

7.13 PROCEDIMENTO PARA ASCENDER LED DE FALHA DENTRO DO


WHILE

/**PROCEDIMENTO PARA ASCENDER LED DE FALHA *****************************************************************************/

for(i = 0; i <= 32; i++)


{
LIBERA_DADOS = 1; // INIBE A VISUALIZAÇÃO DAS SAIDAS DO CI 74HC595 BLOCO 1
// Delay10KTCYx(18);
SH_CP = 0;
//Delay10KTCYx(18);
ST_CP = 0; //ZERA OS CLOCK'S DE DESLOCAMENTO DO 74HC595 BLOCO 1

if( DADOS[i] == 1)
INSERE_DADOS = 1; // INSERE VALOR DO BIT QUE IRA SE DESLOCAR NAS PORTA DO 74HC595 BLOCO 1

else //OU
INSERE_DADOS = 0; // INSERE VALOR DO BIT QUE IRA SE DESLOCAR NAS PORTA DO 74HC595 BLOCO 1

SH_CP = 1;
//Delay10KTCYx(18);
ST_CP = 1;
//Delay10KTCYx(18);
}

LIBERA_DADOS = 0; // MOSTRA COMPOSIÇÃO DOS BIT's NAS PORTAS DO 74HC595 BLOCO 1


//Delay10KTCYx(18); //delay de 15ms
}
}
}
while (PORTA_ABERTA == 0);

ABRE_PORTA = 0;
28

7.14 A EXECUTA LAÇO DE PROGRAMAÇÃO DEFININDO FUNÇÃO


PARA IDENTIFICAÇÃO DE ANDAR

O elevador utilizará esta função para armazenar na memória ao posição em que se


encontra dentro do poço.

//** EXECUTA LAÇO DE PROGRAMAÇÃO ******************************************************************************/

while(1) //Laço de repetição infinita


{

/** DEFINE FUNÇÃO ANDAR ******************************************************************************/

ANDAR = POSICAOA*1 + POSICAOB*2 + POSICAOC*4 + POSICAOD*8; // DIGITOS PARA INDENTIFICAÇÃO DA POCIÇÃO


DA CABINE NOS ANDARES

7.15 A FAZ VARREDURA NOS BOTÕES DE CHAMADA


Esta parte do programa utiliza um protocolo de varredura serial, auxiliada por um
deslocador de movimento denominado 74HC595, onde um pulso alto atinge um
único botão externo de cada vez em tempos distintos e monitorados pelo programa.
Isto permite um retorno e identificação do botão pressionado e o mapeamento de
uma variável de acordo com estes .
Vide funcionamento em anexo dois (2)

/** FAZ VARREDURA NOS BOTÕES DE CHAMADA ****************************************************/

INSERE_DADOS2 = 1; // INIBE A VISUALIZAÇÃO DAS SAIDAS DO CI 74HC595 BLOCO 2

for(i= 0; i < 32; i++)


{
LIBERA_DADOS2 =1;
SH_CP2 = 0;
//Delay10KTCYx(18);
ST_CP2 = 0; //ZERA OS CLOCK'S DE DESLOCAMENTO DO 74HC595 DA VARREDURA DE BOTÕES
//Delay1KTCYx(18);
SH_CP2 = 1;
//Delay1KTCYx(18);
ST_CP2 = 1; //SETA OS CLOCK'S DE DESLOCAMENTO DO 74HC595 DA VARREDURA DE BOTÕES
//Delay1KTCYx(18);
LIBERA_DADOS2 = 0;

if(CHAMADAS == 1 && i < 10)


chamadas_cab[i] = 1; //ISERE VALOR NA MEMORIA DE CHAMADA DE CABINE
29

if(CHAMADAS == 1 && i >= 10 && i < 20)


chamadas_sub[i-10] = 1; //ISERE VALOR NA MEMORIA DE CHAMADA DE SUBIDA
if(CHAMADAS == 1 && i >= 20 && i < 30)
chamadas_des[i-20] = 1; //ISERE VALOR NA MEMORIA DE CHAMADA DE CABINE

INSERE_DADOS2 = 0; //RETORNA ESTADO ZERO PARA DESLOCAR O PRIMEIRO DADO (NIVEL ALTO) ATÉ A ULTIMA PORTA
}

LIBERA_DADOS2 = 1; //LIBERA TRANSFERENCIA DE DE DADOS PARA LEITURA DA PORTA "CHAMADA"

7.16 TRANFERE ESPELHO DE CHAMADAS PARA VARIÀVEL DADOS

/** TRANFERE ESPELHO DE CHAMADAS PARA VARIAVEL DADOS *********************************/

for(i= 0; i < 32; i++)


{
if(i < 10)
DADOS[i] = chamadas_cab[i];
if(i > 9 && i < 20)
DADOS[i] = chamadas_sub[i-10];
if(i > 19 && i < 30)
DADOS[i] = chamadas_des[i-20];
}

7.17 REGISTRA CHAMADAS DE CABINE

Esta parte do programa transfere o sinal de solicitação de chamadas para as saídas


do 74HC595 iluminando os “LED’S” correspondentes aos botões pressionados

/** REGISTRA CHAMADAS DE CABINE ****************************************************/

for(i= 0; i < 32; i++)


{
LIBERA_DADOS = 1; // INIBE A VISUALIZAÇÃO DAS SAIDAS DO CI 74HC595 BLOCO 1
// Delay10KTCYx(18);
SH_CP = 0;
//Delay10KTCYx(18);
ST_CP = 0; //ZERA OS CLOCK'S DE DESLOCAMENTO DO 74HC595 BLOCO 1

if(DADOS[i] == 1)
INSERE_DADOS = 1; // INSERE VALOR NA VARIAVEL DADOS PARA ASCENDER O LED DO BOTÃO RESPECTIVO
else
INSERE_DADOS = 0;
// INSERE VALOR NA VARIAVEL DADOS PARA APAGAR O LED DO BOTÃO não pressionado
SH_CP = 1;
//Delay10KTCYx(18);
ST_CP = 1; //SETA OS CLOCK'S DE DESLOCAMENTO DO 74HC595
//Delay10KTCYx(18);
30

LIBERA_DADOS = 0; //LIBERA ASCENDIMENTO DAS CHAMADAS SOLICITADAS


//Delay10KTCYx(18);

7.18 IDENTIFICA DIREÇÃO DE CHAMADAS SUBIDA OU DESCIDA

Define se as chamadas que estão pressionada se localizam acima ou abaixo da


cabine.

/** DIREÇÃO DE CHAMADAS SUBIDA ******************************************************************************/

for(i = 0; i < 10; i++)


{
if((chamadas_sub[i] || chamadas_cab[i] || chamadas_des[i] ) && ANDAR < i)
{
AUX_CHAM_SUB = 1;
break ;
}
else
AUX_CHAM_SUB = 0;
}

if(AUX_CHAM_SUB && SINAL_DESCE == 0)


SINAL_SOBE = 1;
else
SINAL_SOBE = 0;

/** DIREÇÃO DE CHAMADAS DESCIDA ******************************************************************************/

for(i = 0; i < 10; i++)


{
if((chamadas_des[i] || chamadas_cab[i] || chamadas_sub[i] ) && ANDAR > i)
{
AUX_CHAM_DES = 1;
break ;
}
else
AUX_CHAM_DES = 0;
}

if(AUX_CHAM_DES && SINAL_SOBE == 0)


SINAL_DESCE = 1;
else
SINAL_DESCE = 0;
31

7.19 COMANDO DE ALTA VELOCIDADE

/** COMANDO DE ALTA VELOCIDADE **********************************************************************************/

if((SINAL_DESCE || SINAL_SOBE ) && SINAL_BAIXA == 0 && ABRE_PORTA == 0 && PORTA_FECHADA == 1 )


SINAL_ALTA = 1;
else
SINAL_ALTA = 0;

7.20 PREPARA PARADA COM REVERSÃO DE DIREÇÃO DESCIDA OU


SUBIDA

Estaciona o elevador para atender a ultima ou a única chamada existente, com a


cabine movimentando em sentido contrario a chamada solicitada.
Ex: Uma única chamada de descida no 4º andar com a cabine estacionada no 2º

/** PREPARA PARADA COM REVERSÃO DE DIREÇÃO DESCIDA *********************************************************** */

for(i = 0; i < 10; i++)


if(chamadas_des[i] == 1)
{
AD = 1;//AD = 1 >>> ha chamadas de descida; AD = 0 >>> nao ha chamandas de descida
break;
}

if(SINAL_SOBE && AD)


{
MAIOR = 0;

for(i = 0; i < 10; i++)


if(chamadas_cab[i] || chamadas_des[i] || chamadas_sub[i] && i > MAIOR)
MAIOR = i;

if((MAIOR - ANDAR == 1) && PREPARA_PARADA == 1)


{
SINAL_BAIXA = 1;
SINAL_ALTA = 0;
}
}

/** PREPARA PARADA COM REVERSÃO DE DIREÇÃO SUBIDA ***************************************************************************/

for(i = 0; i < 10; i++)


if(chamadas_sub[i])
{
AS = 1;//AS = 1 >>> ha chamadas de subida; AS = 0 >>> nao ha chamandas de subida
32

break;
}

if(SINAL_DESCE && AS)


{
MENOR = 10;

for(i = 0; i < 10; i++)


if(chamadas_cab[i] ||chamadas_sub[i] || chamadas_des[i] && i < MENOR)
MENOR = i;

if((ANDAR - MENOR == 1) && PREPARA_PARADA)


{
SINAL_BAIXA = 1;
SINAL_ALTA = 0;
}
}

7.21 PREPARACAO_DE_PARADA NA MESMA DIREÇÃO

/** PREPARACAO_DE_PARADA ***********************************************************************************************/

for(i = 0; i < 10; i++)


{
if((chamadas_cab[i] || chamadas_des[i] ) && PREPARA_PARADA && ANDAR - i == 1 && SINAL_DESCE)
{
SINAL_BAIXA = 1;
SINAL_ALTA = 0;
break;
}
if((chamadas_cab[i] || chamadas_sub[i]) && PREPARA_PARADA && i - ANDAR == 1 && SINAL_SOBE)
{
SINAL_BAIXA = 1;
SINAL_ALTA = 0;
break;
}
}

7.22 PARADA

/** PARADA***************************************************************************************************************************/

for(i = 0; i < 10; i++)


{
if(NIVELAMENTO && ANDAR == i && SINAL_BAIXA)
{
SINAL_BAIXA = 0;

if(PORTA_ABERTA == 0)
33

PARADA = 1;
}

7.23 CANCELANDO CHAMADA

/** CANCELANDO CHAMADA *******************************************************************************************************/

if( PARADA && PORTA_ABERTA)


{
chamadas_cab[ANDAR] = 0;
chamadas_sub[ANDAR] = 0;
chamadas_des[ANDAR] = 0;
}

for(i = 0; i < 10; i++)


if(SINAL_SOBE == 0 && SINAL_DESCE == 0 && i == ANDAR)
{
chamadas_cab[ANDAR] = 0;
chamadas_sub[ANDAR] = 0;
chamadas_des[ANDAR] = 0;
}

7.24 ABRE PORTA

/** ABRE PORTA ********************************************************************************************************************************/

if(PORTA_ABERTA == 0 && PARADA && NIVELAMENTO)


ABRE_PORTA = 1;
else
{
ABRE_PORTA = 0 ;
PARADA = 0;
}

7.25 FECHA PORTA

/** FECHA PORTA *********************************************************************************************************************************/

for(i=0; i<10; i++)


{
if((chamadas_cab[i] || chamadas_des[i] || chamadas_sub[i]) && PORTA_FECHADA == 0)
{
FECHA_PORTA = 1;
break;
}
else
34

FECHA_PORTA = 0;
}
}//end while
}//end main

7.26 CONFIGURA SISTEMA


void ConfiguraSistema (void)
{
/** Configura todas as 13 portas analógicas ANx (portas do conversor A/D) como pinos digitais*******************************************/

ADCON1 |= 0x0F; // Todos os pinos como digital

//ENTRADA

TRISAbits.TRISA4 = 1; // CHAMADAS
TRISDbits.TRISD0 = 1; // BIT A DA POSIÇÃO
TRISDbits.TRISD1 = 1; // BIT B DA POSIÇÃO
TRISDbits.TRISD2 = 1; // BIT C DA POSIÇÃO
TRISDbits.TRISD3 = 1; // BIT D DA POSIÇÃO
TRISDbits.TRISD4 = 1; // SENSOR DE NIVELAMENTO DE ANDARES
TRISBbits.TRISB0 = 1; // VA
TRISBbits.TRISB1 = 1; // VB
TRISBbits.TRISB2 = 1; // VC
TRISBbits.TRISB3 = 1; // VD
TRISBbits.TRISB6 = 1; // INDICAÇÃO DE PORTA ABERTA
TRISBbits.TRISB7 = 1; // INDICAÇÃO DE PORTA FECHADA
TRISCbits.TRISC6 = 1; // SENSOR DE PORTA FECHADA
TRISEbits.TRISE0 = 1; // SENSOR LIMITE DE DESCIDA
TRISEbits.TRISE1 = 1; // SENSOR LIMITE DE SUBIDA

/***********************************************************************************************/

//SAIDAS

TRISDbits.TRISD5 = 0; // SINAL_SOBE
TRISDbits.TRISD6 = 0; // SINAL_ALTA
TRISDbits.TRISD7 = 0; // SINAL_BAIXA
TRISEbits.TRISE2 = 0; // FECHA PORTA
TRISAbits.TRISA0 = 0; // SH_CP2
TRISAbits.TRISA1 = 0; // INSERE_DADOS2
TRISAbits.TRISA2 = 0; // ST_CP2
TRISAbits.TRISA3 = 0; // LIBERA_DADOS2
TRISAbits.TRISA5 = 0; // PARADA
TRISCbits.TRISC7 = 0; // ABRE PORTA
TRISCbits.TRISC0 = 0; // SH_CP
TRISCbits.TRISC1 = 0; // DATA
TRISCbits.TRISC2 = 0; // ST_CP
TRISCbits.TRISC6 = 0; // LIBERA_DADOS
TRISBbits.TRISB4 = 0; // SINAL DESCE
TRISBbits.TRISB5 = 0; // PREPARAÇÃO DE PARADA
35

}//end ConfiguraSistema

/** V E C T O R R E M A P P I N G ***********************************************************/
// Seção necessária para informar ao compilador C18 onde são os novos endereços
//da memória de programa que ele deve alocar as rotinas de tratamento do evento
//de "reset" do microcontrolador.
//
//ATENÇÃO: COPIAR ESTA SEÇÃO DO CODIGO PARA TODO ARQUIVO "main.c" DOS PROJETOS
//QUE UTILIZAM O BOOTLOADER PARA GRAVAÇÃO IN-CIRCUIT.

extern void _startup (void); // See c018i.c in your C18 compiler dir
#pragma code _RESET_INTERRUPT_VECTOR = 0x000800
void _reset (void)
{
_asm goto _startup _endasm
}
#pragma code
/** EOF main.c ***************************************************************/

8 CONSIDERAÇÕES FINAIS OU CONCLUSÃO

Diego Corradi

O curso de PIC foi de grande importância, a partir dele adquiri uma visão melhor
sobre microcontroladores e melhorei meu raciocínio com lógica digital. E ainda tive a
oportunidade de conhecer o Luiz que me ensinou muitas coisas na área de elétrica e
eletrônica, ampliando minha visão na área. Com o projeto de conclusão de curso
obtive conhecimentos do funcionamento do elevador, parte de sensoriamento,
prioridades, além de conhecer novos dispositivos eletrônicos e otimizar um projeto a
partir de portas lógicas, flip flop's, e melhorar meu raciocínio com programação de
computadores, linguagem C.

Luiz Cláudio

Ao participar do curso da PICMINAS no primeiro dia de aula senti dificuldades para


realizar um programa que ascendesse apenas um LED, sem conhecimento nenhum
para tal.
Acho que o programa acima diz por si próprio a evolução que o curso proporcionou
em minha vida em apenas duas semanas.
36

Meus agradecimentos aos profissionais altamente classificados desta empresa.

9 REFERÊNCIAS BIBLIOGRÁFICAS

OPICMINAS departamento educacional da empresa AXOON Soluções Tecnológicas em Saúde.


Curso de linguagem C ANSI para PIC18F4550. CD interativo. Belo Horizonte, 2010, volume 1.

EBAH!, Pedro. MANUAL PROTEUS EM PORTUGUÊS. Disponível


Em:<http//:www.prdf.mpf.gov.br/~gazoto/monograf/revfranc> Acesso em: 04 Abr. 2010.

Vous aimerez peut-être aussi