Você está na página 1de 82

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:
3 2 1 0
10112   =  1  ×  2   +  0  ×  2   +  1  ×  2   +  1  ×  2


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:

3 2 1 0
10112   =  1 × 2   +  0 × 2   +  1 × 2   +  1 × 2   =  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:

2 1 0
3628   =  3 × 8   +  6 × 8   +  2 × 8   =  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.
1 0
Assim, E316   =  E × 16   +  3 × 16   =  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.

A A =  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 A A = 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

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 + B B
Complemento → B B  =  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 modificador Tipo Tamanho em bytes Intervalo

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

long int Inteiro long 4 -2.147.483.648 a 2.147.483.647

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

unsigned long int Inteiro longo sem sinal 4 0 a 4.294.967.295

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

double Ponto flutuante com precisão simples 8 1.7 E-308 a 1.7E+308

long double Ponto flutuante com precisão dupla longo 16 3.4E-4932 a 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- 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) 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