Você está na página 1de 68

DESCRIÇÃO

Fundamentos da programação de sistemas embarcados.

PROPÓSITO
A manipulação de bases numéricas e álgebra booleana utilizadas nos sistemas computacionais é
primordial para o profissional dominar os mecanismos de compilação e programação em
linguagem C para sistemas embarcados.

PREPARAÇÃO
Não há pré-requisitos operacionais.

OBJETIVOS
MÓDULO 1

Reconhecer a importância dos sistemas embarcados e suas aplicações

MÓDULO 2

Identificar as bases de numeração e a conversão entre bases

MÓDULO 3

Empregar as regras da álgebra booleana no desenvolvimento de sistemas embarcados

MÓDULO 4

Distinguir as principais características e a importância da linguagem C

INTRODUÇÃO
Você pode observar que a tecnologia baseada em computadores se torna cada vez mais
incorporada em produtos eletrônicos. É até difícil identificar produtos eletrônicos recentes que não
tenham algum sistema computacional integrado para controlá-lo, que podemos chamar de sistema
embarcado ou embutido. Como resultado, os sistemas embarcados são encontrados, atualmente,
em todos os tipos de equipamentos eletrônicos e dispositivos. Desde pequenas quantidades de
processamento, em itens como um temporizador eletrônico de uma cafeteira, a sistemas
incorporados muito mais complexos, como consoles de jogos, televisores e até mesmo na
automação de grandes fábricas e sistemas industriais, os sistemas embarcados se tornaram
onipresentes.
Neste conteúdo, entenderemos a importância dos sistemas embarcados, como eles se
desenvolveram e as suas aplicações. Na caminhada para dominar a programação em sistemas
embarcados, começaremos com a identificação dos sistemas de numeração usados e as regras da
álgebra booleana. Veremos também uma introdução à linguagem mais utilizada na programação
de sistemas embarcados, a linguagem C.

MÓDULO 1

 Reconhecer a importância dos sistemas embarcados e suas aplicações

GENERALIDADES SOBRE OS SISTEMAS


EMBARCADOS
Os sistemas embarcados são amplamente difundidos no cenário tecnológico moderno.

Foto: Shutterstock.com

Um exemplo representativo de nossa vida diária, incorporando tais sistemas, são os telefones
celulares ou smartphones. Os smartphones de última geração fornecem ao usuário um conjunto de
funcionalidades altamente sofisticadas, incluindo funções de comunicação, streaming de vídeo,
música e acesso à Internet, com uma qualidade de serviço muito satisfatória. Em parte, isso se
tornou possível graças à melhoria significativa dos circuitos que compõem o sistema embarcado,
com grande capacidade de integração de dispositivos.

Bom, você pode estar discordando da afirmação de que um smartphone é um sistema embarcado.

Com tantas funções, como não atribuir a esse aparelho uma classificação de computador, como
você já deve ter ouvido várias vezes?

Faz sentido classificar um smartphone na mesma categoria de uma máquina de lavar?

Essa é uma boa discussão para desenvolvermos. As discordâncias, que, nesse caso, podem
deixar de existir daqui a algum tempo, são benéficas para o entendimento mais profundo sobre
sistemas embarcados. Vamos voltar a essa discussão após verificarmos o histórico de
desenvolvimento e os aspectos gerais sobre os sistemas embarcados.

BREVE HISTÓRICO DOS SISTEMAS


EMBARCADOS

 COMENTÁRIO

Todos nós vivemos no presente e planejamos o futuro nos vários aspectos de nossa vida. Mas,
para saber exatamente para onde estamos indo, primeiro precisamos entender de onde viemos.
Para isso, precisamos de uma apreciação da História para compreendermos a nossa identidade.
Isso não é diferente para o profissional quando se trata da história de desenvolvimento das
tecnologias com as quais ele trabalha, como os sistemas embarcados, em nosso caso.

Um dos primeiros sistemas reconhecidamente embarcados foi o Computador de Orientação


Apollo, o sistema digital instalado no Módulo de Comando Apollo e no Módulo Lunar, desenvolvido
por Charles Stark Draper no Laboratório de Instrumentação do MIT (Instituto de Tecnologia de
Massachusetts) em 1961.

No início do projeto, o Computador de Orientação Apollo foi considerado o item mais arriscado no
projeto, pois empregava os circuitos integrados (CIs) monolíticos recentemente desenvolvidos para
reduzir o tamanho e o peso.
Desse modo, o primeiro computador a usar CIs ajudou os astronautas a coletar dados de voo em
tempo real.

Temos aqui um primeiro termo que nos permite identificar um tipo muito comum de sistema
embarcado: tempo real.

Em um sistema de tempo real, a reação a um evento, ou o tempo de execução de uma tarefa, é


determinístico e independente da carga do sistema. Ou seja, deve ocorrer dentro de um período
especificado, sem atrasos.

 ATENÇÃO

Não confundir com o jargão, comum no dia a dia, de se referir a tempo real como algo que ocorre
enquanto as pessoas estão assistindo a algo ou esperando, neste caso, um intervalo considerado
curto para a observação, mas não necessariamente dentro de um período determinado.

Nem todos os sistemas embarcados são de tempo real, como veremos em uma classificação mais
adiante, embora este seja predominante.

Em 1961 foi criado o computador de orientação Autonetics D-17, que foi um dos primeiros
sistemas embarcados produzidos em massa, para o míssil Minuteman.

Em 1965, a Autonetics, agora parte da Boeing, desenvolveu o D-17B, o computador usado no


sistema de orientação de mísseis Minuteman I. Este é amplamente reconhecido como o primeiro
sistema embarcado produzido em massa.

Em 1968, o primeiro sistema embarcado para um veículo foi lançado: o Volkswagen 1600, que
usava um microprocessador para controlar seu sistema de injeção eletrônica de combustível.

 COMENTÁRIO

Na década de 1960, com as primeiras aplicações, o preço dos sistemas embarcados caiu e houve
um grande aumento no poder de processamento e na funcionalidade. O desenvolvimento dos
sistemas embarcados passou a se confundir com o dispositivo mais utilizado nesses sistemas, o
microcontrolador.

Em 1971 foi desenvolvido pela Texas Instruments o primeiro microcontrolador: a série TMS1000,
que se tornou comercialmente disponível em 1974, contendo um processador de 4 bits,
integrando memória somente leitura (ROM) e memória de acesso aleatório (RAM). Nessa mesma
época, um microprocessador, o Intel 4004, foi projetado para calculadoras e outros sistemas
pequenos, mas ainda exigia memória externa e chips de suporte.

 COMENTÁRIO

À medida que o custo dos microprocessadores e microcontroladores caiu, tornou-se viável


substituir os dispendiosos controladores baseados em botões e componentes analógicos, como
potenciômetros e capacitores variáveis, por botões lidos por um microprocessador, mesmo em
produtos de consumo.

No início da década de 1980, os projetos de microcontroladores se expandiram, com


componentes do sistema de memória, entrada e saída, sendo integrados no mesmo chip com o
processador.

Os microcontroladores passam a encontrar aplicações em que um computador de uso geral seria


muito caro. Um microcontrolador de custo comparativamente baixo poderia agora ser programado
para cumprir a mesma função que muitos componentes separados.

 ATENÇÃO

Embora, nesse contexto, um sistema embarcado seja geralmente mais complexo do que uma
solução tradicional, a maior parte da complexidade está contida no próprio microcontrolador.
Poucos componentes adicionais são necessários e a maior parte do esforço de projeto passa para
o software embarcado, também conhecido como firmware .

O protótipo e o teste do firmware podem ser mais rápidos em comparação com o projeto e a
construção de um novo circuito sem processador embutido.

No final da década de 1980, surgiram os primeiros sistemas operacionais embarcados, como:

O VxWorks, lançado pela Wind River;

O Windows Embedded CE, da Microsoft, em 1996.

No final da década de 1990, os primeiros produtos Linux embarcados começaram a ser


desenvolvidos.
 COMENTÁRIO

Hoje, o Linux é usado em vários dispositivos embarcados, como os que se baseiam nos
computadores de placa única e tamanho reduzido, incluindo os Raspberry Pi e o BeagleBone.

DEFINIÇÃO DE SISTEMA EMBARCADO


Sistemas embarcados são projetados para uma tarefa específica.

Embora usem técnicas semelhantes às dos computadores, eles não podem ser utilizados como um
computador de uso geral, que tem uma variedade de programas diferentes para tarefas diferentes.

Dessa forma, sua função pode ser focada no que eles precisam fazer, tornando-os mais baratos e
eficientes.

Assim, podemos definir um sistema embarcado como qualquer sistema de computador contido em
um produto que não seja descrito como um computador.

Uma definição mais completa foi dada por Henzinger e Sifakis (2006):

“Um sistema embarcado é um sistema de computador para fins especiais que consiste em uma
combinação de componentes de software e hardware sujeitos a restrições físicas. Essas restrições
físicas vêm do ambiente do sistema e de sua plataforma de execução”.

Assim, um sistema embarcado está em interação com seu mundo externo, também conhecido
como seu ambiente, que pode ser, por exemplo, um processo físico, alguns dispositivos técnicos
em um sistema maior ou algum operador humano. Sua função consiste em abastecer seu
ambiente conectado com serviços específicos, como, por exemplo, a observação, a supervisão ou
o controle de uma planta industrial.

Essa função específica de um sistema embarcado o torna um sistema de computador para fins
especiais, em contraste com os sistemas de computador para fins mais gerais, como
computadores de mesa ou laptops.

A imagem, a seguir, apresenta uma configuração simplificada de um processo de controle


implementado por um sistema embarcado.

Observe o uso de sensores, para capturar dados do ambiente, e dos atuadores, que atuam em
movimentos de motores, por exemplo, para estabelecer o controle. Dentro do controlador principal,
temos o firmware que gerencia as entradas e saídas de interface com o usuário, mostrador e
botões, por exemplo. Como todo sistema computacional, o sincronismo é realizado por um circuito
de relógio (clock ).

Imagem: Marcos Santana Farias, 2021.


 Configuração simplificada de um sistema embarcado.

Os sistemas embarcados, em sua maioria, são gerenciados por microcontroladores, mas também
por microprocessadores e processadores digitais de sinais (DSP), estes com firmwares
embarcados.

Circuitos integrados de aplicação específica (ASIC) e matrizes de portas programáveis em campo


(FPGA) podem gerenciar sistemas embarcados de alto desempenho sem software embarcado.

FPGAs e ASICs são sistemas de processamento baseados em hardware digital, descrito e


integrado no chip com ferramentas de software específicas dos fabricantes.

FPGAs podem ser reprogramados, mas não os ASICs. Assim, não existe para os mesmos a
possibilidade de alterar a funcionalidade depois da fabricação.

FPGAs e ASICs podem acionar componentes externos com grande quantidade de portas para
manuseio de interfaces elétricas diversas.

No caso dos sistemas embarcados que integram um software, para que o sistema cumpra sua
função, cada parte deve fornecer ao projetista vantagens específicas:

A parte do software permite reprogramar a funcionalidade de um sistema para vários fins.


Portanto, favorece a flexibilidade do projeto.

A parte de hardware permite obter melhor desempenho de execução e aumenta significativamente


a capacidade do sistema de satisfazer as restrições, por exemplo, de velocidade, gasto de energia
e memória.
A forma como a parte do software é programada também pode afetar o desempenho do sistema, o
que restringe a programação de sistemas embarcados a poucas linguagens.

TIPOS DE SISTEMAS EMBARCADOS


Os sistemas embarcados podem ser classificados em quatro categorias, com base em seus
requisitos de desempenho e funcionais:

SISTEMAS EMBARCADOS AUTÔNOMOS


Os sistemas embarcados autônomos não requerem um sistema hospedeiro (host ), como um
computador. Sendo autônomo, ele funciona sozinho. É a aplicação mais conhecida dos sistemas
embarcados, na qual captura os sinais das portas de entrada analógicas ou digitais, processa,
calcula e converte os dados e fornece os valores resultantes por meio dos dispositivos conectados.
Exemplos de sistemas embarcados independentes são câmeras digitais, consoles de videogame,
fornos de micro-ondas e sistemas de medição de temperatura ou pressão arterial.

SISTEMAS EMBARCADOS DE TEMPO REAL


Um sistema embarcado de tempo real é definido como aquele que fornece uma resposta
necessária em determinado tempo, sem atrasos. Logo, esses tipos de sistemas embarcados
seguem os prazos de conclusão de uma tarefa. Boa parte dos sistemas embarcados são de tempo
real, notadamente os que não possuem sistema operacional. Nesse ponto, podemos definir três
abordagens com respeito a sistemas operacionais em sistemas embarcados.

Bare Metal ‒ significa que não há, de fato, nenhum sistema operacional. Essa é a
abordagem original de trabalho com sistemas embarcados, e trata-se, ainda, da mais
popular, por ser econômica e eficiente. Na programação bare metal , escreve-se um
firmware , executado diretamente no hardware, sem ter a abstração subjacente dos sistemas
operacionais. Geralmente, os programas bare metal terão um carregador de programa
(bootloader ) mínimo para iniciar o processador, o relógio e a memória, saltando para o
programa principal.

RTOS ‒ significa "sistema operacional de tempo real". Um sistema RTOS fornece garantias
exatas em relação ao tempo em que as operações serão concluídas, trazendo o que há de
bom no Bare Metal , que não possui sistema operacional.
Linux ‒ ele se comporta mais como um "computador real", o que é ótimo por muitas razões.
No entanto, por causa disso, não fornece garantias de determinismo no tempo de execução.
Raspeberry pi e BeagleBone estão nessa solução.

SISTEMAS EMBARCADOS EM REDE


Esses tipos de sistemas embarcados estão relacionados a uma rede para acessar os recursos. A
conexão pode ser com ou sem fio. Esse tipo de sistema é a área atual de crescimento mais rápido
em aplicações de sistema embarcado. O servidor web embutido é um tipo de sistema em que
todos os dispositivos embutidos são conectados a um servidor, acessados e controlados por um
navegador da web. Exemplo de sistema embarcado em rede LAN é um sistema de segurança
doméstico, em que todos os sensores são conectados sob o protocolo TCP/IP. Alguns consideram
os sistemas embarcados em rede, principalmente com comunicação sem fio, o futuro da utilização
em massa desses sistemas. Assim como, há muito, não se concebe um sistema embarcado sem
comunicação serial, a comunicação sem fio pode vir a ser o padrão pela necessidade de que todo
sistema embarcado se integre em rede com o crescimento da Internet das Coisas (IoT).

SISTEMAS EMBARCADOS MÓVEIS


Os sistemas embarcados móveis são os usados em dispositivos embarcados portáteis, como
telefones celulares, câmeras digitais, medidores temperatura e relógios inteligentes, dentre muitos
outros.

Ser classificado em uma categoria não exclui a classificação em outra. Assim, um sistema pode
ser autônomo, de tempo real e móvel, como, por exemplo, uma câmera digital.

EXEMPLOS DE SISTEMAS EMBARCADOS


Existe uma lista interminável de exemplos de sistemas embarcados, como já pudemos observar.
Vamos citar alguns em mais detalhes para que possamos reconhecer essas aplicações mais
facilmente e justificar a sua classificação como sistema embarcado.

CÂMERA DIGITAL

As câmeras que usamos hoje são inteligentes e têm muitos recursos que não estavam presentes
nos primeiros modelos, tudo por causa do sistema embarcado usado nelas. Uma câmera digital
tem basicamente três funções:

Capturar uma imagem (que chamamos de dados).


Armazenar esses dados da imagem.


Apresentá-los.

Funções adicionais, como foco automático, alteração da imagem para contraste e brilho,
estabilização da imagem, detecção de sorrisos para disparo, dentre outras, são proporcionadas por
sensores e processamento de alto desempenho do sistema embarcado.

As câmeras digitais mais usadas hoje estão integradas, como todos esses recursos, nos
smartphones. As imagens são armazenadas e processadas na forma de dados digitais binários.
Não há necessidade, como no passado, de utilizar filme para armazenar as imagens. Esse recurso
aumentou a capacidade de armazenamento e facilitou a transferência de imagens.

 COMENTÁRIO

Podemos dizer que a câmera é um dos exemplos importantes de sistemas embarcados. Possui
processador próprio, sensores, atuadores e memória para armazenamento.

SISTEMAS EMBARCADOS AUTOMOTIVOS

Hoje, os carros usam sistemas embarcados para substituir os antigos sistemas tradicionais. Os
automóveis que usam sistemas embarcados podem consistir em centenas de processadores ou
controladores.

Cada controlador executa sua própria tarefa dedicada.

Alguns deles controlam motores.

Outros atendem aos dispositivos de painel.


O uso de sistemas embarcados no setor automotivo reduziu o fator de custo, melhorou o
desempenho geral e aumentou as funcionalidades, reduzindo o peso e tornando os automóveis
mais seguros e confiáveis.

As aplicações de sistemas embarcados automotivos incluem, dentre outras:

Controle automático de estabilidade;

Sistema de controle de tração;

Airbag;

Sistema de navegação;

Sistema de controle de temperatura.

ROBÔS INDUSTRIAIS

Os sistemas embarcados têm muitas aplicações nas indústrias. Hoje, todo o processo industrial
está sendo levado para a automação.

Um robô industrial é um sistema embarcado que possui uma variedade de formas, sendo que cada
uma executa uma série de tarefas diferentes. Alguns robôs industriais são usados para mover
peças, ferramentas, materiais etc. Alguns são usados em operações de montagem, enquanto
outros, na fabricação.

Esses robôs aumentaram muito a produtividade nos processos industriais, sendo amplamente
utilizados onde operações precisas são necessárias ou nas operações pesadas em locais de difícil
acesso e insalubres para humanos.

MÁQUINA DE LAVAR AUTOMÁTICA

Exemplos de eletrodomésticos com sistemas embarcados incluem máquinas de lavar e secar


automáticas. As máquinas possuem um controlador para gerenciar todas as tarefas. Sensores e
atuadores, nesse caso, são sensores de nível, válvulas e motores, além de mostrador e teclado
para entrada de informações.

Foto: Shutterstock.com

Depois de colocar as roupas na máquina, todo o processo consiste nas funções dedicadas de
lavar, enxaguar e centrifugar, com as temporizações para cada ciclo podendo ser alteradas por
meio do teclado.

SMARTPHONES

Voltamos à discussão inicial:

Smartphones são sistemas embarcados?

Um sistema embarcado é uma combinação de hardware e software de computador, e talvez de


sensores, atuadores e/ou outras peças adicionais, projetadas para executar uma função dedicada.
Os sistemas embarcados podem fazer parte de um sistema ou produto maior, como é o caso de
um sistema de frenagem antibloqueio em um carro.

Vamos, agora, verificar alguns itens existentes em um smartphone:

Tela sensível ao toque

Circuitos para comunicação com rede de voz

Bluetooth

Processador de áudio
Circuitos para comunicação com rede sem fio (WiFi)

Conectividade USB

Sistema operacional

Sensores (acelerômetro, giroscópio)

Câmera integrada

Memória de armazenamento

Sensor de localização (GPS)

Processador central

Podemos considerar que o processador central, junto com todo o hardware periférico sincronizado,
usando um software embarcado, constitui um sistema embarcado.

Smartphones podem, dessa forma, ser considerados como um sistema embarcado complexo e
sofisticado.

Outro ponto de vista pode considerar o smartphone como um sistema completo, um dispositivo de
computação de uso geral que executa o sistema operacional no qual o usuário trabalha. No
entanto, eles contêm vários sistemas embarcados, como o núcleo do modem e as soluções de
chip único para Wi-Fi, Bluetooth e GPS. Nessa forma de avaliar, um smartphone moderno não é
um computador com poucos recursos, nem um sistema embarcado de última geração, mas um
computador de uso geral completo. Eles são, primeiro, um computador móvel e, depois, um
sistema de chamadas telefônicas.

 COMENTÁRIO

A diferença entre o sistema embarcado e o sistema de uso geral está diminuindo hoje em dia. O
smartphone pode estar na categoria de computador de uso geral porque podemos usar vários
aplicativos. Podemos modificar, instalar e desinstalar os aplicativos.
Por outro lado, ele vem com sistema operacional pré-instalado e não podemos modificá-lo. Aqui,
“modificar” significa que não podemos instalar outro sistema operacional, como fazemos em um
PC, como Linux e Windows. Além disso, não podemos atualizar a funcionalidade do smartphone
além do permitido pelo fabricante. Portanto, essas condições estão de acordo com a definição do
sistema embarcado.

Smartphones estão, realmente, na divisa entre os sistemas embarcados e os computadores de uso


geral, mas a classificação como sistema embarcado é a mais aceita.

Na perspectiva de um desenvolvedor de firmware , você pode pensar neles apenas como


sistemas embarcados de ponta. No entanto, se você está vindo do mundo da computação de uso
geral, pode pensar neles como computadores com recursos limitados. Seja como for, o importante
é ter os argumentos para defender o seu ponto de vista. Nosso primeiro passo, nesse sentido, será
identificar como os sistemas embarcados manipulam dados numéricos.

O QUE SÃO SISTEMAS EMBARCADOS?


No vídeo a seguir, apresentamos o conceito de sistemas embarcados, os seus tipos e exemplos de
aplicação.
VERIFICANDO O APRENDIZADO

1. CONSIDERE AS AFIRMAÇÕES A SEGUIR SOBRE SISTEMAS


EMBARCADOS DE TEMPO REAL.

UM SISTEMA EMBARCADO BASEADO EM LINUX É DE TEMPO REAL.

UM SISTEMA EMBARCADO QUE CONTROLA O AIRBAG DE UM


AUTOMÓVEL É DE TEMPO REAL.

UM SISTEMA EMBARCADO DE UM RELÓGIO DIGITAL É DE TEMPO


REAL.

UM SISTEMA EMBARCADO DE UMA SMART TV É DE TEMPO REAL.

QUAIS SÃO AS AFIRMAÇÕES CORRETAS?

A) I, II e III

B) I, III e IV

C) II e III

D) II, III e IV
E) Somente a II

2. AVALIE AS AFIRMAÇÕES A SEGUIR E A RELAÇÃO SUGERIDA ENTRE


ELAS.

SMARTPHONES SÃO CONSIDERADOS COMO UM SISTEMA


EMBARCADO.

PORQUE

O SMARTPHONE ESTÁ NA CATEGORIA DE COMPUTADOR DE USO


GERAL, ONDE PODEMOS MODIFICAR, INSTALAR E DESINSTALAR OS
APLICATIVOS.

A RESPEITO DESSAS AFIRMAÇÕES, ASSINALE A ALTERNATIVA CORRETA.

A) As asserções I e II são proposições verdadeiras e a II é uma justificativa correta da I.

B) As asserções I e II são proposições verdadeiras, mas a II não é uma justificativa correta da I.

C) A asserção I é uma proposição verdadeira e a II é uma proposição falsa.

D) A asserção I é uma proposição falsa e a II é uma proposição verdadeira.

E) As asserções I e II são proposições falsas.

GABARITO

1. Considere as afirmações a seguir sobre sistemas embarcados de tempo real.

Um sistema embarcado baseado em Linux é de tempo real.

Um sistema embarcado que controla o airbag de um automóvel é de tempo real.


Um sistema embarcado de um relógio digital é de tempo real.

Um sistema embarcado de uma Smart TV é de tempo real.

Quais são as afirmações corretas?

A alternativa "C " está correta.

Um dos primeiros pontos de decisão no projeto de sistemas embarcados é se o sistema exigirá


recursos de computação em tempo real. A computação em tempo real descreve a capacidade de
reagir às entradas e entregar a saída prescrita dentro de um período limitado, sem atrasos. Em
aplicações críticas, onde seu mau funcionamento pode fazer a diferença entre a vida e a morte, o
tempo real é obrigatório. Em geral, aplicações embarcadas com sistema operacional não são de
tempo real, excetuando as que utilizam RTOS (sistema operacional de tempo real). Assim,
somente as opções II e III são de tempo real. Sistemas embarcados com Linux não são de tempo
real, assim como os das Smart TVs, que, em geral, trabalham com Android ou sistemas baseados
em Linux, como WebOS.

2. Avalie as afirmações a seguir e a relação sugerida entre elas.

Smartphones são considerados como um sistema embarcado.

PORQUE

O smartphone está na categoria de computador de uso geral, onde podemos modificar,


instalar e desinstalar os aplicativos.

A respeito dessas afirmações, assinale a alternativa correta.

A alternativa "B " está correta.

Smartphones são sistemas embarcados complexos, assim como outros dispositivos modernos,
como as Smart TVs e os tablets. Porém, a justificativa para serem classificados como sistemas
embarcados não é o fato de serem um computador de uso geral.
A classificação como computador de uso geral é aceita pela diversidade de aplicativos e utilitários
que podem ser usados. Porém, a classificação como sistema embarcado vem da combinação de
hardware e software com sensores, atuadores e outros dispositivos adicionais, todos projetados
para executar uma função dedicada.

MÓDULO 2

 Identificar as bases de numeração e a conversão entre bases

SISTEMAS DE NUMERAÇÃO: BASES E


CONVERSÃO
Nós, humanos, fazemos contas há muito tempo. Para isso, usamos sistemas que relacionam
símbolos únicos a valores específicos.

O sistema numérico é a técnica que usamos para representar e manipular números. Assim, esse
sistema deve ter símbolos exclusivos para cada valor, ser consistente, facilmente reproduzível e
fornecer valores comparáveis. Nos familiarizamos desde crianças com o sistema decimal que
forma a base de como os humanos contam. O sistema decimal tem uma base 10 porque fornece
10 símbolos (0 a 9) para representar todos os números. Nós passamos a usar o sistema decimal,
muito provavelmente, porque temos 10 dedos para contar. No entanto, os sistemas computacionais
não possuem essa facilidade.

Para contar, um sistema computacional só consegue usar a informação ligado ou desligado, que
pode ser representada, respectivamente, por 1 e 0.

Portanto, os computadores representam as informações de maneira diferente dos humanos, e,


assim, precisamos de sistemas diferentes para representar os números.

BASES E NOTAÇÃO POSICIONAL


Você contou na base 10 durante toda a sua vida. Com muita rapidez, se lhe perguntarem quanto é
8 + 4, você responde 12. No momento desse cálculo, você está pensando na base 10. Vamos dar
uma olhada mais de perto no que você tem feito todos esses anos e talvez não tenha pensado
sobre isso.

Quando estamos fazendo uma contagem, primeiro percorremos todos os dígitos: 0, 1, 2 ... 8, 9.
Depois de atingir o 9, você não tem mais dígitos para representar o próximo número. Então, você
muda de volta para 0 e adiciona 1 ao dígito das dezenas, chegando ao 10. O processo se repete
continuamente.

Embora tudo isso seja muito básico, você não deve ignorar o que está acontecendo. O dígito mais
à direita representa o número de unidades, o próximo dígito representa o número de dezenas, o
seguinte, o número de centenas, e assim por diante. Você deve ter notado um padrão. Vejamos o
que acontece, matematicamente, usando, como exemplo, o número 375:

Como podemos observar, existem 3 grupos de 100 unidades em 375. Não por coincidência,

100 = 10x10, que também pode ser escrito como 102.

Existem 7 grupos de dez unidades, e 10 = 101.

Finalmente, existem 5 grupos de uma unidade e, como qualquer número elevado a 0 é igual

a 1, por definição, 1 = 100.

Podemos concluir que um número decimal pode ser escrito por um polinômio em potências de 10.
Assim, 375 na base 10 pode ser considerado como:

375 = 3 x 102 + 7 x 101 + 5 x 100

Falar sobre números escritos em bases múltiplas pode causar confusão. Por exemplo, 10 na base
2 não é igual a 10 na base 10. Portanto, quando necessário, usaremos uma notação padrão em
que um subscrito denota a base dos números. Por exemplo, nossa versão na base 2 do valor 10
agora se apresenta como 102.

Conforme observado, todos sabemos o valor de um número de base 10, porque sempre usamos a
base de 10, e isso vem naturalmente para nós. No entanto, se entendermos os padrões da
notação posicional da base 10, podemos entender melhor as outras bases. De acordo com o que
vimos na base 10, temos que qualquer número inteiro positivo b, (b > 1), pode ser escolhido como
a base (ou raiz) de um sistema numérico. Se a base for b, então b dígitos são usados [0,1,2,3, ...,
b-1]. Esse padrão pode ser usado na definição de outras bases. Assim, um número na base 2
(binário) é representado por dígitos 0 e 1, e um número na base 8 (octal) é representado por
dígitos de 0 a 7. Para bases maiores que 10, geralmente, usamos letras para representar dígitos
maiores que 9. Um exemplo é o sistema numérico de base 16, conhecido como sistema
hexadecimal. Neste, usamos dígitos 0-9, e depois A (representando 10 em decimal), B
(representando 11) etc. A imagem a seguir resume o padrão de representação dessas bases.

Imagem: Marcos Santana Farias.


 Quatro sistemas de numeração utilizados em computação.

SISTEMA NUMÉRICO DE BASE 2


Os circuitos integrados em um computador são feitos de muitos transistores, ativados pelos sinais
eletrônicos (baixo e alto) que recebem. Assim como um interruptor de luz, o transistor permite ou
impede que a corrente flua. Portanto, ele tem apenas dois estados: ligado e desligado.

O ligado indica o estado alto e o desligado, o estado baixo de um transistor.

Esses estados podem ser representados usando os dois dígitos, 1 e 0, respectivamente. Esses
dois dígitos formam o sistema numérico binário, também referido como sistema de base 2, pois
tem apenas dois dígitos. Essa informação, ligado ou desligado, representa o que chamamos de um
bit para um computador. Assim, um bit é a unidade mais básica de armazenamento em um
computador.

Quando se trata de colocar valores e dígitos nesse sistema, colocamos valores correspondentes
às potências, ou aos pesos, ascendentes de 2 da direita para a esquerda. Assim, o número 1011
em binário pode ser representado na notação posicional como:
10112  


Atenção! Para visualização completa da equação utilize a rolagem horizontal

O dígito mais à esquerda é o bit mais significativo (MSB).

O dígito mais à direita é chamado de bit menos significativo (LSB).

Você pode manipular os bits à esquerda e à direita com operadores bit a bit na programação
embarcada para alterar com eficiência o valor de um número no nível do código de máquina.

Mas qual o valor do número binário 1011 em decimal?

CONVERSÃO ENTRE AS BASES DECIMAL E


BINÁRIA

Agora que sabemos os fundamentos do sistema binário, vamos aprender como converter entre
decimal e binário. Começamos com a conversão binária para decimal. Sabemos que o sistema
binário tem valores nominais de potências de 2.

Esses valores são pesos para os dígitos (0 ou 1) nessas posições. Funciona assim:

Multiplicamos cada dígito por seu peso (2 elevado à sua posição).

Somamos todos os fatores para obter o número decimal.

Vamos pegar o número binário 1011 e convertê-lo para o sistema numérico decimal usando a
notação posicional que já conhecemos:

10112 = 1×23 + 0×22 + 1×21 + 1×20 = 1×8 + 0×4 + 1×2 + 1×1 = 11


Atenção! Para visualização completa da equação utilize a rolagem horizontal

Agora vamos tentar o contrário.

Como convertemos de um número decimal em um número binário?


Um método para fazer isso é a divisão repetida, um atalho útil. Assim, pegue, por exemplo, o
número 11.

Começamos dividindo-o por dois e anotando o resto da divisão.



Quando dividimos 11 por 2, obtemos 5 com o resto 1.



Em seguida, pegamos 5 e dividimos por 2, chegando ao resultado de 2 com resto 1.



Esse processo continua até chegarmos a zero.

Os restos que reunimos, na ordem inversa, formam nosso número binário. Veja esses passos na
imagem a seguir.

Imagem: Marcos Santana Farias.


 Conversão de um número decimal em seu equivalente em binário.
SISTEMA NUMÉRICO DE BASE 8
Com o aumento do valor de um número decimal, o número de bits em sua representação binária
também aumenta. Às vezes, um número binário é tão grande que se torna difícil visualizá-lo. O
sistema numérico octal, ou de base 8, foi concebido para uma representação compacta dos
números binários.

Você deve observar um padrão semelhante aos anteriores vistos, na base 10 e na base 2. Depois
que chegarmos ao 7, ficamos sem dígitos diferentes para qualquer número maior. Precisamos de
uma maneira para representar o oito de alguma forma. Portanto, adicionamos outro dígito,
alteramos o 7 de volta para 0 e terminamos com 10.

CONVERSÃO ENTRE AS BASES OCTAL E


BINÁRIA

Dado um número binário, um número octal equivalente, representado por 3 bits, é calculado
agrupando 3 bits da direita para a esquerda e substituindo cada grupo de 3 bits pelo dígito octal
correspondente. Mas por que 3 bits em um número binário são agrupados para obter o número
octal?

Vimos que o valor base do sistema numérico octal é 8.

Converta o valor 8 em termos de expoente de 2, ou seja, 8 = 23.

Portanto, três dígitos binários são suficientes para representar todos os 8 dígitos octais.

Em termos simples, conte todas as combinações possíveis de três dígitos binários, que são 2x2x2
= 8.

Portanto, 3 bits são suficientes para representar qualquer dígito octal. Consequentemente, grupos
de 3 bits em um número binário são formados para obter um número octal equivalente.

Caso o número de bits em um número binário não seja múltiplo de 3, adicione o número
necessário de 0s na posição mais significativa do número binário.

 EXEMPLO
Para converter 100011002 em número octal:

Faça o agrupamento de 3 bits do número binário fornecido (da direita para a esquerda) 010
001 100.

Grave o número octal para cada grupo de 3 bits: 2 1 4

Portanto, 100011002 = 2148

O raciocínio inverso pode ser usado para converter de octal para binário. O número octal é
convertido em binário, substituindo cada dígito octal por um grupo de três dígitos binários.

 EXEMPLO

Para converter 4678 em um número binário:

Dígitos octais 4 6 7.

Escreva o valor binário de 3 bits para cada dígito 100 110 111.

Portanto, 4678 = 1001101112

SISTEMA NUMÉRICO DE BASE 16


O sistema numérico hexadecimal, assim como sistema octal, é uma forma mais compacta de
representar números em um computador, pois requer apenas 4 bits para representar o valor de um

dígito. Isso ocorre porque 4 bits (24 = 16) são suficientes para representar os 16 símbolos
alfanuméricos.

O hexadecimal usa os 10 números do sistema decimal e seis símbolos extras, A, B, C, D, E e F.

O sistema hexadecimal tem aplicações na programação em baixo nível, como na linguagem de


montagem. Isso porque os endereços de memória de um sistema computacional são
representados em hexadecimal. A memória é composta de locais que possuem um endereço
exclusivo. Normalmente, o tamanho de um endereço de memória é de 16 ou 32 bits. Assim, para
acessar o endereço de memória de 16 bits, um programador precisa usar 16 ou 32 bits, o que é
difícil de lidar. Para simplificar a representação do endereço, números hexadecimais são usados.

Vamos considerar um endereço de memória de 16 bits 11010011001101112. Usando a notação

hexadecimal, esse endereço é mapeado para D33716, mais fácil de lembrar e trabalhar.

Agora, pelo que vimos da conversão de binário para octal, você consegue deduzir como foi feita
essa conversão?

Como 4 bits são suficientes para representar os 16 símbolos alfanuméricos da numeração


hexadecimal, grupos de 4 bits em um número binário são formados para obter um número
hexadecimal equivalente.

Caso o número de bits em um número binário não seja múltiplo de 4, devemos adicionar o número
necessário de 0s na posição mais significativa do número binário. Dessa forma, o agrupamento de
4 bits do número binário fornecido (da direita para a esquerda) fica 1101 0011 0011 0111.

Assim, para cada conjunto de 4 bits, temos os números decimais 13, 3, 3 e 7. O número 13 em
hexadecimal é representado pela letra D. Logo, o número hexadecimal equivalente é D33716.

 VOCÊ SABIA

Números hexadecimais também são usados para descrever as cores na página da web.

Cada cor é composta por três cores primárias (vermelho, verde e azul) popularmente chamadas
RGB. Na maioria dos mapas coloridos, cada cor é geralmente escolhida em uma paleta de 16
milhões de cores. Portanto, são necessários 24 bits para representar cada cor com três
componentes (8 bits para o vermelho, 8 bits para o verde, 8 bits para o componente azul). Fica
difícil lembrar o código de cores binário de 24 bits. Assim, os códigos de cores são escritos na
forma hexadecimal para representação compacta.

Por exemplo, o código de 24 bits para amarelo é 11111111, 11111111, 00000000. O equivalente
hexadecimal é FF0, bem mais fácil de usar e memorizar.

CONVERSÃO DE OUTROS SISTEMAS


NUMÉRICOS PARA O SISTEMA NUMÉRICO
DECIMAL
Podemos usar as mesmas etapas usadas para converter o número binário em decimal para fazer a
conversão de um valor na base b em seu equivalente decimal, no qual o valor b pode ser 2, 8, 16
ou outro valor para o sistema de numeração.

ETAPA 01
Escreva o número da posição para cada símbolo alfanumérico do número fornecido.

ETAPA 02
Obtenha o valor posicional de cada símbolo, elevando seu número de posição ao valor da base b
do número fornecido.

ETAPA 03
Multiplique cada dígito com o respectivo valor posicional para obter um valor decimal.

ETAPA 04
Adicione todos esses valores decimais para obter o número decimal equivalente.

Veja o exemplo de conversão do número 3628 em seu equivalente decimal:

3628 = 3×82 + 6×81 + 2×80 = 3×64 + 6×8 + 2×1 = 24210


Atenção! Para visualização completa da equação utilize a rolagem horizontal

CONVERSÃO DE DECIMAL PARA OUTROS


SISTEMAS NUMÉRICOS
Também aqui podemos utilizar as mesmas etapas usadas para converter um decimal em um
número binário. Para converter um número decimal em qualquer outro sistema numérico (binário,
octal ou hexadecimal), use as etapas fornecidas a seguir.

ETAPA 01
Divida o número fornecido pelo valor da base (b) do sistema numérico em que será convertido.

ETAPA 02
Observe o valor de resto da divisão.

ETAPA 03
Continue dividindo o quociente pelo valor base e guarde o resto até que o quociente seja zero.

ETAPA 04
Escreva os restos anotados na ordem inversa (de baixo para cima).

Veja a seguir o exemplo de conversão do número 12710 em seu equivalente hexadecimal:

Imagem: Marcos Santana Farias.


 Conversão de um número decimal em seu equivalente hexadecimal.
CONVERTENDO BASES NUMÉRICAS
Para finalizarmos este módulo, abordarmos no próximo vídeo o processo de conversão de bases
numéricas.

VERIFICANDO O APRENDIZADO
1. O SISTEMA DE NUMERAÇÃO MAIS CONHECIDO É O DECIMAL, QUE
OPERA COM A BASE 10. PORÉM, EXISTEM OUTROS SISTEMAS DE
NUMERAÇÃO MUITO UTILIZADOS EM SISTEMAS COMPUTACIONAIS, COMO
BINÁRIO, OCTAL, HEXADECIMAL. CONSIDERANDO A REPRESENTAÇÃO
E3, ANALISE AS AFIRMATIVAS ABAIXO.

É UMA REPRESENTAÇÃO QUE PODE PERTENCER AO SISTEMA DE


NUMERAÇÃO HEXADECIMAL.

CONVERTENDO-A PARA A BASE BINÁRIA, VERIFICAREMOS QUE


POSSUI MSB IGUAL A 0.

SE CONVERTIDA PARA A BASE DECIMAL, EQUIVALE AO NÚMERO 227.

QUAIS AS OPÇÕES ESTÃO CORRETAS?

A) I e II

B) I e III

C) II e III

D) Somente a I

E) Somente a II

2. ANALISANDO A REPRESENTAÇÃO OCTAL 38, MARQUE A ALTERNATIVA


QUE INDICA RESPECTIVAMENTE A REPRESENTAÇÃO BINÁRIA E A
REPRESENTAÇÃO DECIMAL DESSE NÚMERO.

A) 011111 e 38

B) 001111 e 31

C) 011111 e 31

D) 101111 e 38

E) 38 não existe na representação octal.


GABARITO

1. O sistema de numeração mais conhecido é o decimal, que opera com a base 10. Porém,
existem outros sistemas de numeração muito utilizados em sistemas computacionais, como
binário, octal, hexadecimal. Considerando a representação E3, analise as afirmativas abaixo.

É uma representação que pode pertencer ao sistema de numeração hexadecimal.

Convertendo-a para a base binária, verificaremos que possui MSB igual a 0.

Se convertida para a base decimal, equivale ao número 227.

Quais as opções estão corretas?

A alternativa "B " está correta.

E3 é uma representação que pode pertencer ao sistema de numeração hexadecimal (16 bits),
além de outras a partir de 15 bits, pois essas representações usam letras maiúsculas para
representar números de 10 em diante. O MSB é o dígito mais significativo de um número binário.
Precisamos converter E3 de hexadecimal para binário. 4 bits são suficientes para representar um
símbolo alfanumérico da numeração hexadecimal. Assim, o símbolo E em hexadecimal é
convertido para 1110 (14 em decimal). O símbolo 3 em hexadecimal é convertido para 0011.
Assim, o número binário correspondente a E3 em hexadecimal é 11100011, que possui MSB igual
a 1. Por fim, para converter E3 de hexadecimal para decimal, usamos a notação posicional. Assim,
E316 = E×161 + 3×160 = 14×16 + 3×1 = 22710

2. Analisando a representação octal 38, marque a alternativa que indica respectivamente a


representação binária e a representação decimal desse número.

A alternativa "E " está correta.

Existe um padrão que deve ser observado em qualquer base numérica. Assim como na base 10
temos a representação com dígitos de 0 a 9, e na base 2 de 0 a 1, em qualquer outra base b, b
dígitos são usados [0,1,2,3, ..., b-1]. Dessa forma, na base 8, os dígitos usados vão de 0 a 7. Isso
porque, quando chegamos ao 7, ficamos sem dígitos diferentes para qualquer número maior. Por
conclusão, 38 não pode ser existir na representação octal, de base 8.
MÓDULO 3

 Empregar as regras da álgebra booleana no desenvolvimento de sistemas embarcados

ÁLGEBRA BOOLEANA
Você já sabe que um sistema computacional é um sistema digital no qual as quantidades variam
em níveis discretos, ligado ou desligado, 1 ou 0. Dessa forma, os sistemas digitais transportam
informações usando combinações de sinais 1s e 0s, utilizando o sistema de numeração binário que
conhecemos. Uma das melhores coisas sobre o sistema binário está no fato de que ele é muito
eficiente no tratamento de operações especiais, chamadas de operações lógicas.

As operações lógicas comparam dois bits e estabelecem um terceiro bit como resultado dessa
comparação. Operações lógicas são realizadas em um sistema digital por circuitos digitais lógicos.

Mas o que ocorre entre a entrada e saída desses circuitos lógicos para permitir o processamento
das operações lógicas?

Vamos analisar a programação de sistemas embarcados digitais sobre o ponto de vista da álgebra
booleana e da lógica matemática, fundamentais para o entendimento do processamento dos dados
nesses sistemas.

ÁLGEBRA BOOLEANA E OPERAÇÕES


LÓGICAS BINÁRIAS
Os computadores digitais modernos são projetados usando técnicas e simbologia de um campo da
matemática chamado álgebra moderna. Os matemáticos têm estudado por mais de cem anos um
ramo chamado de álgebra booleana. A álgebra booleana inclui métodos para manipular variáveis
e expressões lógicas. O filósofo grego Aristóteles fundou um sistema de lógica baseado em
apenas dois tipos de proposições: “verdadeiro” e “falso”. Sua definição bivalente (de dois modos)
da verdade levou às leis fundamentais da lógica.

Nada poderia ser mais simples e normal para o raciocínio humano do que as regras de uma
álgebra booleana, pois essas se originaram em estudos de como raciocinamos, quais linhas de
raciocínio são válidas, o que constitui prova e outros assuntos relacionados.

 VOCÊ SABIA

O nome álgebra booleana homenageia um grande matemático inglês, George Boole, que em 1854
publicou um livro clássico, Uma investigação das leis do pensamento , no qual fundamenta as
teorias matemáticas da lógica e das probabilidades. A intenção declarada de Boole era realizar
uma análise matemática da lógica.

Boole procurou dar forma simbólica ao sistema de lógica de Aristóteles. Começando com sua
investigação das leis do pensamento, Boole construiu uma “álgebra lógica”, que passou a ser
conhecida como álgebra booleana.

Em meados do século XX, Claude Shannon, engenheiro eletrotécnico e matemático, aplicou as


ideias de Boole para manipular expressões lógicas na análise do que agora é chamado de
circuitos digitais, a base dos dispositivos eletrônicos digitais, dos projetos de circuitos lógicos e
sistemas computacionais que conhecemos.

E quais são esses circuitos digitais?

Os computadores digitais modernos são construídos a partir de circuitos lógicos digitais cujos
blocos de construção básicos são portas lógicas, sendo cada uma projetada para implementar uma
operação binária com uma função lógica específica.

As informações são mantidas em palavras de dados, representando dados numéricos ou


instruções, constituídas por sequências de bits individuais com valores 1 ou 0. Esses valores são
análogos às proposições da lógica booleana e às declarações ou conclusões delas derivadas, que
foram definidas como "verdadeiro" ou "falso".

 COMENTÁRIO

Álgebra booleana, portanto, é a ferramenta usada para projetar combinações de portas lógicas
para implementar funções mais complexas, como operações matemáticas e funções de controle.
Desse modo, todas as instruções dos programas que você criará para sistemas embarcados irão
passar por circuitos lógicos (formados por portas lógicas) que podem ser representados por
expressões na álgebra booleana.

E quais são as operações binárias implementadas pelas portas lógicas?


Portas lógicas digitais básicas executam operações lógicas de E (AND ), OU (OR ) e NÃO
(NOT ) com números binários. Existem também as variações NÃO E (NAND ) e NÃO OU
(NOR ), além das portas OU EXCLUSIVO (XOR ) e NÃO OU EXCLUSIVO (XNOR ). No projeto
da lógica digital, como já sabemos, apenas dois estados são permitidos, geralmente referidos
como Lógica “1” e Lógica “0”, ou ALTO (HIGH ) e BAIXO (LOW ), ou VERDADEIRO (TRUE ) e
FALSO (FALSE ), representados na Álgebra Booleana pelos números binários 1 e 0.

A imagem a seguir apresenta um resumo dos símbolos utilizados para representar as portas
lógicas e as suas respectivas tabelas-verdade para duas entradas, que mostram qual o resultado
na saída X para as combinações de entradas A e B. Com esse comportamento funcional, dado
pelas tabelas-verdade, as portas lógicas podem ser usadas para representar qualquer circuito
lógico.

Imagem: Marcos Santana Farias.


 Portas lógicas – símbolos e tabelas-verdade.

REPRESENTAÇÃO DAS OPERAÇÕES NA


ÁLGEBRA BOOLEANA
A álgebra booleana lida com variáveis binárias e operações lógicas. A operação OU também é
chamada de Adição Lógica, usando assim o símbolo da adição (+). Da mesma forma, a operação
E, chamada de Multiplicação Lógica, usa o símbolo da multiplicação (x, * ou nada entre duas
variáveis) para representá-la nas expressões. Uma barra em cima do caractere, ou um sinal gráfico
plica (‘), representa a lógica NÃO. O símbolo para OU Exclusivo é ⊕, enquanto o símbolo para
NÃO OU Exclusivo é ⊙. As expressões algébricas da lógica são também chamadas expressões
booleanas, funções lógicas ou funções booleanas, consistindo em variáveis binárias, as constantes
0 e 1 e os símbolos de operações lógicas.

 ATENÇÃO

A álgebra booleana, sendo uma operação lógica, permite que as regras usadas na álgebra de
números sejam aplicadas à lógica. Assim como uma expressão algébrica comum pode ser
simplificada por meio dos teoremas básicos, a expressão que descreve uma determinada rede de
circuitos de computação também pode ser reduzida ou simplificada. Esse é o grande benefício
da utilização da álgebra booleana.

Ao formalizar as regras da lógica, a álgebra booleana pode ser usada para simplificar expressões
booleanas que representam circuitos lógicos. Assim, ela reduz a expressão original a uma
expressão equivalente com menos termos, o que significa que menos portas lógicas são
necessárias para implementar o circuito lógico, trazendo enorme benefício econômico aos projetos
de sistemas computacionais.

CIRCUITOS DIGITAIS REPRESENTANDO


FUNÇÕES BOOLEANAS
Vamos examinar como as portas lógicas são usadas para representar e implementar as funções
booleanas em diagramas de circuitos digitais. Consideremos a seguinte função booleana:

F(A,B,C,D)=A+B(C+D)C


Atenção! Para visualização completa da equação utilize a rolagem horizontal

O circuito digital da figura abaixo implementa a função f(A,B,C,D). O circuito digital consiste em
funções lógicas elementares, implícitas na função.

Imagem: Marcos Santana Farias.


 Circuito digital que implementa a função booleana A+B(C+D)C.

E como chegamos ao circuito partindo da função?

Primeiro, precisamos ver que a função booleana poderia ser especificada por sua tabela-verdade.
A utilização da função booleana no lugar da tabela-verdade se dá pela simplificação. Circuitos com
maior quantidade de entradas teriam que ser representados por tabelas cada vez maiores para
analisar todas as possibilidades. A função booleana, para representar corretamente a tabela-
verdade, informa quais combinações das variáveis de entrada fornecem a saída ativada, igual a 1.

Analisando a função booleana, vemos que para chegarmos à saída igual a 1, temos uma
multiplicação lógica de três partes da função: A+B(C+D) e C.

Essa multiplicação pode ser realizada por uma porta lógica AND de três entradas, como mostrado
na figura. Considerando agora as 3 partes individuais, temos:

A+B é obtido com uma porta NOR

(C+D) é obtido com uma porta OR

C é obtido com uma porta NOT

Assim, o circuito mostrado na imagem anterior é obtido a partir das análises da função booleana.

LEIS E REGRAS DA ÁLGEBRA BOOLEANA


Na simplificação da expressão booleana, as leis e regras da álgebra booleana desempenham um
papel importante. Existem as seguintes leis da álgebra booleana:

LEI COMUTATIVA

Esta lei afirma que não importa em que ordem usamos as variáveis. Vimos que na álgebra
booleana, o OR e as operações de adição são semelhantes. No diagrama abaixo, a porta OR
mostra que a ordem das variáveis de entrada não importa de forma alguma. Para duas variáveis, a
lei comutativa da adição é escrita como:

A + B = B + A

Da mesma maneira, para duas variáveis, a lei comutativa da multiplicação é escrita como:

AB = BA

LEI ASSOCIATIVA

Esta lei estabelece que a operação pode ser realizada em qualquer ordem quando a prioridade das
variáveis for a mesma. Para três variáveis, a lei associativa da adição é escrita como:

A + (B + C) = (A + B) + C


Atenção! Para visualização completa da equação utilize a rolagem horizontal

De forma análoga, para três variáveis, a lei associativa da multiplicação é escrita como:

A (BC) = (AB) C

LEI DISTRIBUTIVA

De acordo com esta lei, se realizarmos a operação OR de duas ou mais variáveis e, em seguida,
realizarmos a operação AND do resultado com uma única variável, o resultado será semelhante a
realizar a operação AND dessa variável única com cada uma das duas ou mais variáveis e, em
seguida, executar a operação OR desse produto.

Para três variáveis, a lei distributiva é escrita como:


A (B + C) = AB + AC,

ou

A + (BC) = (A + B).(A + C)


Atenção! Para visualização completa da equação utilize a rolagem horizontal

LEI IDEMPOTENTE

Quando é realizada uma operação AND ou OR consigo mesma, a variável permanece


inalterada, ou seja:

AA = A

A + A = A

PROPRIEDADE DO 0

Temos uma variável de entrada A cujo valor é 0 ou 1. Quando executamos a operação AND com
0, o resultado sempre será 0. Quando executamos a operação OR com 0, o resultado sempre
será A.

(A.0) = 0

A + 0 = A

PROPRIEDADE DO 1

Temos uma variável de entrada A cujo valor é 0 ou 1. Quando executamos a operação OR com 1,
o resultado será sempre 1. Quando executamos a operação AND com 1, o resultado sempre será
A.

A + 1 = 1

A.1 = A
LEI COMPLEMENTAR

Quando é realizada uma operação AND e OR com seu complemento (negação), o resultado
será 0 e 1, respectivamente.

AA= 0

A + A = 1

LEI DA DUPLA NEGAÇÃO

Esta lei estabelece que, quando a variável vem com duas negações, o símbolo é removido e a
variável original é obtida.

A== A

LEI DE ABSORÇÃO

Esta lei nos permite absorver as variáveis semelhantes, conforme representado a seguir.

A + (AB) = A

A.(A + B) = A

Deduções da lei de absorção, utilizando regras já apresentadas:

 A + (A.B) = (A.1)+ (A.B) = A(1 + B) = A.1 = A

A(A + B) = (A + 0).(A + B) = A + (0.B) = A


Atenção! Para visualização completa da equação utilize a rolagem horizontal

LEIS DO TEOREMA DE MORGAN

A operação de um circuito lógico OR e AND permanecerá a mesma se invertermos todas as


entradas, mudarmos os operadores de AND para OR e OR para AND , e invertermos a saída.
Ou, em outras palavras:
O complemento ou a negação de um produto (AND ) de variáveis é igual à soma (OR ) dos
complementos das variáveis.

O complemento ou a negação de uma soma (OR ) de variáveis é igual ao produto (AND ) dos
complementos das variáveis.

AB = A + B

A+B = A.B

SIMPLIFICAÇÃO USANDO ÁLGEBRA


BOOLEANA
No quadro a seguir, temos um resumo das regras de equivalência usadas para simplificação das
expressões booleanas.

Idempotente AA = A A+A = A

Associativa (AB)C = A(BC) (A+B)+C = A+(B+C)

Comutativa AB = BA A+B = B+A

Distributiva A(B+C) = AB+AC A+BC = (A+B)(A+C)

Propriedade de 0 A.0 = F A+0 = A

Propriedade de 1 A.1 = A A+1 = T

Complemento AA=0 A+A=1


De Morgan AB =  A+B A+B = A¯B¯

Quadro: Regras de equivalência usadas para simplificação das expressões booleanas.


 Elaborado por Marcos Santana Farias.


Atenção! Para visualização completa da tabela utilize a rolagem horizontal

Suponha que você recebeu a função (expressão) booleana seguinte para construir um circuito
digital. Antes, você pode tentar a simplificação da expressão para construir um circuito equivalente
menor.

AB(A+B)(B+B)


Atenção! Para visualização completa da equação utilize a rolagem horizontal

 ATENÇÃO

A simplificação de funções booleanas é um passo importante no projeto de circuitos digitais. Como


vimos anteriormente, a álgebra booleana usa um conjunto de leis e regras de equivalência lógica
para definir a operação de um circuito lógico digital, com "0" e "1" sendo usados para representar
uma condição de entrada ou saída digital. A aplicação das regras exige atenção, sendo um
exercício fundamental no entendimento de circuitos digitais combinacionais, em que, em qualquer
instante de tempo, a saída depende apenas dos níveis presentes nos terminais de entrada.

Vamos aplicá-las.

AB(A+B)(B+B) 

AB(A+B)(B+B)

AB(A+B).1

AB(A+B)

(A+B)(A+B)

A + BB

A+0
A

Expressão original

Complemento → (B+B) = 1

Propriedade de 1 → AB(A+B)1 = AB(A+B)

De Morgan → AB = A+B

Distributiva → (A+B)(A+B) = A+BB

Complemento → BB = 0

Propriedade de 0 → A+0 = A


Atenção! Para visualização completa da equação utilize a rolagem horizontal

Verifique que, com a simplificação, a expressão equivalente necessita de somente uma porta
lógica NOT para implementar o circuito digital.

AS EXPRESSÕES BOOLEANAS
Assista ao vídeo a seguir. Nele, explicamos como representar os circuitos lógicos através de
expressões booleanas e a como simplificar estas expressões.
VERIFICANDO O APRENDIZADO

1. VOCÊ RECEBEU A EXPRESSÃO BOOLEANA ABAIXO PARA MONTAR O


CIRCUITO DIGITAL EQUIVALENTE. PORÉM, RESOLVEU SIMPLIFICAR A
EXPRESSÃO UTILIZANDO AS REGRAS DA ÁLGEBRA BOOLEANA PARA
USAR MENOS PORTAS LÓGICAS NO CIRCUITO A SER MONTADO. QUAL A
EXPRESSÃO SIMPLIFICADA?

AB+A(B+C)+B(B+C)

A) AB+AC+B

B) A+BC

C) AB+C

D) AC+AB+C

E) B+AC

2. A SEGUINTE EXPRESSÃO BOOLEANA FOI ENCONTRADA EM UM


MANUAL DE PORTÃO AUTOMÁTICO.

(A+B)(B+C)

QUAL O CIRCUITO ABAIXO SERVE PARA SER UTILIZADO NESTE PORTÃO?

A)

B)

C)
D)

E)

GABARITO

1. Você recebeu a expressão booleana abaixo para montar o circuito digital equivalente.
Porém, resolveu simplificar a expressão utilizando as regras da álgebra booleana para usar
menos portas lógicas no circuito a ser montado. Qual a expressão simplificada?

AB+A(B+C)+B(B+C)

A alternativa "E " está correta.

Partindo da expressão original, AB + A(B + C) + B(B + C), deve-se usar as regras a seguir: aplicar
a lei distributiva ao segundo e terceiro termos da expressão - AB + AB + AC + BB + BC. Aplicar a
regra (BB = B) para o quarto termo - AB + AB + AC + B + BC. Aplicar a regra (AB + AB = AB) para
os dois primeiros termos - AB + AC + B + BC. Aplicar a regra (B + BC = B) para os dois últimos
termos - AB + AC + B. Aplicar a regra (AB + B = B) ao primeiro e terceiro termos - B+AC.
Resultado final: B+AC.
2. A seguinte expressão booleana foi encontrada em um manual de portão automático.

(A+B)(B+C)

Qual o circuito abaixo serve para ser utilizado neste portão?

A alternativa "B " está correta.

Analisando a função booleana, vemos que para chegarmos à saída igual a 1 temos uma
multiplicação lógica de duas partes da função: (A+B) e (B+C). Essa multiplicação é realizada por
uma porta lógica AND de duas entradas. Considerando agora as duas partes individuais temos:
(A+B) é obtido com uma porta OR , assim como (B+C). Desse modo, o circuito terá duas portas
OR de duas entradas e uma porta AND de duas entradas na saída, recebendo as saídas das
portas OR , como mostrado na alternativa com a figura:

MÓDULO 4

 Distinguir as principais características e a importância da linguagem C

LINGUAGEM C E COMPILAÇÃO
Talvez você já tenha ouvido alguém falar que a linguagem C é muito antiga e ultrapassada. Se
você já programa em outra linguagem, essa afirmação pode trazer mais uma dificuldade de
convencê-lo da necessidade de se aprender a linguagem C.

Um bom argumento seria: C não é uma linguagem difícil de se aprender, e todos os benefícios do
seu aprendizado serão bem aproveitados em outras linguagens.

No entanto, há um argumento mais apropriado em nosso caso: uma das poucas uniformidades
na maioria dos sistemas embarcados é o uso da linguagem de programação C. Na realização
de um sistema embarcado, a programação do sistema desempenha um papel muito importante.
Portanto, a seleção correta da linguagem de programação é essencial. A predominância da
linguagem C é ampla nessa área, pois, ainda é, depois da linguagem de montagem, a que melhor
atende aos fatores mais relevantes na escolha de uma linguagem de programação para o
desenvolvimento de sistemas embarcados.

CARACTERÍSTICAS DAS LINGUAGENS DE


PROGRAMAÇÃO PARA SISTEMAS
EMBARCADOS
O desenvolvimento de software embarcado (firmware ), durante os anos dos primeiros projetos de
sistemas embarcados, era uma tarefa árdua em função de ser quase que exclusivamente realizada
em linguagem de montagem (assembly ).

A linguagem de montagem é uma linguagem de programação por meio de símbolos que mais se
aproxima da linguagem de máquina em forma e conteúdo.

É a linguagem de programação mais básica disponível para qualquer processador, sendo por isso
chamada de linguagem de baixo nível. Com a linguagem de montagem, um programador
trabalha apenas com operações que são implementadas diretamente na unidade central de
processamento, acionando registradores e posições de memória.

A linguagem de montagem geralmente carece das conveniências das linguagens de alto nível,
como variáveis e funções, e não é portável entre várias famílias de processadores. Estas têm as
mesmas estruturas e conjunto de comandos da linguagem de máquina, mas permitem que um
programador use nomes em vez de números. Essa linguagem ainda é útil para programadores de
sistemas embarcados quando a velocidade é necessária ou quando eles precisam realizar uma
operação que não é possível em linguagens de alto nível.
Com o aumento na complexidade e na demanda de qualidade pelo software embarcado, a procura
por novas formas de desenvolvimento que facilitassem atingir novos requisitos levou à busca por
linguagens de programação mais amigáveis do que a linguagem de montagem. O uso exclusivo de
linguagem de montagem no desenvolvimento de sistemas embarcados se tornaria muito pesado e
oneroso. Uma linguagem de programação para sistemas embarcados, no entanto, precisaria
seguir alguns requisitos bem restritos, como:

TAMANHO DO ARQUIVO GERADO


Os processadores embarcados têm uma quantidade muito limitada de memória de programa. Por
isso, o espaço ocupado pelo programa embarcado na memória é muito importante, devendo estar
otimizado para ser o menor possível, como ocorre no arquivo gerado pela linguagem de
montagem.

DESEMPENHO
Os programas devem ser executados o mais rápido possível. O hardware não deve ficar lento
devido a um software lento.

PORTABILIDADE
O mesmo código deve ser compilado para diferentes processadores com poucas modificações,
algo que a linguagem de montagem não permite.

MANIPULAÇÃO DE BITS
Usando operadores bit a bit, pode-se alterar os bits de registradores dos processadores
embarcados, como é feito na linguagem de montagem, algo que é imprescindível quando se trata
de sistemas embarcados.

A partir desses requisitos, a escolha da linguagem C para sistemas embarcados foi natural. O
ponto forte de C, e o que a diferencia de outras linguagens, é o fato de ser uma linguagem de alto
nível com atributos de “baixo nível”. C oferece aos programadores embarcados um grau
extraordinário de controle direto do hardware sem sacrificar os benefícios das linguagens de alto
nível.

 COMENTÁRIO

A natureza de “baixo nível” da linguagem C foi uma intenção clara do seu criador, Dennis M.
Ritchie (1988), que comentou em seu primeiro livro sobre a linguagem: “C é uma linguagem
relativamente de ‘nível baixo’. Essa caracterização não é pejorativa; significa simplesmente que C
lida com o mesmo tipo de objetos que a maioria dos computadores.”

A linguagem C foi projetada para implementar o Sistema Operacional Unix, ficando próxima ao
sistema operacional, o que a torna uma linguagem eficiente devido ao seu competente
gerenciamento de recursos no nível do sistema. Outro ponto importante no uso de C é que a
linguagem não é limitada, mas amplamente utilizada em sistemas operacionais, compiladores de
linguagem, drivers de rede.

Então, podemos dizer que, por projeto, a linguagem C se presta muito bem ao desenvolvimento
embarcado porque fica entre o software e o hardware de nível superior, permitindo que você
acesse e controle o hardware diretamente, sem sacrificar os benefícios de uma linguagem de alto
nível. Ela é particularmente eficaz para o hardware que precisará existir por um tempo, já que
programas escritos em C podem operar por décadas devido à alta estabilidade da linguagem.

A linguagem C também oferece aos desenvolvedores a capacidade de usar abstrações com


eficiência, sem muitos custos. A estrutura de dados de C, assim como a de C++, é baseada em
algoritmos, o que a torna uma ótima escolha para resolver todos os pequenos quebra-cabeças que
você encontrar durante o desenvolvimento embarcado. Essa linguagem também tem
independência em relação ao processador, facilitando a portabilidade de código.

 COMENTÁRIO

A linguagem C ainda é a padrão para ser usada no desenvolvimento embarcado, e provavelmente


será assim por muito tempo. À medida que nosso mundo se torna mais conectado por meio da
Internet e das aplicações de Internet da Coisas (IoT), continuaremos a ver a linguagem C sendo
usada em mais e mais sistema embarcados.

COMPILAÇÃO
Um código-fonte escrito em linguagem C precisa passar por um programa, chamado compilador,
para que tenhamos um código executável que funcione em um processador, seja esse de um
sistema embarcado ou não.

A compilação é o processo de tradução do código-fonte para um código em linguagem de


máquina, os 0s e 1s.
Ao final do processo de compilação, um arquivo executável em código binário fica disponível para
ser usado.

No caso dos sistemas embarcados, em geral, temos um arquivo.hex (hexadecimal) ou .bin.

No caso de um PC com sistema operacional Windows, temos um arquivo.exe.

Não existem muitas diferenças entre o processo de compilação em programas que rodam em
sistemas operacionais ou em um sistema embarcado. Porém, quando as ferramentas de
compilação são executadas no mesmo sistema do arquivo executável a ser gerado, caso do
Windows ou Linux, elas podem fazer muitas suposições sobre o sistema. Normalmente, esse não
é o caso no desenvolvimento de software embarcado, em que as ferramentas de compilação são
executadas em um computador diferente da plataforma de hardware de destino.

Nesse caso, estamos nos referindo à compilação para programas que são executados diretamente
no hardware, sem ter nenhuma abstração subjacente, como no caso dos sistemas operacionais.
Isso é chamado de programação bare metal . Geralmente, os programas bare metal terão um
carregamento (bootloader ) mínimo para iniciar o processador, relógio e memória, antes de saltar
para o programa principal. O processo de compilação, a conversão da representação do código-
fonte do seu software embarcado em uma imagem binária executável, pode ser sintetizado em três
etapas distintas:

ETAPA 01
Cada um dos arquivos de origem é compilado ou montado em um arquivo-objeto.

ETAPA 02
Todos os arquivos-objeto que resultam da primeira etapa devem passar pelo vinculador para
produzir um único arquivo-objeto, denominado programa relocável.

ETAPA 03
Os endereços de memória física devem ser atribuídos aos deslocamentos relativos dentro do
programa realocável em um processo denominado relocação, executado pelo localizador.

O resultado da etapa final é um arquivo contendo uma imagem binária executável que está pronta
para ser executada no sistema embarcado. O processo de compilação de software embarcado é
ilustrado na imagem a seguir. Cada uma dessas ferramentas de desenvolvimento pega um ou mais
arquivos como entrada e produz um único arquivo de saída.

Imagem: Marcos Santana Farias.


 Processo de compilação de software embarcado.

O compilador, montador, vinculador e localizador da imagem anterior são executados em um


computador host , um computador de uso geral, e não no próprio sistema embarcado. Ainda
assim, essas ferramentas combinam seus esforços para produzir um arquivo binário que será
executado corretamente apenas no sistema embarcado de destino.

ESTRUTURA DE UM PROGRAMA EM C
Antes de estudarmos os blocos de construção básicos da linguagem de programação C, vamos
examinar uma estrutura de programa C mínima para que possamos tomá-la como uma referência.
Um programa em C consiste basicamente nas seguintes partes:

Comandos do pré-processador

Funções

Variáveis

Declarações e Expressões

Comentários

Vejamos um código simples:


#include<stdio.h>

int main() {

/* meu primeiro programa em C */

printf("Bom dia! \n");

return 0;

Vamos verificar as várias partes do programa visto anteriormente:

A primeira linha do programa, #include <stdio.h>, é um comando ou instrução de pré-processador,


uma diretiva de inclusão que diz a um compilador C para incluir o arquivo stdio.h antes de ir para a
compilação real. Esse arquivo é um header, um cabeçalho para a biblioteca padrão stdio, que
possui declarações de funções úteis para entrada e saída de dados. Em um código para sistema
embarcado, é usada para incluir no processo de compilação as definições do chip, por exemplo,
como no caso abaixo, do microcontrolador PIC18F4550.

#include <18F4550.H>

A próxima linha int main () é a função principal onde a execução do programa começa.

A próxima linha /*...*/ será ignorada pelo compilador e foi colocada para adicionar comentários ao
programa. Portanto, essas linhas são chamadas de comentários no programa.

A próxima linha printf (...) é outra função disponível em C que causa a mensagem "Bom dia! " a ser
exibida na tela.

A próxima linha return 0; termina a função main () e retorna o valor 0.

Uma definição de pré-processador muito utilizada em sistemas embarcados é #define, que cria
uma string que será substituída por um número. Ela é útil porque permite modificar facilmente um
valor que aparece em várias partes diferentes do programa. Por exemplo:

#define TAXA 1000

Nesse caso, pode-se alterar 1000 para qualquer outro número e esse novo valor será usado para
substituir todas as instâncias da string TAXA. As definições de pré-processador também são uma
ótima maneira de tornar o código mais legível.

VARIÁVEIS E TIPOS DE DADOS EM C


Os compiladores podem gerenciar os detalhes de baixo nível associados a variáveis sem muita
entrada do programador. Porém, se você quiser otimizar o uso de variáveis, precisará saber algo
sobre a configuração de memória do dispositivo e a maneira como ele lida com dados de
diferentes larguras de bits. Alguns tipos básicos de dados que o C suporta são char, int, float,
double.

O formato geral para declarar uma variável é:

tipo nome_variavel;

 ATENÇÃO

Um nome de variável pode ter letras, dígitos e o símbolo underscore “_” (sublinhado). A primeira
letra de uma variável deve ser uma letra ou o símbolo “_”.

TIPOS DE DADOS DE FUNÇÃO

Os programas em C podem lidar com funções e parâmetros. O tipo de dado da função determina o
tipo de valor que pode ser retornado por uma determinada sub-rotina. Sem um tipo de retorno
especificado, qualquer função retorna um valor do tipo inteiro como seu resultado. A linguagem C
também oferece suporte a tipos de dados de parâmetro, que indicam valores que devem ser
passados para uma função especificada.

 ATENÇÃO

Quando uma função é declarada sem nenhum parâmetro, ou quando um valor de retorno não é
esperado, a função pode ser anotada como void .

TIPOS DE DADOS INTEIROS

A linguagem C suporta três tipos de dados diferentes para inteiros: int, short e long.
Em arquiteturas de 8 bits, o tamanho padrão dos valores int é normalmente definido como 16 bits,
mas a linguagem C permite que os tamanhos int sejam alternados entre 8 e 16 bits para reduzir o
consumo de memória.

O tipo de dados short int permite que os programadores especifiquem um valor inteiro com apenas
um ou dois bytes de tamanho.

Usar o tipo de dados long int aloca duas vezes a quantidade padrão de memória do tipo de dados
int.

TIPOS DE DADOS DE BITS

Em alguns compiladores C para sistemas embarcados, usa-se dois tipos de variáveis para
quantidades de tamanho de bit: bit e bits. Um valor de bit corresponde a um único bit
independente, enquanto os dados variáveis de bits são usados para gerenciar e endereçar
coletivamente uma estrutura de 8 bits. Os programadores podem atribuir um valor de byte a uma
variável de bits para permitir o endereçamento de bits individuais dentro dos dados.

NÚMEROS REAIS

Uma das diferenças maiores entre os aplicativos de computador desktop e aqueles usados para
alimentar sistemas embarcados é o tratamento de números reais e tipos de dados de ponto
flutuante (float ). Esses tipos de dados incluem números negativos e números com dígitos em
ambos os lados de uma vírgula decimal.

 COMENTÁRIO

Os números reais representam uma carga significativa nas capacidades de computação e


armazenamento de memória dos sistemas embarcados e, portanto, esses tipos de dados estão
entre os implementados com menos frequência.

Além dos tipos de dados convencionais, também existem tipos de dados complexos que podem
ser úteis para programar microcontroladores para aplicativos de sistemas embarcados. Isso inclui
tipos como ponteiros, matrizes, tipos enumerados (conjuntos finitos de valores nomeados),
estruturas (formas de estruturar outros dados) e muito mais.

MODIFICADORES

Modificadores, como long, short, signed e unsigned, podem ser acrescentados às variáveis,
alterando o alcance dos tipos de dados, como mostrado na tabela a seguir:

Tipo de dado e Tamanho


Tipo Intervalo
modificador em bytes

char Caractere 1 -128 a 127

signed char Caractere com sinal 1 -128 a 127

unsigned char Caractere sem sinal 1 0 a 255

Int Inteiro 2 -32.768 a 32.767

signed int Inteiro com sinal 2 -32.768 a 32.767

unsigned int Inteiro sem sinal 2 0 a 65.535

short int Inteiro curto 2 -32.768 a 32 767

signed short int Inteiro curto com sinal 2 -32.768 a 32.767


unsigned short int Inteiro curto sem sinal 2 0 a 65.535

-2.147.483.648 a
long int Inteiro long 4
2.147.483.647

-2.147.483.648 a
signed long int Inteiro longo com sinal 4
2.147.483.647

unsigned long int Inteiro longo sem sinal 4 0 a 4.294.967.295

Ponto flutuante com


float 4 3.4 E-38 a 3.4E+38
precisão simples

Ponto flutuante com 1.7 E-308 a


double 8
precisão simples 1.7E+308

Ponto flutuante com 3.4E-4932 a


long double 16
precisão dupla longo 1.1E+4932

 Tabela elaborada por Marcos Santana Farias.


Atenção! Para visualização completa da tabela utilize a rolagem horizontal

FUNÇÕES DE ENTRADA E SAÍDA


Funções são um conjunto de instruções separadas em bloco, que podem ser utilizadas em outras
partes do código. Fazer com que o processador execute as instruções contidas na função é
denominado de “chamar” a função. Uma função pode aceitar uma ou várias entradas e pode
fornecer uma saída, chamada de valor de retorno.
 COMENTÁRIO

As funções de entrada e saída de dados mais usadas em C são printf () e scanf (). Essas funções
estão disponíveis na biblioteca C por padrão. As macros relacionadas são definidas no cabeçalho
“stdio.h”.

FUNÇÃO PRINTF()

Na linguagem de programação C, a função printf() é usada para imprimir caracteres string, float,
inteiro, octal e valores hexadecimais na tela de saída.

Usamos a função printf() com o especificador de formato %d para exibir o valor de uma variável
inteira. Da mesma maneira, usamos:

%c é usado para exibir o caractere.

%f para a variável float.

%s para a variável de string.

%lf para a variável dupla.

%x para a variável hexadecimal.

Para gerar uma nova linha, usamos “\n” na instrução C printf().

FUNÇÃO SCANF()

A função scanf() é usada para ler caracteres, strings e dados numéricos do teclado.

Considere o programa de exemplo a seguir, no qual o usuário insere um caractere. Esse valor é
atribuído à variável “ch” e, em seguida, exibido. Assim como na função printf(), o especificador de
formato % é usado na instrução scanf(). O e comercial (&) é usado antes do nome da variável “ch”
na instrução scanf() para apontar para a variável e fazer a atribuição do valor fornecido pelo
usuário.

#include <stdio.h>

int main()

char ch;

printf("Entre com um caractere \n");

scanf("%c", &ch);

printf("Caractere de entrada %c \n", ch);

As funções printf(), scanf() e suas variações são sofisticadas e, como tal, consomem uma grande
quantidade de espaço de código compilado. Dessa forma, embora existam compiladores para
sistemas embarcados que as integrem, em funções como escrita para porta serial e display, elas
devem ser usadas com cuidado para não consumir todo o espaço de código na memória do
sistema embarcado.

OPERADORES E ESTRUTURAS
CONDICIONAIS
Operações matemáticas e manipulação de bits são realizadas por meio de operadores.

A linguagem C tem os seguintes operadores:

igual (=)

adição (+)

subtração (-)

multiplicação (*)

divisão (/)

bit a bit AND (&)

bit a bit OR (|)

resto da divisão (%)

incremento (++)
decremento (--)

As entradas para uma declaração de operador são variáveis ou constantes, e o resultado é


armazenado em uma variável.

IF E ELSE

As declarações condicionais permitem que você execute ou não uma ação com base no fato de
uma determinada condição ser verdadeira ou falsa. Essas declarações usam as palavras if e else,
por exemplo:

if (count < 0)

count = 0;

else

count ++;

Possíveis comparações de operador usadas na instrução if são:

x == y x igual a y

x != y x não é igual a y

x>y x maior que y

x<y x menor que y

x <= y x menor ou igual que y

x >= y x maior ou igual que y


x && y E lógico

x || y OU lógico

 Quadro elaborado por Marcos Santana Farias.


Atenção! Para visualização completa da tabela utilize a rolagem horizontal

SWITCH-CASE

O switch-case é um comando com possibilidades mais simplificadas que o if-else, permitindo


apenas a comparação de igualdade com variáveis do tipo int, char e long. O switch-case é
vantajoso quando é necessário fazer muitas comparações, pois irá oferecer maior agilidade na
implementação.

Sintaxe:

switch (expressao) {

case constante1:

instrucoes1;

break;

case constante2:

instrucoes2;

break;

...

default:

instrucoes;

Para utilizar o switch-case, basta substituir a palavra expressao no código pelo nome da variável
que terá sua expressão avaliada.

Substituir a palavra constante1 pela constante a ser comparada com o conteúdo da variável em
expressao, e instrucoesX pelas instruções que se pretende executar caso a comparação seja
verdadeira.

A cláusula default funciona como o último else em um conjunto de instruções if, ou seja, se
nenhuma condição anterior for verdadeira, então as instruções em default serão executadas. A
cláusula default é opcional.

A cláusula break é responsável pela parada na execução das instruções, pois, caso não seja
colocada, as validações presentes no switch continuarão a ser executadas, mesmo que um case já
tenha resultado em verdadeiro.

ESTRUTURAS DE REPETIÇÃO (LOOPS)


For loops e while loops fornecem um meio conveniente de executar repetidamente um bloco de
código. Esses tipos de tarefas surgem com muita frequência em aplicações embarcadas.

For loops são mais orientados para situações em que um bloco de código deve ser executado um
número específico de vezes.

While loops são úteis quando o processador deve continuar repetindo o mesmo bloco de código
até que uma condição mude de verdadeiro para falso.

Aqui estão exemplos de ambos os tipos para imprimir os números de 1 a 10.

for(int i=1; i<=10 ; i++){


printf("%d \n", i);

int i = 1;

while(i <= 10){

printf("%d \n", i);

i++;

A LINGUAGEM C NOS SISTEMAS


EMBARCADOS
No vídeo a seguir, abordamos as peculiaridades que uma linguagem de programação deve ter
para que seja utilizada em um sistema embarcado e como a linguagem C atende a essas
particularidades.

VERIFICANDO O APRENDIZADO
1. PARA SISTEMAS EMBARCADOS, A COMPILAÇÃO PODE SER DEFINIDA
COMO O PROCESSO EM QUE O COMPUTADOR USA VÁRIAS
FERRAMENTAS PARA CONVERTER UMA LINGUAGEM DE PROGRAMAÇÃO
DE ALTO NÍVEL EM UMA LINGUAGEM DE MÁQUINA DE MODO QUE O
PROCESSADOR EMBARCADO POSSA ENTENDÊ-LA. RELACIONE OS
NOMES DAS FERRAMENTAS COM A CONVERSÃO QUE ELA REALIZA E
ESCOLHA A OPÇÃO CORRETA.

1-
A - ARQUIVO-FONTE PARA ARQUIVO-OBJETO
COMPILADOR

2- B - ARQUIVO-OBJETO PARA PROGRAMA


LOCALIZADOR RELOCÁVEL

3- C – PROGRAMA RELOCÁVEL PARA PROGRAMA


VINCULADOR EXECUTÁVEL


ATENÇÃO! PARA VISUALIZAÇÃO COMPLETA DA TABELA UTILIZE A
ROLAGEM HORIZONTAL

A) 1-A, 2-B, 3-C

B) 1-B, 2-C, 3-A

C) 1-A, 2-C, 3-B

D) 1-C, 2-B, 3-A

E) 1-B, 2-A, 3-C

2. VOCÊ RECEBEU O CÓDIGO ABAIXO. O QUE DEVE SER ESCRITO EM


XXXXXXXXXXXX E YYYYYYYYYYY, RESPECTIVAMENTE,
CORRESPONDENDO AO QUE O CÓDIGO EXECUTA?

#INCLUDE <STDIO.H>

VOID MAIN()

INT NUM1, NUM2;

PRINTF("ENTRE COM UM NÚMERO INTEIRO: ");

SCANF("%D", &NUM1);

NUM2 = NUM1 % 2;

IF (NUM2 == 0)

PRINTF("%D XXXXXXXXXXXX ", NUM1);

ELSE

PRINTF("%D YYYYYYYYYYY ", NUM1);

A) “é número inteiro”, “é número fracionário”

B) “é número fracionário”, “é número inteiro”

C) “é número par”, “é número ímpar”

D) “é número ímpar”, “é número par”

E) “é número inteiro”, “é número par”

GABARITO

1. Para sistemas embarcados, a compilação pode ser definida como o processo em que o
computador usa várias ferramentas para converter uma linguagem de programação de alto
nível em uma linguagem de máquina de modo que o processador embarcado possa
entendê-la. Relacione os nomes das ferramentas com a conversão que ela realiza e escolha
a opção correta.

1- Compilador A - Arquivo-fonte para arquivo-objeto


2- Localizador B - Arquivo-objeto para programa relocável

3- Vinculador C – Programa relocável para programa executável


Atenção! Para visualização completa da tabela utilize a rolagem horizontal

A alternativa "C " está correta.

O compilador tem a função de traduzir os arquivos-fonte escritos em alguma linguagem de


programação, como C, em um conjunto equivalente de códigos de operação (opcodes) para um
processador específico. Esses opcodes são guardados em um arquivo-objeto. O trabalho do
vinculador é combinar esses arquivos-objeto e, no processo, resolver todos os símbolos não
resolvidos. A saída do vinculador é um novo arquivo-objeto que contém todo o código e dados dos
arquivos-objeto de entrada e está no mesmo formato, chamado de programa relocável. O
localizador usa essas informações para atribuir endereços de memória física a cada uma das
seções de código e dados dentro do programa relocável. Em seguida, ele produz um arquivo de
saída que contém uma imagem de memória binária, o programa executável que pode ser
carregado no processador de destino.

2. Você recebeu o código abaixo. O que deve ser escrito em xxxxxxxxxxxx e yyyyyyyyyyy,
respectivamente, correspondendo ao que o código executa?

#include <stdio.h>

void main()

int num1, num2;

printf("Entre com um número inteiro: ");

scanf("%d", &num1);

num2 = num1 % 2;

if (num2 == 0)

printf("%d xxxxxxxxxxxx ", num1);

else

printf("%d yyyyyyyyyyy ", num1);

A alternativa "C " está correta.

A expressão num2 = num1 % 2 usa o operador % para guardar na variável num2 o resto da divisão
do número fornecido pelo usuário por 2. Então, a instrução if (num2 == 0) testa se esse resultado é
zero. Sendo zero, indica que o número fornecido é par. Do contrário (else), deve ser informado que
o número é ímpar. Portanto, em xxxxxxxxxxxx deve ser usada a informação “é número par”; e em
yyyyyyyyyyy, a informação “é número ímpar”. Como as variáveis num1 e num2 foram declaradas
como inteiras, não há possibilidade de testar se o usuário entrou com um número fracionário.

CONCLUSÃO

CONSIDERAÇÕES FINAIS
Neste conteúdo, vimos como os sistemas embarcados são onipresentes no nosso dia a dia em
aplicações variadas. Avaliamos os fundamentos para o desenvolvimento desses sistemas com a
verificação das bases numéricas usadas em sistemas computacionais e as regras da álgebra
booleana que permitem simplificar circuitos digitais. Analisamos, por fim, os aspectos principais da
linguagem de programação mais utilizada para o desenvolvimento dos sistemas embarcados, a
linguagem C.

AVALIAÇÃO DO TEMA:
REFERÊNCIAS
BOLL, M.; REINHART, J. A História da lógica. Biblioteca Básica da Filosofia. Lisboa: Edições 70,
1992.

BOOLE, G. The Calculus of Logic. The Cambridge and Dublin Mathematical Journal, v. 3, 1848.

BOOLE, G. An Investigation of The Laws of Thought on Which are Founded the Mathematical
Theories of Logic and Probabilities. Londres: Macmillan, 1958.

KERNIGHAN, B. W.; RITCHIE, D.; DENNIS M. The C Programming Language. Prentice Hall
Professional Technical Reference, 1988.

CAPUANO, F. G; IDOETA, I. V. Elementos de eletrônica digital. São Paulo: Érica, 2012.

DENARDIN, G. W.; BARRIQUELLO, C. H. Sistemas operacionais de tempo real e sua


aplicação em sistemas embarcados. São Paulo: Ed. Blucher, 2019.

FLOYD, T. Sistemas Digitais: Fundamentos e Aplicações. Porto Alegre: Bookman, 2007.

HENZINGER, T. A.; SIFAKIS, J. The embedded systems design challenge. In: Formal
Methods, v. 4085, 2006.

OLIVEIRA, A. S. de; ANDRADE, F. S. de. Sistemas Embarcados - Hardware e Firmware na


Prática. São Paulo: Érica, 2010.

EXPLORE+
Para aprimorar os seus conhecimentos no assunto estudado, recomendamos as seguintes leituras:

O artigo referente ao desenvolvimento de sistemas embarcados: Desenvolvimento de


sistemas embarcados usando alto nível de abstração , de Carlos Michel Betemps,
encontrado no site do Programa de Pós-Graduação em Computação da Universidade
Federal de Pelotas.

O artigo sobre o uso de atuadores em robótica e comunicação com PC: Construção de um


protótipo de um braço robótico microcontrolado com interface de comunicação com um
microcomputador , de Leandro Almeida Santos e Enrique Peter Rivas Padilla, encontrado no
site Sistema Olimpo.
A revisão de literatura sobre os requisitos que devem ser considerados durante o
desenvolvimento de sistemas embarcados: Especificação de requisitos para sistemas
embarcados: uma revisão sistemática da literatura, de Henrique Santos da Gama et al .,
publicado na Brazilian Journal of Development, v.7, n.3, 2021.

CONTEUDISTA
Marcos Santana Farias

Você também pode gostar