projeto de sistemas eletrônicos · 2017-03-06 · microcontroladores executam com perfeição...
TRANSCRIPT
Curso de Formação Profissional Técnico em
Eletroeletrônica – Módulo II
Senai Arcos-MG
CFP Eliezer Vitorino Costa
Raphael Roberto Ribeiro Silva
Técnico em eletroeletrônica pelo INPA – Arcos
Estudante de Engenharia Elétrica do IFMG - Formiga
Projeto de Sistemas
Eletrônicos
ProgramaçãoPara um microcontrolador funcionar, precisamos escrever as instruções em
seu firmware, instruções essas que servem como parâmetro de funcionamento.
1 – Funcionamento de um Programa
O funcionamento de uma memória de um microcontrolador depende de
dois conjuntos de vários bits, conhecidos como barramento de endereço e
barramento de dados.
Funcionamento de um ProgramaPor convenção, os bits do barramento de endereço são representados pela
letra A (Addres), e os bits de dados são representados pela letra D (Data).
O microcontrolador envia os bits referentes ao endereço da informação e a
memória responde no barramento de dados, trazendo a informação
correspondente ao endereço solicitado.
Funcionamento de um ProgramaAlém dos barramentos de endereço e de dados, existem outros bits que
servem para controlar o funcionamento da memória.
O funcionamento de um microcontrolador depende de varias instruções, de
modo que cada instrução é equivalente a uma informação gravada na
memória, ou seja, quando o microcontrolador solicita uma informação contida
em um endereço, ele recebe, na verdade, uma instrução. A combinação de
zeros e uns que compõem a instrução determina o que o microcontrolador ira
reconhecer se deve executar uma operação matemática, ler um sensor ou
ativar uma saída.
Funcionamento de um ProgramaAs instruções são executadas sequencialmente, quase sempre iniciando
pelo endereço zero. Desse modo, ao ligar o microcontrolador, ele executará a
instrução gravada nesse endereço da memoria de programa. Após executar a
instrução, o microcontrolador incrementará o endereço, buscando a instrução
gravada no endereço um, e assim, sucessivamente. O gerenciamento desses
endereços é feito por um registrador interno ao microcontrolador, chamado de
contador de programa. Ele funciona como uma espécie de ponteiro, que indica
qual será a próxima instrução executada.
Funcionamento de um ProgramaAlgumas instruções levam mais tempo para serem executadas que outras.
Isso ocorre porque algumas precisam de varias etapas para serem concluídas.
As etapas de execução das instruções são chamadas de ciclos de maquina.
Exemplo:
a) Instrução de um ciclo de maquina: ativar uma saída. O microcontrolador
precisa apenas da instrução para realizar a tarefa.
b) Instrução de vários ciclos de maquina: realizar uma soma. Além da
instrução que indica a soma, o microcontrolador precisara buscar os
operandos, ou seja, os números que serão somados. Por esse motivo,
além das instruções, a memoria de programa pode conter dados que são
necessários para executar algumas instruções, como foi o caso dos
operandos de uma soma.
Funcionamento de um Programa
Funcionamento de um Programa
Funcionamento de um ProgramaAlém da quantidade de ciclos, o tempo gasto entre uma instrução e outra
depende da frequência de trabalho do microcontrolador, conhecida como clock.
Quanto maior o clock, menor será o tempo de um ciclo de maquina e,
consequentemente, mais rapidamente a instrução será executada.
Resumindo, o programa de um microcontrolador é composto por varias
instruções gravadas de modo sequencial na memoria do programa. A
velocidade com que essas instruções são processadas depende do clock do
microcontrolador.
Linguagens de ProgramaçãoAs linguagens de programação ao invés de se utilizar números binários, as
instruções são escritas por meio de mnemônicos (técnica para facilitar a
memorização), que são textos e símbolos que indicam o que ela faz. Imagine
que a instrução 00110111, seja uma soma. Em linguagem de programação,
essa instrução binária é representada pelo símbolo da adição “+”.
Desse modo, toda a criação do programa é realizada no formato de texto.
Quando o programa esta pronto, ele precisa ser convertido para a linguagem
binária. Essa conversão recebe o nome de compilação, que é realizada por
programas de computador específicos para esse fim. Assim, você digitara todo
o programa na forma de texto, e o compilador será responsável por traduzi-lo
para a linguagem que o microcontrolador entende.
Não apenas os microcontroladores, mas todos os sistemas
computadorizados funcionam dessa forma, e existem muitos e diferentes tipos
de linguagem de programação. A principal diferença entre elas é a proximidade
que cada um tem com a estrutura de instruções binarias.
Linguagens de ProgramaçãoAs linguagens de programação que mais se aproximam das instruções
binárias são chamadas de linguagens de baixo nível. Já as linguagens mais
distantes da estrutura binaria são conhecidas como linguagens de alto nível.
As linguagens de baixo nível tem a vantagem de permitir uma
programação mais próxima ao modo de funcionamento do microcontrolador,
consomem menos memoria de programa e costumam ser mais velozes.
Porem, o texto do programa é mais extenso, o que dificulta a programação.
Para os microcontroladores, as duas linguagens mais utilizadas são a
Assembly e a C. A assembly é uma linguagem de baixo nível. A linguagem C
possui alto nível, se comparada a assembly.
Para melhor aproveitamento de espaço e velocidade de processamento,
prefira a Assembly. Para programas mais complexos, com muitas instruções,
em que o espaço e a velocidade não são críticos, prefira a linguagem C.
Lógica de ProgramaçãoLógica é o “[...] modo coerente pelo qual as coisas ou acontecimentos se
encadeiam [...]” (Aulete, Caldas, 2007, p.631). Assim, nos microcontroladores,
as instruções devem estar encadeadas de forma lógica para funcionar. No que
se refere aos microcontroladores, não existe suposição. Tudo deve ser
minuciosamente detalhado.
Em programação, quando alguma tarefa não é executada da forma que
esperamos, certamente, é porque alguma etapa não foi bem planejada. Os
microcontroladores executam com perfeição exatamente aquilo que as
instruções o orientam a fazer.
Portanto, programar um microcontrolador é como ensinar alguém a chegar
a um lugar desconhecido. Se você não passar detalhadamente as instruções,
certamente, ela irá se perder no caminho.
Programação EstruturadaUm programa é formado por varias instruções em sequência. Imagine
como seria um programa mais complexo, composto por centenas de
instruções. Provavelmente, chegara a conclusão de que o programa ficaria
enorme e muito difícil de ser analisado.
Assim, algumas técnicas de programação surgiram com o objetivo de
organizar programas, de modo a facilitar o desenvolvimento e também a
analise, em caso de modificações ou ajustes. Um dos primeiros métodos, que
ainda é utilizado ate hoje, é a programação estruturada. Nele, as instruções
são organizadas em blocos.
Os principais objetivos desse método são:
a) Dividir tarefas grandes em pequenas tarefas; e
b) Permitir o reaproveitamento de um conjunto de tarefas.
Programação Estruturada1 - Dividir tarefas grandes em pequenas tarefas: Imagine um programa para
executar as tarefas que uma pessoa desenvolve do momento em que acorda
ate a hora de sair de casa para o trabalho.
Tarefa acordar
1 – levantar da cama;2 – Caminhar ate o banheiro;3 – Tirar a roupa;4 – Abrir o registro do chuveiro;5 – Pegar o sabonete;6 – Esfregar o corpo;7 – Enxaguar o corpo;8 – Fechar o registro do chuveiro;9 – Enxugar o corpo;10 – Vestir a roupa;11 – Pegar a escova de dentes;12 – Pegar a pasta de dentes;
13 – Colocar a pasta de dentes sobre a escova;14 – Introduzir a escova na boca;15 – Esfregar a escova sobre os dentes;16 – Enxaguar a boca;17 – Lavar a escova de dentes;18 – Guardar a escova de dentes;19 - Guardar a pasta de dentes;20 – Caminhar ate a porta de saída;21 – Ir ao trabalho.
Programação EstruturadaAgora vamos dividir a tarefa acordar em blocos. Ao invés de 21 instruções,
ela foi resumida para apenas 6. Na verdade , ela será executada da mesma
forma. No entanto, tomar banho e escovar os dentes foram transferidas para
outros blocos. Assim, a execução do programa será direcionada para os
blocos, e ao fim, retornara para a execução das outras tarefas.
Programação Estruturada2 – Reaproveitamento de um conjunto de tarefas: algumas tarefas precisam
ser executadas varias vezes, em momentos diferentes. Para evitar que você as
digite, todas as vezes, é uma boa ideia coloca-las em blocos. Assim, sempre
que precisar realizar essa tarefa, basta mencionar o bloco, ou seja, você
digitara apenas um bloco, mas poderá executa-lo quantas vezes quiser. Como
exemplo, vamos incluir café da manhã na tarefa acordar. Isso exigira que o
bloco escovar os dentes seja executado duas vezes.
Programação Estruturada
Programação EstruturadaOs blocos possuem nomes técnicos: são chamados de procedimento ou
função. A diferença entre o procedimento e a função está no final da execução
do bloco. Enquanto o procedimento simplesmente retorna a execução normal
da tarefa, a função é capaz de retornar informações obtidas dentro do bloco.
Como exemplo, imagine um bloco para calcular a área de um triangulo. Ao final
da execução, é importante saber qual foi o resultado do calculo, no caso, a
área do triangulo.
Assim, os blocos utilizados na tarefa acordar são procedimentos, pois não
precisam retornar valores ou resultados. O bloco para calcular a área de um
triangulo, por sua vez, é uma função, já que retorna a área do triangulo ao final
de sua execução.
Estrutura Básica de um ProgramaO programa principal é sempre digitado e armazenado em um arquivo
denominado main.
O compilador é responsável por converter as instruções digitadas para o
formato compreendido pelo microcontrolador. Mas nem tudo que for digitado
será compilado.
Além das instruções, o programa pode conter trechos de textos utilizados
como comentários ou informações ao longo do programa. Para inserir
comentários em uma programação deve ser feito da seguinte forma:
// Isto é um comentário de uma linha
/* Isto é
um comentário de
varias linhas */
Estrutura Básica de um ProgramaUma boa prática de programação é utilizar o recurso de comentários logo
no inicio do programa, contendo informações como o nome do autor, a data e
uma breve descrição sobre o programa ou sobre o projeto.
O próximo passo é informar ao compilador sobre os arquivos adicionados
que compõem o programa. Um programa pode ser dividido em vários arquivos.
Alem disso, os fabricantes costumam disponibilizar arquivos com trechos de
programas prontos, para facilitar a programação de determinadas funções.
Assim, existem arquivos prontos para o acionamento de temporizadores,
conversores A/D, acionamento de display, etc. Esses arquivos são conhecidos
como bibliotecas.
Estrutura Básica de um ProgramaPortanto, sempre que o projeto utilizar bibliotecas ou possuir vários
arquivos, é necessário informar ao compilador. A diretiva
“#Include<nome_do_arquivo>” tem essa finalidade. Exemplo:
#Include <p18f4550.h>
#Include <ado.h>
#Include “XLCD.h” // Biblioteca para escrever no LCD
#Include <timers.h> //Biblioteca para as funções do timer
#Include <stdio.h>
#Include <stdlib.h>
#Include <delas.h> //Biblioteca para as funções delay
Estrutura Básica de um ProgramaAlguns arquivos estão entre os símbolos < e >. Isso significa que os
arquivos estão localizados na pasta de instalação do compilador. O arquivo
indicado entre aspas está localizado na mesma pasta do projeto.
Além disso, todos os arquivos possuem extensão “h”. Trata-se de um tipo
de arquivo na linguagem C, que funciona como uma espécie de cabeçalho
para arquivos com extensão “c”. Os arquivos com extensão “h” são opcionais,
mas muito comuns em bibliotecas e programas muito extensos.
Estrutura Básica de um ProgramaApós indicar os arquivos, devemos informar ao compilador sobre as
configurações especificas do microcontrolador que vamos utilizar. Cada
modelo possui sua própria configuração, mas, dentre as principais, podemos
citar o modo de operação do oscilador, responsável pelo clock, temporizador
interno contra falhas (watchdog timer, ou temporizador cão de guarda), etc.
Pra informar as configurações, deve-se utilizar a diretiva #pragma config,
seguida da configuração desejada.
#pragma config FOSC = HS
#pragma config PWRT = ON
#pragma config WDT = OFF
#pragma config PBADEN = OFF
#pragma config LVP = OFF
#pragma config BOR = OFF
#pragma config VREGEN = OFF
#pragma config MCLRE = ON
Estrutura Básica de um ProgramaApós deixar os comentários iniciais do programa, indicar os arquivos
externos e configurar o funcionam
ento do microcontrolador, podemos dar inicio ao programa propriamente dito.
O programa é sempre iniciado pelo procedimento denominado main.
Assim, é obrigatório que nele contenha um procedimento com esse nome.
Para cria-lo, basta escrever a palavra void, seguida do nome do procedimento,
no caso, main.
É obrigatório o uso de parênteses após o nome. Para delimitar o
procedimento, é necessário abrir chaves no inicio e fechá-las ao seu termino.
Assim, todas as instruções compreendidas entre as duas chaves pertencem ao
mesmo procedimento.
void main () {
//instrução 1;
}
Estrutura Básica de um ProgramaAlém do procedimento main, o programa pode conter muitos outros.
Durante a execução do procedimento main, existem chamadas que direcionam
o programa para o Procedimento1 e, mais adiante, para o Procedimento2.
Trata-se de um exemplo sobre como criar procedimentos para a programação
estruturada.
void main () {
//instrução 1;
Procedimento1 ();
//instrução 2;
Procedimento2 ();
}
void Procedimento1 () {
//instrução 1;
}
void Procedimento2 () {
//instrução 1;
}
Estrutura Básica de um ProgramaA diferença entre procedimento e função é que o segundo pode retornar
um valor, como um resultado de um calculo, por exemplo. Para tanto, basta
substituir a palavra void pelo tipo de dado que esperamos.
O quadro a seguir mostra os tipos de dados que os microcontroladores da
família PIC trabalham. Basicamente, a diferença entre eles esta na
capacidade, ou seja, no limite numérico que cada dado suporta.
Estrutura Básica de um ProgramaTIPO TAMANHO VALOR MÍNIMO VALOR MÁXIMO
Char 8 bits -128 127
Signed char 8 bits -128 127
Unsigned char 8 bits 0 255
Int 16 bits -32,768 32,767
Unsigned int 16 bits 0 65,535
Short 16 bits -32,768 32,767
Unsigned short 16 bits 0 65,535
Short long 24 bits -8,388,608 8,388,607
Unsigned short long 24 bits 0 16,777,215
Long 32 bits -2,147,483,648 2,147,483,647
Unsigned long 32 bits 0 4,294,967,295
Float 32 bits 1.17549435𝑒−38 6.80564693𝑒−38
Double 32 bits 1.17549435𝑒−38 6.80564693𝑒−38
VariáveisDurante a execução de um programa, é comum o armazenamento
temporário de informações, que funcionam como uma espécie de rascunho,
para serem aproveitadas posteriormente. Esses espaços para rascunhos são
chamados de variáveis.
Para declarar uma variável, basta indicar, no inicio da função ou do
procedimento, o tipo de dado desejado e, na sequencia, atribuir um nome de
sua preferencia. Exemplo:
int soma () {
char variável11; //criação da variável11
char variável12; //criação da variável12
char variável13; //criação da variável13
variavel11 = 1; //armazenando o numero 1 na variavel11
variavel12 = 15; //armazenando o numero 15 na variavel12
variavel13 = variavel11 + variavel12; //armazenando a soma
return variavel13; //retornando o conteúdo da variavel13
}
Operadores e Instruções da Linguagem C
+ Adição <=Comparador lógico “menor ou igual que”
++ Incremento de variável (variável + 1) >=Comparador lógico “maior ou igual que”
- Subtração == Comparador lógico “igual a”
-- Decremento de variável (variável -1) != Comparador lógico “diferente de”
* Multiplicação && AND lógico
/ Divisão (parte inteira da divisão) || OR lógico
%Resto da divisão ( se for divisão de inteiros)
! NOT lógico
^ Exponencial & AND binário
< Comparador lógico “menor que” | OR binário
> Comparador lógico “maior que” ~ NOT binário
Instrução whileA instrução while forma um bloco de instruções que se repete, enquanto
uma determinada condição for verdadeira. Quando a ultima instrução do bloco
é executada, o programa retorna ao inicio do bloco while, formando uma
espécie de laço de repetição ou loop. A condição de loop é definida a critério
do programador, que poderá determinar quantas vezes o bloco será
executado. Exemplo:
void main () {
int var; //declaração de uma variável chamada var
var = 0; //atribui o valor de zero para a variável var
while (var < 0) { /* O bloco while sera executado enquanto o valor da
variável for menor que 8 */
var += 1; //a variável var é incrementada em 1 unidade (var = var + 1)
}
//quando a variável var for igual a 9, o programa irá sair do bloco while
}
Instrução forA instrução for constitui um bloco de instruções que é executado certa
quantidade de vezes, de acordo com uma condição de teste. A diferença esta
no modo como é realizado o teste. Ao invés de contar apenas o teste, os
parâmetros da instrução determinam a condição inicial e o comportamento da
variável de controle utilizada no teste.
void main () {
int i; //declaração de uma variável chamada i
for (i = 0, i < 5, i++) { //Condição inicial: i = 0 //Condição de loop: i < 5
//ajuste de parâmetro: i é incrementado a cada loop
//instrução 1;
//instrução 2;
}
//quando a variável i chegar a 5, o bloco for não será mais executado
//e o programa seguirá a partir desse ponto
}
Instrução if e elseA instrução if faz com que o bloco de instrução seja executado apenas se
determinada condição for verdadeira. Ao contrario das instruções while e for, o
bloco é executado uma única vez, sem realizar loop. Exemplo:
void main () {
int temperatura; //declaração da variável para armazenar a temperatura
temperatura = letemperatura (); //executa a função letemperatura e
//armazena a leitura na variável temperatura
if (temperatura < 25) { //testa o valor da temperatura
ligaaquecedor (); //se a temperatura é menor que 25, executa o
//procedimento que liga o aquecedor
}
else {
desligaaquecedor (); //se a temperatura for igual ou maior que 25
//executa o procedimento desliga aquecedor
}
}
Instrução switchA instrução switch, assim como a instrução if, serve para executar blocos
de instruções baseados em condições. A diferença é que a instrução switch
pode fazer vários testes, ao contrario da instrução if, que faz apenas um.
A utilização da instrução break ao final de case é obrigatório. Isso evita que
as outras condições sejam executadas. Ao final da instrução switch, um bloco
com a diretiva default funciona de forma semelhante ao bloco else, ou seja,
quando nenhuma condição for satisfeita, o bloco default é executado. Vale
ressaltar que o bloco default é opcional.
Instrução switchswitch (dia_da_semana) {
case 1: {
domingo ();
break; }
case 2: {
segunda ();
break; }
...
case 6: {
sexta ();
break; }
case 7: {
sabado ();
break; }
}
Referências Bibliográficas
• TOCCI, Ronald; WIDMER, N. S. "Sistemas Digitais. Princípios e
Aplicações". 11ª Edição. Editora Prentice-Hall, 2011.
• PEDRONI Volnei A. "Eletrônica Digital Moderna e VHDL". 1ª Edição.
Editora Campus, 2010.
• MORAES, Airton Almeida de. NOVAES, Regina Célia Roland. Análise
de Circuitos Elétricos. 2. Ed. SENAI-SP, 2005.
• SENAI – SP. Eletrônica Geral – Mecatrônica. São Paulo, 2003.
• Serviço Nacional de Aprendizagem Industrial. Departamento Nacional.
Projetos de Sistemas Eletrônicos / SENAI. Departamento Nacional,
SENAI. Departamento Regional de São Paulo. Brasília: SENAI/DN,
2014 156 p. il. (Série Eletroeletrônica).