apostila introdução a programação versão 2013

85
INTRODUÇÃO À PROGRAMAÇÃO Ênfase em Projetos de Sistemas Embarcados Prof.: Joel Augusto dos Santos ver.: 2013 CENTRO FEDERAL DE EDUCAÇÃO TECNOLÓGICA DE MINAS GERAIS Coordenação de Eletrônica

Upload: luciano-freitas

Post on 29-Oct-2015

230 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Apostila Introdução a Programação versão 2013

INTRODUÇÃO À PROGRAMAÇÃO

Ênfase em Projetos de Sistemas

Embarcados

Prof.: Joel Augusto dos Santos

ver.: 2013

CENTRO FEDERAL DE EDUCAÇÃO

TECNOLÓGICA DE MINAS GERAIS

Coordenação de Eletrônica

Page 2: Apostila Introdução a Programação versão 2013

2

INTRODUÇÃO À PROGRAMAÇÃO

Ênfase em Projeto de

Sistemas Microcontrolados

Justificativa

A sociedade atual decorrente da evolução tecnológica e seus desdobramentos na produção e na área da informação exige uma reestruturação permanente do processo educativo, pois a velocidade do desenvolvimento científico e tecnológico torna o conhecimento adquirido rapidamente superado, sendo necessário um processo de atualização continuado. O mundo do trabalho exige indivíduos cada vez mais qualificados, dotados de competências relacionadas com a inovação, a criatividade, o trabalho em equipe e a autonomia na tomada de decisões. Cabe à educação profissional o desenvolvimento de competências que proporcionem condições de laboralidade, de forma que o trabalhador possa manter-se em atividade produtiva em contextos socioeconômicos instáveis. Torna-se fundamental a busca por situações de aprendizagem inovadoras, sequências didáticas e projetos que mobilizem menos o processo de memorização e mais o raciocínio, potencializando a interação professor-aluno e aluno-aluno, na busca de formas coletivas de construção do conhecimento. A contextualização dos conteúdos e a interdisciplinaridade promovem um ambiente fértil retirando o aluno da condição de espectador, propiciando aprendizagens mais significativas no âmbito da vida pessoal, social, cultural e produtiva. Esse trabalho busca atingir tais objetivos através do uso da metodologia de projetos aplicativos fomentando a inovação e a pesquisa de forma ordenada e estruturada, promovendo e incentivando a transformação dos conhecimentos adquiridos pelos alunos em ativos permanentes.

Prof. Joel Augusto dos Santos

Page 3: Apostila Introdução a Programação versão 2013

3

"A educação seria muito mais efetiva se seu propósito fosse assegurar que quando eles deixassem a escola, todo menino e menina deveriam saber o quanto eles não sabem, e serem imbuídos com um desejo

vitalício de sabê-lo." Sir William Haley

Conhecimento:

Conhecer os conceitos básicos de algoritmos, programação estruturada e linguagem C padrão ANSI, aplicada a sistemas baseados em microcontroladores.

Habilidades adquiridas:

Transformar a solução de problemas reais em máquina de estados e algoritmos, utilizando conceitos e técnicas aplicadas à programação de sistemas;

Programar os sistemas projetados utilizando linguagem estruturada C padrão ANSI.

Atitudes:

Compreender a importância das técnicas de programação nos atuais sistemas microcontrolados, bem como o uso destas tecnologias com ganho de performance e custo, no projeto de equipamentos embarcados nas diversas áreas de aplicação.

CENTRO FEDERAL DE EDUCAÇÃO TECNOLÓGICA DE MINAS GERAIS

MAIO - 2013

Page 4: Apostila Introdução a Programação versão 2013

4

Índice do conteúdo

Introdução 5

Bit-01- A Lei de Moore está Chegando ao Fim? 9

Capítulo 1 - Representação de Números em Sistemas Computacionais 10

1.1 – Números Naturais 10

1.2 – Números Inteiros 10

1.3 – Números Reais 12

1.4 – Overflow e Underflow 13

1.5 – Ponto Flutuante 14

1.6 – Códigos Binários 17

1.6.1 – Códigos BCD 17

1.6.2 – Código Hexadecimal 18

1.6.3 – Código ASCII 18

Exercícios 01 22

Capítulo2 – Modelagem de Sistemas Computacionais 23

2.1 – Máquina de Estado Finito 23

2.1.1 – Modelo Moore 27

2.2.2 – Modelo Mealy 27

Projeto – Portão de Garagem Automático 29

Exercício 02 31

Bit-02 - Robô Audiobô 32

Capítulo 3 – Lógica de Programação - Algoritmos 33

3.1 – A técnica Top-Down 34

3.2 – Descrição Narrativa 34

3.3 – Fluxogramas 35

Exercício 03 37

Page 5: Apostila Introdução a Programação versão 2013

5

3.4. – Pseudocódigo 38

3.4.1 – Estrutura do Pseudocódigo 39

3.4.2 – Linearização de expressões 40

Exercício 04 44

Bit 03 – Visualg – Exercícios para Lógica de Programação 45

Capítulo 4 – Introdução à Linguagem de Programação C 46

4.1 – Processo de Criação de um Programa 46

4.2 – A Estrutura da Linguagem C 48

4.3 – Variáveis e Tipos de Dados 51

4.4 – Operadores 52

4.4.1 – Operador de Atribuição 52

4.4.2 – Operadores Aritméticos 52

4.4.3 – Operadores de Relação e Lógicos 52

4.4.4 – Incremento e Decremento 53

4.4.5 - Precedência 54

4.5 – Estruturas de Controle de Fluxo 54

4.5.1 – Comando if 54

4.5.2 – comando if-else-if 55

4.5.3 – switch 56

4.5.4 – loop for 57

4.5.5 – while 58

4.5.6 – do while 58

4.5.7 – break 59

Exercício 05 60

4.6 – Matrizes e Vetores 62

4.6.1 – vetores 62

4.6.2 – matrizes 65

Page 6: Apostila Introdução a Programação versão 2013

6

4.7.3 – strings 66

Exercício 06 68

Bit-04 – ANSI e ISO C 69

Capítulo 5 – Desenvolvimento de Projetos com Microcontroladores 70

5.1 – Metodologia de Projeto de Sistemas Embarcados 73

5.2 – Projeto – Pisca Led com MSP430 74

5.2.1 – Escopo do Projeto 74

5.2.2 – Descrição do Hardware 74

5.2.3 – Desenvolvimento do Código Fonte 74

5.3 – Projeto – Sensor de Temperatura com LM35 79

5.3.1 – Escopo do Projeto 79

5.3.2 – Justificativa 79

5.3.3 – Fundamentação Teórica 79

5.3.4 – Código do Programa 82

Page 7: Apostila Introdução a Programação versão 2013

7

Introdução

Em 1958, um jovem engenheiro chamado Jack Kilby foi trabalhar para a empresa Texas Instruments, que já possuía uma grande reputação em inovação. Ele trabalhava com uma técnica de micro módulos (dispositivos empilhados como pratos) e imaginou a possibilidade de, ao invés de empilhar os componentes, fabricá-los no mesmo pedaço de material. O primeiro protótipo era um oscilador de deslocamento de fase, um circuito simples que convertia corrente contínua em corrente alternada. Ao invés de utilizar vários componentes discretos, fabricou então uma tira fina de germânio com quatro terminais de mais o terminal de terra, sendo composto por um transistor, um capacitor e três resistores. Todo o material era unido através de cera como mostra a figura 1 e foi patenteado em 1959.

Figura 1 – Primeiro circuito integrado – Texas Instruments, 1959

Era o início de uma grande evolução tecnológica sem data para terminar. A escala de integração dos circuitos integrados foi alcançando gradativamente níveis cada vez mais elevados, constituindo 4 grupos principais:

SSI (Small Scale Integration) – Integração em pequena escala: São os Circuitos Integrados com menos componentes, e os primeiros da história. Podem dispor de até 30 dispositivos por pastilha (chip).

MSI (Medium Scale Integration) – Integração em média escala: Corresponde aos Circuitos Integrados com várias centenas de componentes, podendo

Page 8: Apostila Introdução a Programação versão 2013

8

possuir de 30 a 1000 dispositivos por pastilha Estes circuitos incluem descodificadores, contadores, etc.

LSI (Large Scale Integration) – Integração em larga escala: Contém milhares de componentes podendo possuir de 1000 até 100 000 dispositivos por pastilha. Estes circuitos normalmente executam funções lógicas complexas, tais como toda a parte aritmética de uma calculadora, um relógio digital, etc.

VLSI (Very Large Scale Integration) – Integração em muito larga escala: É o grupo de Circuitos Integrados com um número de componentes compreendido entre 100 000 e 10 milhões de dispositivos por pastilha. Estes circuitos são utilizados na implementação de dispositivos programáveis como microprocessadores, microcontroladores, processadores digitais de sinais e circuitos de aplicação com hardware reconfigurável ou Dispositivos Lógicos Reprogramáveis (Programmable Logic Device - PLD) que inclui, por exemplo, o FPGA - Field Programmable Gate Array.

Os microcontroladores estão presentes em quase tudo o que envolve a eletrônica nos dias atuais, diminuindo o tamanho, facilitando a manutenção e gerenciando tarefas internas de aparelhos eletroeletrônicos. Um microcontrolador pode efetuar várias funções que necessitariam de um grande número de outros componentes discretos. Assim, conhecer as técnicas de programação e aprender a programar microcontroladores significa “aprender a desenvolver circuitos para suprir exigências de projetos” para as mais diversas aplicações como sistemas de segurança, controle industrial, equipamentos médicos, automação residencial, entretenimento e outros. Por meio da abordagem dos aspectos teóricos e práticos de linguagens de programação, é possível desenvolver projetos e implementar sistemas microcontrolados de pequeno médio e grande porte. O quadro apresentado na figura 2, mostra uma inusitada aplicação de um dispositivo microcontrolado e é prova que o uso desses dispositivos somente é limitado pela criatividade de cada um.

CHUVEIRO COM SHOW DE LUZES

Mais do que apenas inovador e bonitinho, esse chuveiro é realmente útil. As luzes emitidas pelo chuveiro indicam a temperatura da água – para você nunca mais se queimar ou tomar um susto com a água gelada de novo. As luzes vão do verde (quando a temperatura está inferior a 32 graus) ao vermelho intenso (mais de 45 graus). Entre os dois extremos, o chuveiro varia entre azul, laranja, roxo e rosa.

Fonte: http://gerundioinsano.blogspot.com/2011/06/10-chuveiros-

absurdamente-tecnologicos.html

Figura 2 – Exemplo de aplicação de microcontroladores

Page 9: Apostila Introdução a Programação versão 2013

9

Fonte: http://olhardigital.uol.com.br/produtos/digital_news/noticias/a-lei-de-moore-esta-chegando-ao-fim

A Lei de Moore está chegando ao fim? Cientista afirma que, a partir de 2020, o conceito de duplicação do poder dos processadores a cada 18 meses deve acabar

Stephanie Kohn A Lei de Moore é bastante conhecida no mundo da tecnologia. Criada em 1965 pelo então presidente da Intel, Gordon E. Moore, esse conceito sugere que o número de transistores em um processador dobraria a cada 18 a 24 meses ao mesmo custo. O padrão se mantém há anos, mas, segundo o cientista Michio Kaku, autor de diversos livros sobre física e futurologia, não deve se perpetuar por muito tempo. De acordo com o cientista, a famosa lei, que serve de parâmetro não somente para os computadores domésticos, mas para qualquer dispositivo digital, deve acabar em breve. A previsão é que a partir de 2020, a Lei de Moore não seja mais aplicável. Em seu mais recente livro, "A Física do Futuro", Kaku afirma que os transistores serão tão pequenos que entrarão em colisão com as leis físicas. Um bit de informação se resumirá a um átomo, o que irá impor um limite físico ao desenvolvimento dos computadores. Com isso, Kaku acredita que o Vale do Silício, região da Califórnia (Estados Unidos) onde se concentram as maiores empresas de tecnologia, poderá entrar em colapso. O motivo é simples: sem a Lei de Moore, não haverá nada que impulsione o aumento no poder de processamento na computação e, consequentemente, não haverá interesse do consumidor em adquirir novos produtos. Esses argumentos apresentados pelo cientista não são exatamente novos e já foram discutidos até mesmo pelo próprio criador do conceito, em 2005. Outro pesquisador da área de concepção de computadores da IBM, Carl Anderson, também sugeriu que a Lei de Moore teria um breve fim. No entanto, Anderson acredita que o fim da lei deve ocorrer por outros motivos. Ele destaca que os engenheiros, atualmente, desenvolvem sistemas que exigem cada vez menos recursos do processador e que os custos para pesquisas de novos processadores estão cada vez mais altos. De acordo com o pesquisador, três novas tecnologias - mais rápidas, sofisticadas e econômicas - de processadores emergentes também podem significar o término da Lei de Moore. São elas: os chips com conexões ópticas; os processadores 3D (com circuitos tridimensionais empilhados uns em cima dos outros); e os processadores com sistemas aceleradores. O outro lado da moeda Se para alguns a Lei de Moore deve acabar, para outros, como o professor de engenharia da Universidade de Stanford, Jonathan Koomey, o conceito de Gordon poderia ser ampliado. A nova máxima aposta que o consumo de bateria irá diminuir com o tempo, mas a eficiência no desempenho deve continuar crescendo. De acordo com o site Technology Review, a teoria de Koomey se baseia nos aparelhos móveis como tablets e smartphones. Mesmo menores em tamanho, os equipamentos continuam recebendo melhorias em desempenho. O professor acredita que as atualizações não teriam limites e dependeriam, exclusivamente, da inteligência humana. "A ideia é que com uma carga fixa na computação, a quantidade de bateria que você precisa irá diminuir por duas vezes a cada ano e meio", comentou Jonathan Koomey. No fim de 2010, a Intel levantou, por meio de análises e pesquisas, doze assuntos que iriam pautar o mercado de tecnologia no ano que vem. A companhia compartilhou um pouco da opinião de Koomey. "Inovações e técnicas de manufatura continuarão a desafiar os céticos que dizem que a Lei de Moore está morta. Isso significa que nos próximos anos, enquanto bilhões de novos dispositivos adquirem capacidade de computação e conectividade à Internet, eles terão melhor desempenho com mais características embarcadas no silício, ao mesmo tempo em que reduzirão dramaticamente o consumo de energia e ampliarão a duração da bateria", dizia a pesquisa. Em maio deste ano, a Intel anunciou um avanço científico e uma inovação histórica, apresentando transistores chamados Tri-Gate, que serão adotados na tecnologia de produção dos próximos processadores. Para o CEO da companhia, esse marco vai muito além do acompanhamento do ritmo da Lei de Moore."Os benefícios da baixa voltagem e do baixo consumo de energia ampliam em muito o que normalmente vemos com a transição de um processo tecnológico para o próximo", concluiu o CEO.

Page 10: Apostila Introdução a Programação versão 2013

10

Capítulo 1

Representação de Números em Sistemas Computacionai s

Foi a dificuldade de representar um dígito decimal, um número inteiro entre 0 e 9, em componentes elétricos que determinou o uso da base 2 nos primeiros computadores até os dias de hoje. A lógica booleana, baseada na representação binária, foi usada na implementação dos circuitos elétricos a partir do século XX e ainda hoje continua sendo a lógica utilizada nos modernos computadores, tablets, celulares, TV digital e todo tipo de equipamento que a moderna tecnologia nos proporciona.

1.1 - Números Naturais

A forma mais intuitiva de representar números em um sistema computacional seria através da conversão do número decimal para seu correspondente em binário. Como os computadores operam sempre em binário, essa seria a forma mais imediata e eficiente. Quando representamos números desta forma, não temos números negativos. Logo, nenhum número possui sinal algum. Por isso, chamamos tais números de unsigned (sem sinal).

Atualmente, a maioria das máquinas possui representação numérica de 32 bits. Isso significa que seus números são compostos por 32 dígitos. Com uma representação destas, o menor número binário sem sinal que podemos representar é 00000000000000000000000000000000 e o maior é 1111111111111111111111111111111. Convertendo tais valores para decimal, chegamos à conclusão que a maioria dos computadores só lida com números sem sinal cujo valor esteja entre 0 e 4.294.967.295 - que são os equivalentes decimais destes números.

Para descobrir qual é o equivalente decimal de um número binário de 32 bits, usa-se a fórmula abaixo:

N0 * 232 + N1 * 2

31 + N2 * 230 + N3 * 2

29 + (...) + N29 * 23 + N30 * 2

2 + N31 * 21 + N32 * 2

0

onde N0 é o dígito mais significativo e N32 é o bit menos significativo.

1.2 - Números Inteiros

Só que os números podem ser positivos ou negativos. Um aspecto primordial a ser definido seria então como representar o sinal. Nesta representação foi definida a utilização de mais um bit na representação (o bit mais representativo ou significativo), representando o sinal, com a seguinte convenção:

Page 11: Apostila Introdução a Programação versão 2013

11

bit 0 ==> sinal positivo bit 1 ==> sinal negativo A tabela 01 apresenta alguns exemplos de números e sua representação em binário:

Valor decimal Valor binário com 8 bits (7 + bit de sinal)

+9 00001001 (bit inicial 0 significa positivo)

-9 10001001 (bit inicial 1 significa negativo)

+127 01111111 (bit inicial 0 significa positivo)

-127 11111111 (bit inicial 1 significa negativo)

Tabela 01 – representação binária com sinal

Assim, uma representação em binário com n bits teriam disponíveis para a representação do número n-1 bits (o bit mais significativo representa o sinal). Essa representação tem o nome de representação em sinal e magnitude .

sinal magnitude

Figura 3 – representação sinal e magnitude

Entretanto, tal forma de representação já foi abandonada há muito tempo. Um dos principais motivos para o abandono desta representação está no fato de sempre termos que verificar o primeiro bit para descobrir como efetuar uma soma ou subtração entre dois números. Além disso, tal representação tornaria possível um "+0" e um "-0".

A forma de se representar números inteiros em computadores modernos é chamada de Representação em Complemento de 2 . Ela é feita da seguinte forma:

Os 31 bits mais à esquerda representam sempre números positivos. Calculamos o que eles representam com a mesma fórmula vista acima. Entretanto, o primeiro bit representa sempre "0" se o seu valor for "0" ou " − 232 se o seu valor for "1". Assim, a fórmula para se calcular o que representa um número binário inteiro em decimal é:

− N0 * 232 + N1 * 231 + N2 * 230 + N3 * 229 + (...) + N29 * 23 + N30 * 22 + N31 * 21 + N32 * 2

0

onde N0 é o dígito mais significativo e N32 é o bit menos significativo.

A representação em complemento de 2 é boa pelos seguintes motivos:

Page 12: Apostila Introdução a Programação versão 2013

12

� Para somar dois números inteiros, usa-se o mesmo método. Não precisamos verificar o sinal deles. Com isso, podemos criar um circuito digital mais rápido;

� Descobrir o inverso de um número também é simples. Basta invertermos todos os bits e, em seguida, somarmos 1. Sempre funciona;

� O "0" é sempre "0". Não existe uma versão negativa ou positiva deste número.

� Por meio desta notação, números tão pequenos como -4.294.967.296 e tão grandes como 4.294.967.295 podem ser representados.

1.3 - Números Reais

Também é muito útil que computadores possam representar números reais. Vamos estudar agora como eles costumam ser representados em sistemas computacionais.

A forma mais lógica e versátil de representarmos um número real é por meio da notação científica . Um número decimal em notação científica sempre toma a seguinte forma:

N * 10M

onde N é sempre um número real maior ou igual a 1 e menor que 10 que pode ser positivo ou negativo enquanto M é um número inteiro qualquer (que pode ser positivo ou negativo). Por exemplo:

3,15756 * 109 representa aproximadamente quantos segundos existe em um século enquanto

1,00000 * 10 − 9 representa quantos segundos existem em um nanossegundo.

Alternativamente, podemos representar também números em notação científica utilizando uma base binária:

1,00000 * 10 − 1. Lembre-se que esse "10" significa na verdade "2" em representação decimal. Ou seja, o número representado é na verdade 0,5 e não 0,1.

Enfim, quando temos um número em notação científica binária , ele sempre tem a seguinte forma:

S * 1,XXXXX * 10YYYYY , onde "S" representa o sinal (que pode ser positivo ou negativo), "XXXXX" são as partes fracionárias do número e "YYYYYY" representa o expoente.

Então, para representarmos números reais, precisamos representar no espaço de 32 bits os valores do sinal, fração e expoente. Isso é feito da seguinte forma:

S -- E E E E E E E E -- F F F F F F F F F F F F F F F F F F F F F F F

Page 13: Apostila Introdução a Programação versão 2013

13

O Sinal é representado em um único bit (1 para negativo e 0 para positivo), o expoente é representado por 8 bits e a fração é representada por 23 bits. Assim, o exemplo 1,00000 * 10 − 1 (ou 1/2 em decimal) é representado:

0 -- 1 1 1 1 1 1 1 1 -- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Com esta representação, números quase tão pequenos como − 238 ou quase tão grandes como 238 podem ser armazenados.

Entretanto, note que a nossa precisão não é perfeita. Existem muitos números que não podem ser representados desta forma. Por isso, sempre é preciso realizar arredondamentos. E quanto mais operações realizamos, mais erros acabam sendo acumulados. Por essa razão, a maioria dos computadores possui também uma forma mais precisa de representação de números reais. Essa forma normalmente ocupa o dobro do espaço do que costuma ocupar. Uma representação deste tipo ocupa 64 bits. Ela funciona da seguinte forma:

S -- E E E E E E E E E E E -- F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F

Apesar de gastarmos o dobro do espaço de armazenamento desta forma, aumentamos consideravelmente a faixa de valores representados e a precisão com a qual podemos representá-los.

1.4 - Overflow e Underflow

Overflow é o nome do resultado incorreto ao qual chegamos quando tentamos somar números grandes demais e o resultado não pode ser armazenado e nem representado em 32 bits. Ele pode ocorrer quando efetuamos as seguintes operações:

� Somamos dois números positivos � Somamos dois números negativos � Subtraímos um número negativo de um positivo.

É de responsabilidade do hardware sempre verificar se ocorreu um overflow nestes casos. Normalmente, para fazer a verificação basta conferir os sinais dos números. Em caso afirmativo, ele deve ativar um sinal de exceção. O que é feito caso uma exceção seja detectada, depende de cada programa.

Em linguagens de alto nível, o comportamento depende da linguagem usada. C, por exemplo, ignora todos os Overflows. Ao contrário de Fortran que requer que o programa sempre seja avisado.

Page 14: Apostila Introdução a Programação versão 2013

14

Underflow é o que acontece quando lidamos com um número real tão próximo de 0 que o valor do expoente não pode ser corretamente representado. Quando um programa requer uma precisão tão grande assim, recomenda-se o uso de pontos flutuantes de dupla precisão (double) para evitar este inconveniente.

1.5 - Ponto Flutuante

Ponto flutuante (floating point) ou vírgula flutuante é um formato de representação digital de números reais.

O número é dividido numa mantissa (M) e um expoente (E). O valor representado é obtido pelo produto: M · 2E

Desta forma é possível cobrir um largo espectro de números, maximizando o número de bits significativos e consequentemente a precisão da aproximação. Esta forma de representação foi criada por Konrad Zuse ( 1910 - 1995), Cientista e inventor alemão, para os seus computadores Z1 e Z3.

O número de bits alocados para representar a mantissa e o expoente depende da norma utilizada. A maioria dos sistemas que operam com ponto flutuante utilizam representações definidas na norma IEEE 754, publicada em 1985 pelo Institute of Electrical and Electronics Engineers.

A Norma IEEE 754-2008 define os formatos adequados para representar números em ponto flutuante de precisão simples (32 bits) e de precisão dupla (64 bits).

O formato de ponto flutuante de precisão simples (32 bits) consiste num bit de sinal (s), 8 bits de expoente (e) e uma mantissa de 23 bits (m). O bit de sinal (s) é 0 (zero) para números positivos e 1 para números negativos. O campo de expoente (e) corresponde à soma de 127 com o expoente de base 2 do número representado. O campo de mantissa (m) corresponde à parte fracionária da mantissa do número representado. Considera-se a sempre a mantissa normalizada entre 1 e 2. Desta forma a sua parte inteira é sempre apenas um bit igual a 1 (um) que não é necessário representar.

v = S × M × 2E

Onde:

S = 1 − 2 × s

M = 1.m = 1 + m × 2−23

E = e − 127

Por exemplo, a fração decimal:

0,125

é representada por: 1/10 + 2/100 + 5/1000.

Page 15: Apostila Introdução a Programação versão 2013

15

Da mesma forma, a fração binária:

0,001 tem valor: 0/2 + 0/4 + 1/8. Os dois valores são idênticos, sendo o primeiro escrito na base 10 e o segundo na base 2.

Valor S × M × 2E s m e IEEE 754 - Single Precision

1 1 × 1 × 20 0 0x00 127 0 0111 1111 000 0000 0000 0000 0000 0001

-1 -1 × 1 × 20 1 0x00 127 1 0111 1111 000 0000 0000 0000 0000 0001

0,5 1 × 1 × 2−1 0 0x00 126 0 0111 1110 000 0000 0000 0000 0000 0000

-0,5 -1 × 1 × 2−1 1 0x00 126 1 0111 1110 000 0000 0000 0000 0000 0000

0,15625 1 × 1,25 × 2−3 0 0x200000 124 0 0111 1100 010 0000 0000 0000 0000 0000

Tabela2 – Representação IEE 754 padrão simples

Page 16: Apostila Introdução a Programação versão 2013

16

As notações com os bits do campo expoente (e) todos a um ou todos a zero são reservadas para valores especiais. O zero é representado com e=0 e m=0. Outros valores de m com e=0 indicam números não normalizados. Nestes casos considera-se a mantissa entre 0 e 1.

IEEE 754 - Single Precision

Valor

s e m

0 0000 0000 000 0000 0000 0000 0000 0000

+0

Zero

1 0000 0000 000 0000 0000 0000 0000 0000

-0

0 1111 1111 000 0000 0000 0000 0000 0000

+Inf Infinito Positivo

1 1111 1111 000 0000 0000 0000 0000 0000

-Inf Infinito Negativo

0 1111 1111 010 0000 0000 0000 0000 0000

+NaN

Not a Number

1 1111 1111 010 0000 0000 0000 0000 0000

-NaN

Tabela 3 – Representação IEE 754 padrão simples

Muitas frações decimais não podem ser representadas exatamente como frações binárias finitas. Por consequência, diversos números armazenados na máquina em váriáveis do tipo ponto flutuante (float, double, real) são apenas aproximações.

Considere, por exemplo, a fração 1/3. Uma aproximação decimal seria:

0,3

ou, melhor:

0,33

ou, ainda melhor:

0,333

e assim por diante. Não existe uma fração finita capaz de resultar em exatamente 1/3.

Page 17: Apostila Introdução a Programação versão 2013

17

Um outro exemplo interessante é a fração 1/10. Em muitas linguagens de programação, apesar de rotinas de impressão mostrar o valor 0,100000, se exibirmos o número com maior precisão (por exemplo, 20 casas decimais), veremos que o valor real armazenado será algo aproximado de:

0,10000000149001612000 (o valor pode mudar segundo o hardware e a linguagem utilizada).

1.6 - Códigos binários

O sistema binário ou base 2, é um sistema de numeração posicional em que todas as quantidades se representam com base em dois numeros, com o que se dispõe das cifras: zero e um (0 e 1).

Os computadores digitais trabalham internamente com dois níveis de tensão, pelo que o seu sistema de numeração natural é o sistema binário (aceso, apagado). Com efeito, num sistema simples como este é possível simplificar o cálculo, com o auxílio da lógica booleana. Em computação, chama-se um dígito binário (0 ou 1) de bit, que vem do inglês Binary Digit. Um agrupamento de 8 bits corresponde a um byte (Binary Term). Um agrupamento de 4 bits é chamado de nibble.

O sistema binário é base para a Álgebra booleana (de George Boole - matemático inglês), que permite fazer operações lógicas e aritméticas usando-se apenas dois dígitos ou dois estados (sim e não, falso e verdadeiro, tudo ou nada, 1 ou 0, ligado e desligado). Toda eletrônica digital e computação está baseada nesse sistema binário e na lógica de Boole, que permite representar por circuitos eletrônicos digitais (portas lógicas) os números, caracteres, realizar operações lógicas e aritméticas. Os programas de computadores são codificados sob forma binária e armazenados nas mídias (memórias, discos, etc) sob esse formato.

Dado um número N, binário, para expressá-lo em decimal, deve-se escrever cada número que o compõe (bit), multiplicado pela base do sistema (base = 2), elevado à posição que ocupa. Uma posição à esquerda da vírgula representa uma potência positiva e à direita uma potência negativa. A soma de cada multiplicação de cada dígito binário pelo valor das potências resulta no número real representado.

Exemplo:

101,01(2) = 1x22 + 0x21 + 1x20, 0x2-1 + 1x2-2

= 4 + 0 + 1 , 0/21 + 1/22 = 5,25(10)

Alguns códigos porém, são desenvolvidos tendo em vista um objetivo específico como a transmissão de dados entre sistemas, detecção de falhas de transmissão ou representação da informação em uma interface homem/máquina – IHM.

1.6.1 - Código BCD

É um código binário que expressa os números decimais, Decimal Codificado em Binário. Como só existem 10 dígitos no sistema decimal (0 até 9) a tabela verdade

do código BCD vai da linha 0 até a linha 9 somente. Este tipo de código é usado, por exemplo, para mostrar ao ser humano o resultado das operações com números binários feito pelos computadores e circuitos digitais.

Page 18: Apostila Introdução a Programação versão 2013

18

Para representar um número decimal no código BCD cada número decimal

gera 1 número binário de 4 dígitos, como no exemplo abaixo:

N=123 escrito em BCD resulta:

1 2 3

0001 0010 0011

N= 0001 0010 0011

Observe que o código BCD requer mais dígitos binários para representar o

mesmo número decimal que o correspondente código binário.

Por exemplo para representar o número N=12 no código binário N=1100 no

código BCD

N= 0001 0010.

1.6.2 – Código Hexadecimal

O sistema hexadecimal é um sistema de numeração posicional que representa os números em base 16. Representado pelos símbolos: 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F.

Ele é muito utilizado para representar números binários de uma forma mais compacta, pois é muito fácil converter binários pra hexadecimal e vice-versa.

Dois dígitos hexadecimais correspondem exatamente a um byte.Dessa forma, esse sistema é bastante utilizado em aplicações de computadores e microprocessadores (programação, impressão e displays).

Exemplo:

1011 1101

B D

1.6.3 - Código ASCII

Este código é usado para transmitir informações alfanuméricas. A sequência de números binários expressa uma letra, número ou símbolo usado na escrita. Este código é usado na transmissão dos dados entre o teclado e o computador, por exemplo, e também pode ser usado por programas de computação para identificar a tecla que foi pressionada.

O código ASCII é um código de 8 Bits, 7 bits são usados para transmitir a informação e o oitavo bit pode ser usado para informar a paridade ou pode ser levado para o valor zero. Todo caractere tem sua representação em 8 bits, mas um conjunto de 8 bits pode caracterizar também uma instrução. Como ficou estabelecido a representação de um caracter alfa numérico será expresso em 8 bits, ou vários grupos de 8 bits aglutinados. Definiu-se que qualquer conjunto de 8 bits será chamado de byte (BinarY TErm, ou termo binário).

Page 19: Apostila Introdução a Programação versão 2013

19

Ao ser criado o ASCII - American Standard Code for Information Interchange (Código Americano Padrão para Troca de Informações) utilizava apenas 127 códigos diferentes, para representar um conjunto de caracteres de controle para o fluxo de dados, além de caracteres imprimíveis, de uso corrente na língua inglesa (letras maiúsculas e minúsculas de A até Z; os dígitos de 0 a 9, e sinais gráficos de pontuação).

código caracter código caracter código caracter código caracter

000 CTRL-@ 032 (BRANCO) 064 @ 096 `

001 CTRL-A 033 ! 065 A 097 a

002 CTRL-B 034 " 066 B 098 b

003 CTRL-C 035 # 067 C 099 c

004 CTRL-D 036 $ 068 D 100 d

005 CTRL-E 037 % 069 E 101 e

006 CTRL-F 038 & 070 F 102 f

007 CTRL-G 039 ' 071 G 103 g

008 CTRL-H 040 ( 072 H 104 h

009 CTRL-I 041 ) 073 I 105 i

010 CTRL-J 042 * 074 J 106 j

011 CTRL-K 043 + 075 K 107 k

012 CTRL-L 044 , 076 L 108 l

013 CTRL-M 045 - 077 M 109 m

014 CTRL-N 046 . 078 N 110 n

015 CTRL-O 047 / 079 O 111 o

016 CTRL-P 048 0 080 P 112 p

017 CTRL-Q 049 1 081 Q 113 q

018 CTRL-R 050 2 082 R 114 r

019 CTRL-S 051 3 083 S 115 s

020 CTRL-T 052 4 084 T 116 t

021 CTRL-U 053 5 085 U 117 u

022 CTRL-V 054 6 086 V 118 v

023 CTRL-W 055 7 087 W 119 w

024 CTRL-X 056 8 088 X 120 x

025 CTRL-Y 057 9 089 Y 121 y

026 CTRL-Z 058 : 090 Z 122 z

027 CTRL-[ 059 ; 091 [ 123 {

028 CTRL-\ 060 < 092 \ 124 |

029 CTRL-] 061 = 093 ] 125 }

030 CTRL-^ 062 > 094 ^ 126 ~

031 CTRL-_ 063 ? 095 _ 127 DEL

Tabela 4 – Tabela ASCII original

Com o surgimento dos microcomputadores pessoais e sua popularização mundial, ficou patente a necessidade de se representar caracteres acentuados (com diacríticos) em função de aquelas máquinas estarem atingindo mercados não concebidos originalmente, e que se utilizavam de uma gama maior de tipos imprimíveis.

Foi desta forma que a IBM ao lançar o seu PC (Personal Computer) ampliou a tabela ASCII dando a ela a capacidades de 256 caracteres codificados, incluindo então além de diacríticos uma série de caracteres semi-gráficos.

Page 20: Apostila Introdução a Programação versão 2013

20

Tabela 4 - Tabela ASCII estendida de 1981 (hoje CP 437)

Esta ampliação da tabela ASCII, como pode ser observado, contemplava muitos caracteres acentuados, porém ainda não acomodava todas as possibilidades de diacríticos, principalmente para os idiomas de origem latina (p. ex.: ã; õ; Ã; Õ; etc.). Ainda se carecia de alguns caracteres maiúsculos acentuados, sem deixar de lembrar do uso do til nas vogais "a" e "o". Com esta necessidade fervilhando no mercado, a Microsoft implementou o conceito de Páginas de Código, onde haveriam diversas tabelas ASCII estendidas para cada necessidade. Aquela original recebeu a denominação de ASC 437 (Código de Página para US) e aquela que melhor nos serve para os países da América Latina recebeu a denominação ASC 850 (Código de Página Latin I), que é mostrada na tabela a seguir.

Page 21: Apostila Introdução a Programação versão 2013

21

código caracter código caracter código caracter código caracter

128 Ç 160 á 192 + 224 Ó

129 ü 161 í 193 - 225 ß

130 é 162 ó 194 - 226 Ô

131 â 163 ú 195 + 227 Ò

132 ä 164 ñ 196 - 228 õ

133 à 165 Ñ 197 + 229 Õ

134 å 166 ª 198 ã 230 µ

135 ç 167 º 199 Ã 231 þ

136 ê 168 ¿ 200 + 232 Þ

137 ë 169 ® 201 + 233 Ú

138 è 170 ¬ 202 - 234 Û

139 ï 171 ½ 203 - 235 Ù

140 î 172 ¼ 204 ¦ 236 ý

141 ì 173 ¡ 205 - 237 Ý

142 Ä 174 « 206 + 238 ¯

143 Å 175 » 207 ¤ 239 ´

144 É 176 _ 208 ð 240

145 æ 177 _ 209 Ð 241 ±

146 Æ 178 _ 210 Ê 242 _

147 ô 179 ¦ 211 Ë 243 ¾

148 ö 180 ¦ 212 È 244 ¶

149 ò 181 Á 213 i 245 §

150 û 182 Â 214 Í 246 ÷

151 ù 183 À 215 Î 247 ¸

152 ÿ 184 © 216 Ï 248 °

153 Ö 185 ¦ 217 + 249 ¨

154 Ü 186 ¦ 218 + 250 ·

155 ø 187 + 219 _ 251 ¹

156 £ 188 + 220 _ 252 ³

157 Ø 189 ¢ 221 ¦ 253 ²

158 × 190 ¥ 222 Ì 254 _

159 ƒ 191 + 223 _ 255

Tabela 5 - Tabela ASCII estendida CP 850

Page 22: Apostila Introdução a Programação versão 2013

22

EXERCÍCIO-01

1 - Pesquise:

a) limite máximo e mínimo para o expoente em precisão simples.

b) limite máximo e mínimo para o expoente em precisão dupla.

2. Mostre a representação binária do número -0,7510 nas precisões simples e dupla no padrão IEEE 754

3 - Dados os números abaixo, informe quantos bits são necessários para representá-los.

a) 5.467 h) 133.054

b) 67.894 i) 1.048.577

c) 23.546 j) 500.786

d) 18.769 k) 43.629

e) 33.098 l) 3.021.392

f) 21.345 m) 37.639.478

g) 65.535

4 - Para os números a seguir, apresente suas correspondentes representações nos códigos BCD e hexadecimal.

a) 57

b) 2048

c) 72374

d) 9000

Page 23: Apostila Introdução a Programação versão 2013

23

Capítulo 2

Modelagem de Sistemas Computacionais

O rápido crescimento da capacidade computacional das máquinas resultou na demanda por sistemas de software cada vez mais complexos. O surgimento de sistemas de software mais complexos por sua vez, trouxe a necessidade de buscar por novas formas de desenvolver sistemas e consequentemente, as técnicas utilizadas para a construção de sistemas computacionais têm evoluído de forma impressionante, notavelmente no que tange à modelagem de sistemas. Até meados da década de 1990, as três metodologias de modelagem mais populares entre os profissionais da área de engenharia de software eram: o método de Booch, o método OMT (Object Modeling Technique) de Jacobson e o método OOSE (Object-Oriented Software Engineering) de Rumbaugh. A união dessas metodologias resultou na UML - Unified Modeling Language - ou Linguagem de Modelagem Unificada.

É uma linguagem visual utilizada para modelar sistemas computacionais. Deve ficar bem claro, no entanto, que a UML não é uma linguagem de programação, mas uma linguagem de modelagem, cujo objetivo é auxiliar os engenheiros de software a definir as características do software, tais como seus requisitos, seu comportamento, sua estrutura lógica, a dinâmica de seus processos e até mesmo suas necessidades físicas em relação ao equipamento sobre o qual o sistema deverá ser implantado.

Todas essas características são definidas por meio da UML antes de o software começar a ser realmente desenvolvido. Um dos diagramas utilizados pela UML para modelagem do sistema é o Diagrama de Máquina de Estados.

2.1 - Máquina de Estados Finitos

Máquina de Estados Finitos é um modelo de descrição de um processo (de hardware ou software) que parte da seguinte premissa:

Um dispositivo que possui um conjunto finito de estados e aceita um finito número de entradas, pode produzir um finito numero de diferentes saídas. Este dispositivo deve ter uma memória que possa armazenar a sequência de entradas recebidas, de forma que a saída seja dependente destas entradas.

Page 24: Apostila Introdução a Programação versão 2013

24

Máquina de Estados Finitos- Finite State Machines - FSM é, provavelmente, a ferramenta mais utilizada pelos desenvolvedores de jogos e programas de computador em geral para selecionar o comportamento de cada agente dentro do jogo. Um exemplo bem simples de uma FSM é um botão liga/desliga como mostrado na figura 4. Esta forma de representação gráfica é uma das mais utilizadas.

Figura 4 – Diagrama de estados de uma chave liga/desliga

As linhas representam as transições de estado, enquanto os círculos representam o estado. O círculo pintado indica qual é o estado inicial. Já em um jogo normalmente uma FSM não é tão simples assim, visto que geralmente os agentes podem ter um conjunto muito maior de estados. Para aumentar nosso entendimento sobre esta técnica, vamos tomar como exemplo um jogo antigo, mas muito popular. Um clássico dos jogos até hoje, lançado inicialmente no início dos anos 80, o Pac-man cuja tela pode ser vista na figura 5.

Figura 5 - Tela do jogo “Pac-MAN

A mecânica do jogo é simples: o jogador controla uma cabeça redonda (uma pizza faltando uma fatia) com uma boca que se abre e fecha, posicionada em um labirinto repleto de pastilhas e 4 fantasmas que o perseguem. O objetivo é comer todas as pastilhas sem ser alcançado pelos fantasmas.

1 - A transição de estado ocorre sempre que o jogador consegue alguma pílula de energia.

Page 25: Apostila Introdução a Programação versão 2013

25

2 - A implementação da ação caçar de cada fantasma é diferente. Eles possuem 3 comportamentos:

Caçar (Chase)

Fugir (Evade)

Dispersar (Scatter)

3 - Os tempos para que ocorra transição entre os eventos são diferentes, dependendo do comportamento.

Assim, a partir destes dados e definido os tempos, é possível elaborar o diagrama de estado geral de funcionamento conforme mostrado na figura 6.

Figura 6 – FSM do jogo Pac-MAN

Na verdade cada estado, neste caso, pode originar outra máquina de estado mais específica para definir o comportamento do fantasma dentro daquele estado. Vamos pegar como exemplo o comportamento de dispersar.

1 – mover em direção aos cantos;

2 – ficar andando em círculos.

Figura 7 – comportamento de dispersar

Page 26: Apostila Introdução a Programação versão 2013

26

Usa-se então o conceito de Máquina de Estado Finita Hierárquica- HFSM- onde cada estado pode ser uma nova FSM de acordo com a figura 8.

Figura 8 – exemplo de implementação de uma HFSM

A Técnica de Máquina de Estado é aplicada igualmente ao projeto de circuitos lógicos. Nesse caso uma FSM é um modelo de comportamento de um determinado circuito ou processo lógico composto por estados, transições e saídas.

ESTADOS -> comporta-se como uma memória, armazena as informações sobre as saídas em um determinado momento;

TRANSIÇÃO -> É a condição para que ocorra a mudança de estado para outro;

SAÍDA -> Descreve a atividade que deve ser realizada em um determinado estado.

Dois tipos de modelamentos são amplamente utilizados, o modelo Moore e o modelo Mealy.

Page 27: Apostila Introdução a Programação versão 2013

27

2.1.1 - Modelo Moore

Figura 8 – Máquina Moore

• As saídas são uma função do estado atual; • As saídas mudam sincronizadas com as mudanças de estado.

A vantagem do modelo de Moore é a simplificação do comportamento. Consideremos por exemplo uma FSM Moore de uma porta de elevador com 4 estados "Aberta", "Fechada", "Abrindo", "Fechando". A máquina de estados reconhece dois comandos: "comando_abrir" e "comando_fechar" que disparam a alteração de estado. A ação de entrada no estado "Abrindo" liga o motor que abre a porta; a ação de entrada no estado "Fechando" liga o motor na outra direção, fechando a porta. Os estados "Aberto" e "Fechado" não Desempenham nenhuma ação.

2.1.2 - Máquina de Estado modelo Mealy

Figura 9 – Máquina Mealy

Page 28: Apostila Introdução a Programação versão 2013

28

• Mudanças nas entradas podem causar mudanças na saída imediatamente;

• Variáveis de estado (vetor de estado) mantém o estado do circuito Armazenado em registros;

• A Lógica de combinações calcula o próximo estado e saídas; • O próximo estado é uma função do estado atual e entradas;

O uso de uma Máquina de Mealy normalmente leva a uma redução no número de estados. Por exemplo uma FSM Mealy implementando o mesmo comportamento visto no exemplo anterior, existem duas input actions:

1 - “inicie o motor para fechar a porta se o comando_fechar chegar” e

2 - “inicie o motor na direção oposta para abrir a porta se o comando_abrir chegar”.

Outro exemplo simples de uma máquina de estados seria um semáforo (sinal de trânsito) como pode ser visto na figura 10. Cada estado corresponde a uma situação que ocorrerá. Quando verde, os carros podem prosseguir na via. Passado um tempo, é acionada a tarefa de mudar para amarelo. Então o semáforo passa de verde para amarelo. Aqui os carros ficam em estado de atenção e já aguardam a próxima transição.

O próximo passo é passar para vermelho. Nesse estado, os carros estão parados na via. De vermelho, o próximo estado somente será verde, assim, os carros podem voltar a trafegar na via.

Figura 10 – Semáforo simples

Uma sugestão de uma FSM para este caso, pode ser visto na figura 11.

Page 29: Apostila Introdução a Programação versão 2013

29

Vamos, finalmente, desenvolver passo a passo um exemplo através de um projeto aplicativo.

Projeto: Portão de Garagem Automático

Objetivo: Controlar remotamente um portão de garagem através de um controle

remoto que possui um único botão de acionamento. A figura 12 mostra o diagrama geral do sistema.

Figura 12 - Sistema de controle para portão de garagem

Passo 1 – o primeiro passo é construir uma tabela de estados relacionando as variáveis de entrada e as variáveis de saída;

Tabela – 6 – Tabela relacionando entrada/saída

Page 30: Apostila Introdução a Programação versão 2013

30

Passo 2 – Identificar na tabela todos os estados não válidos para simplificação;

Tabela – 7 – Identificação dos estados não válidos

Passo 3 – Identificar as ações correspondentes aos estados válidos.

Tabela – 8 – Identificação das ações válidas

Passo 4 – Identificar a sequencia de todos os estados possíveis.

Tabela – 9 – Identificação da sequência dos estados

Page 31: Apostila Introdução a Programação versão 2013

31

Passo 5 – Construir agora o mapa de estado correspondente.

Figura 13 – Mapa de estados do controle para portão de garagem

EXERCÍCIO-02

1 - Modele o comportamento de um flip-flop tipo D utilizando uma FSM

2 - Modele o comportamento de um flip-flop tipo JK utilizando uma FSM.

3 – considere o diagrama em blocos que representa as conexões entre dois sistemas digitais, possibilitando um correto sincronismo na transferência de dados de 8 bits do sistema “A “ para o sistema “B”.

DATA BUS – formado por oito linhas (conexões), permite que uma informação binária seja transferida do sistema A para o sistema B;

STROBE – sinal de habilitação, gerado pelo sistema A, que “avisa” ao sistema B que uma informação está pronta no DATA BUS para ser capturada e armazenada;

BUSY – sinal gerado pelo sistema B para avisar ao sistema A que o sistema B se encontra “ocupado” e portanto, indisponível para receber informações.

ACKNOWLEDGE – sinal gerado pelo sistema B para avisar ao sistema A que uma informação foi capturada e armazenada.

Construa um mapa de estado para o sistema proposto.

Page 32: Apostila Introdução a Programação versão 2013

32

Fonte: http://www.mecatronicaatual.com.br/secoes/leitura/1152

Em: 26/04/2013

AUTOMAÇÃO / Robótica

Robô Audiobô O robô a ser apresentado neste artigo tem sua montagem tanto eletrônica como mecânica bem simples, sendo recomendado ao nosso leitor iniciante e também ao mais experiente. O robô pode ser aproveitado em feiras e mostras em escolas/faculdades e também para diversão por parte daqueles que desejam apenas uma montagem simples e sem o uso de microcontroladores.

Márcio José Soares

O que o robô é capaz de fazer? Esta deve ser a primeira pergunta do leitor, antes de qualquer montagem, seja ela robótica ou outra. Assim, fica garantido que os objetivos serão alcançados. O Audiobô é um robô capaz de responder ao “bater de palmas” ou a um outro som “curto” qualquer, como o “estalar dos dedos” para seu controle. Ele realiza seus movimentos de acordo com uma seqüência lógica. Veja a figura 1.

A cada “sinal” (som emitido) recebido, o robô modifica seu “estado interno ” e executa um determinado movimento. Assim é possível movimentar o robô à frente, fazê-lo parar, executar um desvio (com o giro do mesmo), pará-lo novamente e depois seguir em frente novamente. O controle deste robô utiliza lógica digital discreta CMOS empregando contadores -máquinas de estado . Sendo assim, este robô torna-se um forte candidato para uma mostra ou feira em escolas visando demonstrar os conceitos aprendidos em disciplinas como “lógica digital” “circuitos lógicos” entre outras do gênero. Para aqueles que desejam apenas uma montagem simples, de um robô capaz de “interagir” com o usuário de uma forma também simples, a montagem é igualmente indicada.

O CIRCUITO O circuito do Audiobô, presente na figura 2 , foi dividido em três partes: 1) Circuito de Clock - Disparo (entrada de som) 2) Contador (flip-flops e portas lógicas adicionais) 3) Controle de potência (motores)

Page 33: Apostila Introdução a Programação versão 2013

33

Capítulo 3

Lógica de Programação - Algoritmos

A automatização de tarefas é um aspecto marcante da sociedade moderna. O aperfeiçoamento tecnológico alcançado, teve como elementos fundamentais a análise e a obtenção de descrições da execução de tarefas em termos de ações simples o suficiente, tal que pudessem ser automatizadas por uma máquina especialmente desenvolvida para este fim, O COMPUTADOR.

A partir daí houve um processo de desenvolvimento simultâneo de máquinas (hardware) e dos elementos que gerenciam a execução automática (software) de uma dada tarefa. E essa descrição da execução de uma tarefa, como considerada acima, é chamada algoritmo.

Um algoritmo é formalmente uma sequência finita de passos que levam a execução de uma tarefa. Podemos pensar em algoritmo como uma receita, uma sequência de instruções que levam a uma meta específica. Estas tarefas não podem ser redundantes nem subjetivas na sua definição, devem ser claras e precisas.

Como exemplos de algoritmos podemos citar os algoritmos das operações básicas (adição, multiplicação, divisão e subtração) de números reais decimais. Outros exemplos seriam os manuais de aparelhos eletrônicos, que explicam passo-a-passo os modos de operação.

Até mesmo as coisas mais simples, podem ser descritas por sequências lógicas. Por exemplo:

“Somar dois números quaisquer”.

• Escreva o primeiro número no QUADRO-1

• Escreva o segundo número no QUADRO-2

• Some o número do QUADRO-1 com número do QUADRO-2 e coloque o resultado no QUADRO-3.

Page 34: Apostila Introdução a Programação versão 2013

34

Os programas de computadores são algoritmos escritos numa linguagem específica de computador (Pascal, C, Cobol, Fortran, Visual Basic entre outras) e que são interpretados e executados por uma máquina programável.

3.1 - A Técnica Top-Down

A técnica denominada top-down consiste em atacar o problema de forma gradual. Após o entendimento completo do problema, basta dividi-lo em partes menores para que os detalhes sejam tratados individualmente e a solução como um todo seja alcançada com a união das resoluções de todas as partes. Escrever algoritmos usando top-down facilita a maneira de encarar os problemas, pois dividir um problema inicialmente complexo em partes de solução trivial, propicia 'insights' mentais que nos revelam o caminho que o algoritmo deve seguir.

A estratégia por trás do método top-down (de cima para baixo) é a descrita abaixo:

• ter uma visão geral do problema; • dividi-lo em partes menores; • resolver essas partes; • refinar as partes se uma solução ainda não foi encontrada; • unir todos os refinamentos.

Um algoritmo pode ser representado de três formas: Descrição Narrativa, Fluxograma e Pseudocódigo.

3.2 - Descrição Narrativa

Faz uso da linguagem natural que utilizamos, com o objetivo de descrever os passos principais da solução para um problema.

Uma receita de bolo, por exemplo, é uma descrição narrativa.

Bolo de cenoura

Ingredientes

3 ovos, 2 xícaras (chá) de açúcar

2 xícaras (chá) de farinha de trigo

1 colher (sopa) de fermento

1 xícara (chá) de óleo de soja

3 cenouras médias e cruas

1 pitada de sal.

Modo de fazer

Bata no liquidificador os ovos, as cenouras (em pedaços), o óleo e o sal. Numa tigela, misture o açúcar, o fermento e a farinha. Despeje a mistura do liquidificador para a tigela e misture bem. Leve para assar em forma untada e polvilhada com farinha.

Page 35: Apostila Introdução a Programação versão 2013

35

A grande desvantagem da descrição narrativa é a imprecisão, uma vez que a especificação pode não ficar clara ou ficar ambígua, ou seja, cada um pode interpretar de uma forma. Por exemplo, em algumas receitas de bolo você pode encontrar a frase “leve ao forno até assar”. Algumas pessoas poderiam saber exatamente quando o bolo está assado, outras pessoas não. A definição “cenoura média” é outro exemplo de imprecisão.

3.3 - Fluxogramas

Tentando eliminar a ambiguidade e procurando fazer uso de uma ferramenta já usada na área de administração,o fluxograma passou a fazer uso do conjunto de símbolos gráficos padronizados para representar algoritmos. Nessa representação formas geométricas diferentes implicam em ações, instruções ou comandos distintos. Isso pode ajudar no entendimento do algoritmo e a eliminando a ambiguidade e tornando o entendimento universal, independente da linguagem. Esta forma é intermediária à descrição narrativa e ao pseudocódigo que será visto posteriormente, pois é mais precisa do que a primeira, porém, não se preocupa ainda com detalhes de implementação do programa e com o ambiente de hardware onde será executado. Os principais símbolos usados são apresentados na tabela 10. Além desses símbolos, linhas e setas indicarão a direção do fluxo de execução do algoritmo. E dentro de cada símbolo, deve ser escrito o que ocorrerá naquela fase.

Início ou final do fluxograma

Operação ou comando

Operação de entrada de dados

Operação de saída de dados

Decisão lógica

Elemento de conexão de fluxo

Tabela 10 – Principais símbolos utilizados no fluxograma

Page 36: Apostila Introdução a Programação versão 2013

36

Exemplo:

Desenvolver um fluxograma capaz de obter as notas de duas avaliações de um aluno e calcular a média aritmética dessas notas. O algoritmo deverá entregar como saída, se o aluno foi aprovado ou reprovado.

A solução está mostrada na figura 13.

Figura 13 – Cálculo da média

Apesar de mais claro para ler, evitando a ambiguidade, o fluxograma a dá pouca atenção aos dados, não oferecendo recursos para descrevê-los ou representá-los. Isso vai fazer diferença na hora de implementar um algoritmo em uma linguagem de programação específica.

Porém, esta característica do fluxograma, o torna uma excelente ferramenta para ser usada na etapa inicial do desenvolvimento. Neste momento, o programador se concentrará apenas na lógica de programação, deixando os detalhes específicos como estrutura dos dados, para a etapa posterior, mas aí então a lógica já estará testada.

Page 37: Apostila Introdução a Programação versão 2013

37

EXERCÍCIO- 03

1 - Em uma escola, a média final é dada pela média aritmética de três notas. E a mesma tem o seguinte esquema de avaliação:

MÉDIA SITUAÇÃO DO ALUNO 0 – 4,9 RECUPERAÇÃO 5 – 6,9 PROVA FINAL 7 - 10 PASSOU POR MÉDIA

Desenvolva um algoritmo que a partir da entrada das três notas mostre a situação do aluno. No caso do aluno em recuperação e prova final, mostre também quanto o aluno irá precisar para passar. No caso da recuperação a nota necessária para passar é dada por:

10 – Média + 2

e na prova final é dado por:

10 – Média.

2 - Desenvolva um algoritmo capaz e encontrar o menor dentre 3 números inteiros quaisquer dados por um operador através de um teclado.

Dica: Para obter os números, faça uso do comando “leia”.

3 - Elabore um algoritmo que leia as variáveis C e N respectivamente código e número de horas trabalhadas de um operário. E calcule o salário sabendo-se que ele ganha R$ 10,00 por hora. Quando o número de horas exceder a 50 calcule o excesso e pagamento armazenando-o na variável E, caso contrário zerar tal variável. A hora excedente de trabalho vale R$ 20,00. No final do processamento imprimir o salário total e o salário excedente

4 - A secretária de Meio Ambiente que controla o índice de poluição mantém 3 grupos que são altamente poluentes do meio ambiente. O índice de poluição aceitável varia de 0,05 até 0,25. Se o índice sobe para 0,3 as indústrias do 1º grupo são intimadas a suspenderem suas atividades, se o índice crescer para 0,4 as indústrias do 1º e 2º grupo são intimadas a suspenderem suas atividades, se o índice atingir 0,5 todos os grupos devem ser notificados a paralisarem suas atividades. Faça um algoritmo que leia o índice de poluição medido e emita a notificação adequada aos diferentes grupos de empresas.

Page 38: Apostila Introdução a Programação versão 2013

38

3.4 Pseudocódigo

Esse modelo de descrição de algoritmos surgiu para tentar suprir as deficiências das outras representações. Consiste na definição de uma pseudolinguagem de programação, cujos comandos são em formato textual, mas já lembram um pouco a estrutura de uma linguagem de programação estruturada, ou seja, a pseudolinguagem se assemelha muito ao modo como os programas são escritos. Isso vai permitir que os algoritmos nela representados possam ser traduzidos, quase que diretamente, para uma linguagem de programação. Nele os verbos (ações) disponíveis para utilização são limitados e empregados no imperativo. Deve-se evitar as expressões excessivamente longas, estas restrições visam eliminar a possibilidade de ambiguidade. A técnica é baseada em uma PDL (Program Design Language), que é uma linguagem genérica na qual é possível representar um algoritmo de forma semelhante à das linguagens de programação, portanto vamos ver como fica o exemplo de Calcular média dos alunos representado anteriormente, agora em pseudocódigo.

algoritmo “calcularMedia”

var N1, N2, Media : real

inicio

leia (N1, N2)

Media <- (N1 + N2)/2

se media>=6 entao

escreva (“aprovado”)

senao

escreva (“reprovado”)

fimse

fimalgoritmo

Observe bem as palavras em negrito. São palavras reservadas da linguagem ou seja, só podem ser utilizadas para as funções específicas que foram criadas. Essa característica já é parte do conceito de “estrutura”. Passa a ser obrigatório o uso de padrões e expressões pré-definidas na escrita do algoritmo. Tudo isso objetivando sempre que não haverá ambiguidades ou situações indefinidas.

Page 39: Apostila Introdução a Programação versão 2013

39

3.4.1 - Estrutura do pseudocódigo

A estrutura de um algoritmo em pseudocódigo pode variar um pouco de acordo com o autor ou com base na linguagem de programação que será utilizada posteriormente, mas essas variações ocorrem apenas na sintaxe, pois a semântica deve ser exatamente a mesma. A estrutura que empregaremos para a construção de nossos pseudocódigos será baseada no programa Visualg 2.0.

O Visualg (Visualizador de Algoritmo) é um programa que edita, interpreta e executa algoritmos com uma linguagem próxima do português estruturado como um programa normal de computador. Foi criado pelo professor Cláudio Morgado de Souza, programador/analista e professor universitário no Rio de Janeiro.

Algoritmo <nome do algoritmo>

var

< declaração de variáveis>

inicio

< lista de comandos>

fimalgoritmo

onde as palavras algoritmo e fimalgoritmo fazem parte da sintaxe da linguagem e sempre delimitam o inicio e fim de um algoritmo; a < declaração de variáveis> é a seção ou parte do algoritmo onde descrevemos os tipos de dados que serão usados na lista de comandos.

Uma variável var pode ser vista como uma caixa com um rótulo ou nome colado a ela, que num dado instante guarda um determinado valor. O conteúdo desta caixa não é algo fixo, permanente. Na verdade, essa caixa pode ter seu conteúdo alterado diversas vezes. Contudo, o conteúdo deve ser sempre do mesmo tipo (real, inteiro, caracter).

inicio indica o fim das declarações e o início da seção de comandos; < lista de comandos > é apenas uma indicação de que entre as palavras inicio e fimalgoritmo podemos escrever uma lista com uma ou mais instruções ou comandos.

É importante salientar que, quando um algoritmo é “executado”, as instruções ou comandos de um algoritmo são sempre executados na ordem em que aparecem no mesmo.

Page 40: Apostila Introdução a Programação versão 2013

40

3.4.2 - Linearização de expressões e operadores

Para a construção de algoritmos que realizam cálculos matemáticos, todas as expressões aritméticas devem ser linearizadas, ou seja, colocadas em linhas, devendo também ser feito o mapeamento dos operadores da aritmética tradicional para os do “Português Estruturado” usados no pseudocódigo. A tabela 11 mostra um exemplo de linearização.

Tabela 11 – Exemplo de expressão linearizada

As tabelas 12 e 13 seguintes mostram os operadores aritméticos usados e também os operadores lógicos relacionais.

Tabela 12 – operadores aritméticos

Tabela 13 – operadores relacionais

Page 41: Apostila Introdução a Programação versão 2013

41

Os operadores relacionais realizam a comparação entre dois operandos ou duas expressões e resultam em valores lógicos (VERDADEIRO ou FALSO).

Em expressões computacionais utilizamos somente parênteses "()" para escrever expressões. Na sintaxe do pseudocódigo podemos ter parênteses dentro de parênteses, como seriam os colchetes e as chaves na matemática. Os parênteses indicam quais sub expressões, dentro de uma expressão, serão executados primeiro. A princípio, a execução é da esquerda para direita, mas além dos parênteses, existem prioridades entre os operadores envolvidos na expressão. Tais prioridades são mostradas na tabela 14 .

Tabela 14 – Prioridade de execução das operações

Vamos seguir passo a passo a resolução de uma simples proposta a partir da representação pseudocódigo.

Proposta: Faça um programa que leia dois valores numéricos, calcule e escreva a sua média aritmética.

Etapa 1

A média aritmética de dois valores é calculada como (a+b)/2, e sendo assim a primeira etapa já está pronta.

Etapa 2

Os dados necessários serão os dois valores, que colocaremos em duas variáveis A e B, do tipo numérico, e uma terceira variável, que chamaremos Média, que armazenará a média aritmética calculada.

Etapa 3

A obtenção dos dados neste programa é simples e direta. Basta pedir ao usuário que digite os valores.

Page 42: Apostila Introdução a Programação versão 2013

42

Etapa 4

O processamento aqui é o cálculo da média, usando o método citado acima, na etapa 1. O resultado do cálculo será armazenado na variável Média.

Etapa 5

Basta exibir o conteúdo da variável Média.

Solução apresentada para a proposta:

Algoritmo "Cálculo de Média Aritmética"

VAR

A,B,Media : REAL

Inicio

Escreva ("Programa que calcula a média aritmética de dois valores.")

Escreva ("Digite um valor :")

Leia (A)

Escreva ("Digite outro valor :")

Leia (B)

Media <- (A+B)/2

Escreva ("A média dos dois valores é : ", Media)

FimAlgoritmo

Observe que foi colocado na tela instruções para o usuário usando o comando Escreva. Esta é uma boa técnica de programação, ou seja, a interatividade com o operador. Da mesma forma, ao imprimir o resultado, não foi simplesmente escrito a média, mas foi gerado uma mensagem ao usuário identificando o que aquele valor significa. Todo programa possui uma estrutura sequencial determinada por um INÍCIO e FIM. Em um algoritmo, estes limites são definidos com as palavras Algoritmo e FimAlgoritmo .

Page 43: Apostila Introdução a Programação versão 2013

43

Vejamos outro exemplo:

Escrever um programa que calcule a área do triângulo.

algoritmo “area_triangulo”

var

base, altura, area: real

inicio

escreval(“Digite o valor da base:”)

leia(base)

escreva(“Digite o valor da altura”)

leia(altura)

area<-(base*altura)/2

escreva(“A area do triangulo é”, area)

fimalgoritmo

Page 44: Apostila Introdução a Programação versão 2013

44

EXERCÍCIO- 04

1 - Escreva um algoritmo que lê o valor do raio e calcule a área do círculo Correspondente. (não precisa declarar o pi, pois já é uma função definida pelo programa Visualg).

2 - Leia uma temperatura dada na escala Celsius (C) e imprima o equivalente em Fahrenheit (F). (Fórmula de conversão: F = 9/5 * C + 32)

3 - O custo ao consumidor de um carro novo é a soma do custo de fábrica com a porcentagem do distribuidor e dos impostos, ambos aplicados ao custo de fábrica.Supondo que a porcentagem do distribuidor seja de 12% e a dos impostos de 45%, prepare um algoritmo para ler o custo de fábrica do carro e imprimir o custo ao consumidor.

4 - O cardápio de uma lanchonete é dado abaixo. Prepare um algoritmo que leia a quantidade de cada item que o cliente consumiu e calcule a conta final.

Hambúrguer................. R$ 4,00

Cheeseburger.............. R$ 6,50

Fritas............................ R$ 3,00

Refrigerante................. R$ 3,50

Milkshake..................... R$ 6,20

5 - Uma companhia paga a seus empregados um salário de R$ 1.500,00 por mês mais uma comissão de R$ 50,00 para cada item vendido e mais 5% do valor da venda. Elabore um algoritmo para calcular e imprimir o salário do vendedor num dado mês.

6 - Cada item desta proposta deverá ser realizado pelo programa a partir da escolha do operador.Solicite o mínimo de dados possível ao usuário.

i. Calcular área e perímetro de um quadrado de lado l

ii. Calcular área e perímetro do circulo de raio r

iii. Calcular área e perímetro do retângulo de comprimento c e largura l

iv. Calcular área e volume do cubo de lado l

v. Calcular área e volume de um cone de raio r e altura h

Page 45: Apostila Introdução a Programação versão 2013

45

Fonte: http://www.tinotec.com.br/blog/visualg-e-exercicios-para-logica-de-programacao-e-algoritmos/

Em: 01/05/2013

Visualg - exercícios para Lógica de Programação e Algoritmos

Publicado em: 21/04/2011 · Por: Laurentino Mello

Todos grandes programadores começaram do zero. Isso é fato! A Lógica de programação e os algoritmos fazem parte da vidas desses profissionais que cada vezdesenvolvem soluções mais úteis para nossas vidas. Um dos programas mais utilizados para exercitar essa matéria é o Visualg , que oferece uma linguagem de fácilcompreensão. É muito comum que professores de cursos técnicos ou superiores realizem suas aulas através deste compilador. Abaixo, temos a descrição atribuída pelo site Baixaki ao Visualg 2.5 Portátil ..

O Visualg é um programa que interpreta e executa algoritmos como um “programa” normal de computador.

Baseado em uma linguagem parecida com o “Portugol” ensinado em cursos em todo o Brasil, possui recursos

como simulação da “tela” do computador, visualização de variáveis, “breakpoints”, ajuda on-line, impressão

dos fontes e outras características que auxiliam o aprendizado das técnicas de programação.

Para facilitar a vida de quem quer utilizar este aplicativo, abaixo segue o link do Visualg. Assim você

pode executá-lo de qualquer mídia removível ou computador. O trabalho fica bem mais prático e

cômodo. DOWNLOAD

� http://ultradownloads.com.br/download/Visualg/

Tela do Visualg2.0

Page 46: Apostila Introdução a Programação versão 2013

46

Capítulo 4

Introdução à Linguagem de Programação C

C é uma linguagem de programação que foi projetada por Dennis Ritchie (1972) e continua sendo das mais utilizadas até hoje. Além disso, Ritchie também foi um dos criadores do sistema operacional Unix, que deu origem ao Linux e o Mac OS X e o moderníssimo Android. Aliás, o próprio Unix foi escrito em C. É uma linguagem de propósito geral, sendo adequada à programação estruturada. No entanto é mais utilizada para escrever compiladores, analisadores léxicos, bancos de dados, editores de texto, e atualmente, na elaboração de programas para serem embarcados em microcontroladores, que será o foco da nossa aprendizagem. A linguagem C pertence a uma família de linguagens cujas características são: portabilidade, modularidade, compilação separada, recursos de baixo nível, geração de código eficiente, confiabilidade, regularidade, simplicidade e facilidade de uso.

4.1 - Processo de criação de um programa

A geração do programa executável a partir do programa fonte obedece a uma sequência de operações antes de tornar-se um executável. Depois de escrever o módulo fonte em um editor de textos, o programador aciona o compilador.

Essa ação desencadeia uma sequência de etapas, cada qual traduzindo a codificação do usuário para uma forma de linguagem de nível inferior – linguagem de máquina - que termina com a criação do código executável,criado pelo lincador, como visualizado na figura 14.

Figura 14 – Processo de criação de um programa em C

Page 47: Apostila Introdução a Programação versão 2013

47

Existem no mercado de software, várias empresas que fornecem um ambiente integrado de desenvolvimento – IDE (do inglês Integrated Development Environment) que reúne características e ferramentas de apoio ao desenvolvimento de software com o objetivo de agilizar este processo.

Geralmente os IDEs facilitam a técnica de RAD (de Rapid Application Development, ou "Desenvolvimento Rápido de Aplicativos"), que visa a maior produtividade dos desenvolvedores.

As características e ferramentas mais comuns encontradas nos IDEs são:

Editor - edita o código-fonte do programa escrito na linguagem suportada pela IDE;

Compilador (compiler) - compila o código-fonte do programa, editado em uma linguagem específica e a transforma em linguagem de máquina;

Linker - interliga os vários "pedaços" de código-fonte, compilados em linguagem de máquina, em um programa executável que pode ser executado em um computador ou outro dispositivo computacional como um microcontrolador ou DSP’s.

Depurador (debugger) - auxilia no processo de encontrar e corrigir defeitos no código-fonte do programa, na tentativa de aprimorar a qualidade do software;

Modelagem (modeling) - criação do modelo de classes, objetos, interfaces, associações e interações dos artefatos envolvidos no software com o objetivo de solucionar as necessidades-alvo do software final.

Geração de código - característica mais explorada em Ferramentas CASE, a geração de código também é encontrada em IDEs, contudo com um escopo mais direcionado a templates de código comumente utilizados para solucionar problemas rotineiros. Todavia, em conjunto com ferramentas de modelagem, a geração pode gerar todo ou praticamente todo o código-fonte do programa com base no modelo proposto, tornando muito mais rápido o processo de desenvolvimento e distribuição do software;

Distribuição (deploy) - auxilia no processo de criação do instalador do software, ou outra forma de distribuição, seja discos ou via internet.

Testes Automatizados (automated tests) - realiza testes no software de forma automatizada, com base em scripts ou programas de testes previamente especificados, gerando um relatório, assim auxiliando na análise do impacto das alterações no código-fonte. Ferramentas deste tipo mais comuns no mercado são chamadas robôs de testes.

Refatoração (refactoring) - consiste na melhoria constante do código-fonte do software, seja na construção de código mais otimizado, mais limpo e/ou com melhor entendimento pelos envolvidos no desenvolvimento do software. A

Page 48: Apostila Introdução a Programação versão 2013

48

refatoração, em conjunto com os testes automatizados, é uma poderosa ferramenta no processo de erradicação de "bugs", tendo em vista que os testes "garantem" o mesmo comportamento externo do software ou da característica sendo reconstruída. A tabela 15 mostra alguns exemplos de IDE’s para programação C/C++ mais utilizadas.

IAR Embedded Workbench Gera códigos em C e Assembly para programação de microcontroladores

DEV-C++, Code::Blocks, Turbo C Geram código para C e C++

Tabela 15 – Ambientes Integrados de Desenvolvimento – IDE”s

4.2 - A estrutura da linguagem C

Na linguagem C, todo programa é basicamente um conjunto de funções. Uma função tem um nome e argumentos associados a ela e é composta por declarações de variáveis e blocos de comandos incluindo, possivelmente, chamadas a outras funções. Um bloco de comandos composto por mais de um comando deve ser delimitado por um par de chaves.

Em um programa C, se um nome não foi previamente declarado e ocorre em uma expressão sendo seguido por um parêntese esquerdo, ele é declarado pelo contexto como sendo o nome de uma função. A função de nome especial main (principal) contém os pontos de início e término da execução de um programa em C. Neste caso, todo programa em C deve ter pelo menos a função main . Veja este primeiro exemplo:

int main(); O nome da funcao é main { Printf(“primeiro programa\n”); /* escrever a string na tela */

}

Esse código em C define uma função denominada main com uma lista de argumentos vazia (nenhuma variável entre os parênteses que a seguem).

Todo programa C inicia sua execução chamando a função main(), sendo obrigatória a sua declaração no programa principal. Comentários no programa são colocados entre /* e */ não sendo considerados na compilação.

Page 49: Apostila Introdução a Programação versão 2013

49

Cada instrução encerra com ; (ponto e vírgula) que faz parte do comando.

Existem funções básicas de entrada/saída (I/O) que já estão definidas na biblioteca C. As funções printf() e scanf() por exemplo, permitem respectivamente escrever na tela e ler os dados a partir do teclado. O programador também pode criar novas funções em seus programas, como rotinas para cálculos, impressão, etc. Neste primeiro exemplo, a chamada da função printf() com o argumento “primeiro programa\n”, imprime na tela (terminal) ou outro destino se for especificado, a cadeia de caracteres que compõem seu argumento. Uma sequência de qualquer número de caracteres entre aspas é chamada cadeia de caracteres ou simplesmente “string”. O argumento \n é a diretiva para “nova linha” ou seja, provoca o avanço do cursor para o início da próxima linha, pois apenas a função printf não força uma nova linha. Além do argumento |n, existem outros pré definidos que permitem formatar a saída de de dados de diversas formas, afim de atender a diversas necessidades de programação, como pode ser visto na tabela 16.

\n nova linha %c caractere simples \t tab %d decimal \b retrocesso %e notação científica \" aspas %f ponto flutuante \\ barra %o octal \f salta formulário %s cadeia de caracteres \0 nulo %u decimal sem sinal

%x hexadecimal

Tabela 16 – argumentos que podem ser associados à função printf

Exemplo de aplicação:

main() { printf("Este é o numero dois: %d",2); printf("%s está a %d milhões de milhas\ndo sol","Vê nus",67);

}

Quanto a função scanf() também é uma função básica já implementada em todos compiladores C. Ela é o complemento de printf() e nos permite ler dados formatados da entrada padrão (teclado). Sua sintaxe é similar a printf():

scanf("expressão de controle", argumentos);

A lista de argumentos deve consistir nos endereços das variáveis. C oferece um operador para tipos básicos chamado operador de endereço e é referenciado pelo símbolo "&" que retorna o endereço do operando. A memória do computador é dividida em bytes que são numerados de 0 até o limite da memória disponível. Estas posições são chamadas de endereços. Toda

Page 50: Apostila Introdução a Programação versão 2013

50

variável ocupa uma certa localização na memória, e seu endereço é o primeiro byte ocupado por ela. Veja o seguinte exemplo:

main() { int num; printf("Digite um número: "); scanf("%d",&num); printf("\no número é %d",num); printf("\no endereço e %u",&num);

}

Duas outras funções são também interessantes para manipular caracteres em operações de entrada/saída (I/O). São as funções getchar() e putchar(). A função getchar() é a função original de entrada de caractere dos sistemas baseados em UNIX.getchar() armazena a entrada até que ENTER seja pressionada.

Exemplo:

main()

{

char ch;

ch=getchar();

printf("%c\n,ch);

}

Já a função putchar() escreve na tela o argumento de seu caractere na posição corrente.

Exemplo:

main()

{

char ch;

printf("digite uma letra minúscula : ");

ch=getchar();

putchar(toupper(ch));

putchar('\n');

}

Page 51: Apostila Introdução a Programação versão 2013

51

4.3 - Variáveis e tipos de dados

Uma variável é um nome simbólico dado a uma região da memória que armazena um valor a ser utilizado por uma função. Palavras reservadas da linguagem C (como int, for e if) não podem ser utilizadas como nomes de variáveis. O nome de uma variável pode conter letras e números, mas deve começar com uma letra. Observe que a linguagem C faz distinção entre caracteres maiúsculos e minúsculos. Toda variável que for utilizada em uma função em C deve ser previamente declarada, ou seja, associada a um dos tipos de dados disponíveis. C apresenta dois tipos de dados principais: inteiro e caractere, denotados por int e char respectivamente. Os números inteiros podem ser, portanto, criados através da declaração int e eles são manipuláveis através de operações como + (adição), − (subtração), * (multiplicação) e / (divisão). A remoção é feita automaticamente. Observe que a divisão entre inteiros produz resposta inteira, com a parte fracionária truncada. Os tipos de dados ponto flutuante, denotado por float, e ponto flutuante de precisão dupla, denotado por double, são também oferecidos em C. Como a linguagem C não suporta o tipo de dado booleano, os valores booleanos são representados pelo tipo de dados inteiro, com o <0> denotando <FALSO> e valores diferentes de <0> denotando <VERDADEIRO>. O tipo de dados inteiro pode ser ainda qualificado com short, long ou unsigned para determinar o domínio de valores representáveis. O domínio efetivo para cada qualificador é dependente da máquina. Os qualificadores register, static e extern são utilizados para definir a classe de armazenamento das variáveis. O qualificador register orienta o compilador a armazenar as variáveis preferencialmente em registradores da UCP (pequena área de memória interna ao processador) e o qualificador static indica que as variáveis devem ter seus endereços fixos. O qualificador extern, por sua vez, mostra que as variáveis devem ser definidas em algum outro lugar. Os tipos de dados não acompanhados por nenhum qualificador explícito são considerados automáticos. Este exemplo apresenta algumas declarações de variáveis em C:

int i; /* variavel do tipo inteiro */

short int z1, z2; /* variavel do tipo inteiro, pore m com metade de numero de palavras para representacao */

char c; /* variavel do tipo caractere */

unsigned short int j; /* variavel do tipo inteiro, curto e sem o sinal*/

long m; /* variavel do tipo inteiro, porem com o do bro de numero de palavras para representacao */

register char s; /* variavel do tipo caractere que deve ser colocado preferencialmente num registrador */

float x; /* variavel do tipo ponto flutuante com pr ecisao simples */

double x; /* variavel do tipo ponto flutuante com p recisao dupla */

Page 52: Apostila Introdução a Programação versão 2013

52

Além das representações apresentadas, a linguagem C suporta também a representação exadecimal que será bastante utilizada em aplicações para microcontroladores. Qualquer sequência de algarismos entre 0 e F que inicie com o prefixo 0x, será aceita.

4.4 - Operadores

4.4.1 - Operador de atribuição

O operador de atribuição em C é o sinal de igual "=". Ao contrário de outras linguagens, o operador de atribuição pode ser utilizado em expressões que também envolvem outros operadores.

4.4.2 - Aritméticos

Os operadores *, /, + e - funcionam como na maioria das linguagens, o operador % indica o resto de uma divisão inteira.

i+=2; -> i=i+2;

x*=y+1; -> x=x*(y+1);

d-=3; -> d=d-3;

Ex:

main()

{i

nt x,y; x=10; y=3;

printf("%d\n",x/y);

printf("%d\n",x%y);

}

4.4.3 - Operadores de relação e lógicos

Relação refere-se as relações que os valores podem ter um com o outro e lógico se refere às maneiras como essas relações podem ser conectadas.

Verdadeiro é qualquer valor que não seja 0, enquanto que 0 é falso. As expressões que usam operadores de relação e lógicos retornarão 0 para falso

Page 53: Apostila Introdução a Programação versão 2013

53

e 1 para verdadeiro. Tanto os operadores de relação como os lógicos tem a precedência menor que os operadores aritméticos. As operações de avaliação produzem um resultado 0 ou 1.

Relacionais Lógicos > maior que && and >= maior ou igual || or < menor ! not <= menor ou igual == igual != diferente

Tabela 17 – operadores relacionais e lógicos

Exemplo: main() { int i,j; printf("digite dois números: "); scanf("%d%d",&i,&j); printf("%d == %d é %d\n",i,j,i==j); printf("%d != %d é %d\n",i,j,i!=j); printf("%d <= %d é %d\n",i,j,i<=j); printf("%d >= %d é %d\n",i,j,i>=j); printf("%d < %d é %d\n",i,j,i< j); printf("%d > %d é %d\n",i,j,i> j);

}

Veja um exemplo de aplicaçõa: main() { int x=2,y=3,produto; if ((produto=x*y)>0) printf("é maior");

}

4.4.4 - Incremento e decremento O C fornece operadores diferentes para incrementar variáveis. O operador soma 1 ao seu operando, e o decremento subtrai 1. O aspecto não usual desta notação é que podem ser usado como operadores pré-fixo(++x) ou pós-fixo(x++). ++x incrementa x antes de utilizar o seu valor. x++ incrementa x depois de ser utilizado.

Page 54: Apostila Introdução a Programação versão 2013

54

Exemplo: main() { int x=0; printf("x= %d\n",x++); printf("x= %d\n",x); printf("x= %d\n",++x); printf("x= %d\n",x); }

4.4.5- Precedência

O nível de precedência dos operadores é avaliado da esquerda para a direita. Os parênteses podem ser utilizados para alterar a ordem da avaliação. ++ -- mais alta * / %

+ - mais baixa

4.5 - Estruturas de Controle de Fluxo Os comandos de controle de fluxo são a essência de qualquer linguagem, porque governam o fluxo da execução do programa. São poderosos e ajudam a explicar a popularidade da linguagem. Podemos dividir em três categorias. A primeira consiste em instruções condicionais if e switch . A segunda são os comandos de controle de loop o while , for e o do-while . A terceira contém instruções de desvio incondicional goto , quase não mais utilizada por programadores. 4.5.1 – Comando If sintaxe: if (condição) comando; else comando; Se a condição avaliar em verdadeiro (qualquer coisa menos 0), o computador executará o comando ou o bloco, de outro modo, se a cláusula else existir, o computador executará o comando ou o bloco que é seu objetivo.

Page 55: Apostila Introdução a Programação versão 2013

55

Exemplo: main() {i nt a,b; printf("digite dois números:"); scanf("%d%d",&a,&b); if (b) printf("%d\n",a/b); else printf("divisão por zero\n"); }

Observe outro exemplo: #include <stdlib.h> #include <time.h> main(){ int num,segredo; srand(time(NULL)); segredo=rand()/100; printf("Qual e o numero: "); scanf("%d",&num); if (segredo==num) {printf("Acertou!"); printf("\nO numero e %d\n",segredo);} else if (segredo<num) printf("Errado, muito alto!\n"); else printf("Errado, muito baixo!\n");}

4.5.2 - If-else-if Uma variável é testada sucessivamente contra uma lista de variáveis inteiras ou de caracteres. Depois de encontrar uma coincidência, o comando ou o bloco de comandos é executado. Exemplo: #include <stdlib.h> #include <time.h> main() { int num,segredo; srand(time(NULL)); segredo=rand()/100; printf("Qual e o numero: "); scanf("%d",&num); if (segredo==num) {printf("Acertou!");tg printf("\nO numero e %d\n",segredo);} else if (segredo<num) printf("Errado, muito alto!\n"); else printf("Errado, muito baixo!\n"); }

Page 56: Apostila Introdução a Programação versão 2013

56

4.5.3 - Switch sintaxe: switch(variável) { case constante1: seqüência de comandos break; case constante2: seqüência de comandos break; default: seqüência de comandos }

Uma variável é testada sucessivamente contra uma lista de variáveis inteiras ou de caracteres. Depois de encontrar uma coincidência, o comando ou o bloco de comandos é executado. Se nenhuma coincidência for encontrada o comando default será executado. O default é opcional. A sequência de comandos é executada até que o comando break seja encontrado. Exemplo: main() { char x; printf("1. inclusão\n"); printf("2. alteração\n"); printf("3. exclusão\n"); printf(" Digite sua opção:"); x=getchar(); switch(x) { case '1': printf("escolheu inclusão\n"); break; case '2': printf("escolheu alteração\n"); break; case '3': printf("escolheu exclusão\n"); break; default: printf("opção inválida\n"); } }

Page 57: Apostila Introdução a Programação versão 2013

57

4.5.4 - Loop for Sintaxe: for(inicialização;condição;incremento) comando; O comando for é de alguma maneira encontrado em todas linguagens procedurais de programação. Em sua forma mais simples, a incialização é um comando de atribuição que o compilador usa para estabelecer a variável de controle do loop. A condição é uma expressão de relação que testa a variável de controle do loop contra algum valor para determinar quando o loop terminará. O incremento define a maneira como a variável de controle do loop será alterada cada vez que o computador repetir o loop. Exemplo: main() { int x;for(x=1;x<100;x++)printf("%d\n",x);} Ex: main() { int x,y; for (x=0,y=0;x+y<100;++x,++y) printf("%d ",x+y); }

Um uso interessante para o for é o loop infinito, como nenhuma das três definições são obrigatórias, podemos deixar a condição em aberto. Exemplo: main() { for(;;) printf("loop infinito\n"); }

Outra forma usual do for é o for aninhado, ou seja, um for dentro de outro. Exemplo: main() { int linha,coluna; for(linha=1;linha<=24;linha++) { for(coluna=1;coluna<40;coluna++) printf("-"); putchar('\n'); } }

Page 58: Apostila Introdução a Programação versão 2013

58

4.5.5 - While Sintaxe: while(condição) comando; Uma maneira possível de executar um laço é utilizando o comando while. Ele permite que o código fique sendo executado numa mesma parte do programa de acordo com uma determinada condição:

• o comando pode ser vazio, simples ou bloco, • ele é executado desde que a condição seja verdadeira, • testa a condição antes de executar o laço.

Exemplo: main() { char ch; while(ch!='a') ch=getchar(); }

4.5.6 - Do while Sintaxe: do { comando; } while(condição);

Também executa comandos repetitivos. Exemplo: main() { char ch; printf("1. inclusão\n"); printf("2. alteração\n"); printf("3. exclusão\n"); printf(" Digite sua opção:"); do { ch=getchar(); switch(ch) { case '1': printf("escolheu inclusao\n"); break; case '2': printf("escolheu alteracao\n"); break; case '3':

Page 59: Apostila Introdução a Programação versão 2013

59

printf("escolheu exclusao\n"); break; case '4': printf("sair\n"); } } while(ch!='1' && ch!='2' && ch!='3' && ch!='4'); }

4.5.7 – Break Quando o comando break é encontrado em qualquer lugar do corpo do for, ele causa seu término imediato. O controle do programa passará então imediatamente para o código que segue o loop. Exemplo: main() { char ch; for(;;) { ch=getchar(); if (ch=='a') break; } }

Existem ainda na linguagem C padrão, dois comandos que não são usados regularmente. São eles, continue e goto . O comando continue é relacionado com o break e executa a parte do teste imediatamente, quando usado dentro de um laço while. O comando goto desvia o fluxo da execução para um ponto direcionado por um rótulo, mas formalmente o goto nunca é necessário e na prática é sempre fácil escrever códigos sem usá-lo. Por estas razões, não iremos aprofundar na análise desses comandos.

Page 60: Apostila Introdução a Programação versão 2013

60

EXERCÍCIO- 05

1 - O que faz o seguinte programa?

#include <stdio.h>

int main()

{ int x;

scanf("%d",&x);

printf("%d",x);

return (0);

}

2 - Escreva um programa que leia um caracter digitado pelo usuário, imprima o caracter digitado e o código ASCII correspondente a este caracter.

3 - Explique porque está errado fazer if (num=10) ... O que irá acontecer?

4 - Dê o valor das variáveis x, y e z depois da seguinte sequência de operações:

int x,y,z; x=y=10; z=++x; x=-x; y++; x=x+y-(z--);

5- Faça um programa que apresente na tela a tabela de conversão de graus Celsius para Fahrenheit, de -100 C a 100 C. Use um incremento de 10 C. OBS: Farenheit = (9/5)*(Celsius) + 32.

Page 61: Apostila Introdução a Programação versão 2013

61

6 - Calcule e imprima o valor em reais de cada kw o valor em reais a ser pago o novo valor a ser pago por essa residência com um desconto de 10%. Dado: 100 kilowatts custa 1/7 do salário mínimo; quantidade de kw gasto por residência. 7 - Cálculo de um salário líquido de um professor . Serão fornecidos valor da hora aula, número de aulas dadas e o % de desconto do INSS. 8 - Solicitar salário, prestação. Se prestação for maior que 20% do salário, imprimir : Empréstimo não pode ser concedido. Senão imprimir Empréstimo pode ser concedido. 9 - Apresentar os quadrados dos números inteiros de 15 a 200 10 - Apresentar todos os números divisíveis por 4 que sejam menores que 200. 11 - Elaborar um programa que efetue a leitura sucessiva de valores numéricos e apresente no final o total do somatório, a média e o total de valores lidos. O programa deve fazer as leituras dos valores enquanto o usuário estiver fornecendo valores positivos. Ou seja, o programa deve parar quando o usuário fornecer um valor negativo. 12 - Ler 3 números e imprimir se eles podem ou não ser lados de um triângulo. A condição para isto é que A<B+C e B<A+C e C<A+B. 13 - Solicitar a idade de várias pessoas e imprimir: Total de pessoas com menos de 21 anos. Total de pessoas com mais de 50 anos. O programa termina quando idade for =-99. 14 - Faça um programa que, dado um número de conta corrente com três dígitos, retorne o seu dígito verificador, o qual é calculado da seguinte maneira: Exemplo: número da conta: 235 - somar o número da conta com o seu inverso: 235 + 532 = 767 - multiplicar cada dígito pela sua ordem posicional e somar estes resultados: 7 x 1 + 6 x 2 + 7 x 3 = 40 - o último dígito desse resultado é o dígito verificador da conta, isto é o número zero.

Page 62: Apostila Introdução a Programação versão 2013

62

4.6 - Matrizes e Vetores Existe situações em que os tipos de dados básicos não são suficientes para resolver os problemas encontrados na prática. Em muitas dessas situações, podemos utilizar estruturas de dados homogêneas do tipo vetor ou matriz. Um vetor/matriz é uma coleção de variáveis do mesmo tipo, que é referenciada por um nome comum, sendo que para acessarmos um elemento específico dentro desta coleção de variáveis, utilizamos um índice. 4.6.1 - Vetores Antes de iniciar o nosso assunto, é importante algumas informações. Visto que vetores, matrizes e strings são assuntos fundamentais da linguagem de programação C, um bom programador em C precisa ter domínio sobre esses conteúdos. Assim sendo, recomenda-se que você dedique bastante atenção a esta aula. Aqui serão abordados: o uso de matrizes e strings, suas operações fundamentais e suas aplicações. Mais uma vez, vale salientar que, para que esse assunto seja bem absorvido, é necessário que o aluno tenha trabalhado bem com as atividades práticas dos conteúdos anteriores. Assim como nas aulas passadas, serão sugeridas atividades durante o desenvolvimento do texto e ao final do capítulo, tudo isso para facilitar o aprendizado. Durante seus estudos, você viu que uma variável é um espaço na memória reservado para armazenar valores definidos de acordo com determinados tipos de dados (Aula 2). Por exemplo, variáveis podem ser dos tipos de dados básicos (float, int etc.), podendo armazenar apenas um valor. Entretanto, caso você queira escrever um programa que solicita ao usuário a entrada das notas de 50 alunos de uma turma de sua escola, teria que declarar 50 variáveis do tipo float, como visto no exemplo a seguir: float nota1; float nota2; ... float nota49; float nota50; Essa solução, porém, não é interessante. Para situações como essa, podemos fazer uso de vetores, uma estrutura de dados homogênea e indexada que pode armazenar diversos valores de um mesmo tipo de dado.

Page 63: Apostila Introdução a Programação versão 2013

63

Vetor é uma estrutura de dados homogênea, ou seja, que armazena valores de um mesmo tipo. A figura 15 mostra a declaração de um vetor de 50 posições e sua representação na memória: float notas[50];

Figura 15 – Exemplo de declaração de um vetor

O índice representa a posição onde o dado está armazenado no vetor. Por exemplo, na figura anterior, o valor armazenado na segunda posição do vetor é 9,0. Assim, diz-se que o vetor é uma estrutura indexada. Da mesma forma que as demais variáveis, os vetores devem ser declarados para que o compilador aloque espaço na memória para elas. O modelo a forma geral de declaração de vetores segue abaixo: tipo nome_da_variavel[tamanho] Como exemplo, vamos declarar um outro vetor, agora de 100 elementos chamado material contendo elementos do tipo double: double material[100]; Os elementos de um vetor são identificados pelo nome da variável e a posição que ele ocupa no vetor, da seguinte forma: nome_da_variavel[indice] Sendo que, na linguagem C, a primeira posição corresponde ao índice 0 (zero). Portanto, os elementos do vetor material declarado anteriormente são identificados como mostrado a seguir: material[ 0 ] /* corresponde à primeira posição no vetor, de índice zero */ material[ 1 ] /* corresponde à segunda posição no vetor, de índice um */ material[ 2 ], /* corresponde à terceira posição n o vetor, de índice dois */ ... material[ 98 ] /* e assim por diante... */ material[ 99 ]

Page 64: Apostila Introdução a Programação versão 2013

64

Vamos observar o programa abaixo, onde é carregada um vetor de inteiros com os números de 0 a 99: void main (void) { int x[100]; /* isto reserva 100 elementos intei ros */ int t; for( t=0; t<100; ++t ) x[ t ] = t; } Vejamos outro exemplo: Preencher um vetor com números inteiros (8 unidades); solicitar um número do teclado. Pesquisar se esse número existe no vetor. Caso exista, imprimir em qual posição do vetor. Se não, imprimir mensagem que não existe. main() { int x, vet[8], num, achei=0; for(int x=0;x<8;x++) { printf("\n[%d] Digite um numero: ",x); scanf("%d",&vet[x]); } printf("\n\n"); printf("Digite um valor a ser pesquisado: "); scanf("%d",&num); for(int x=0;x<8;x++) if(vet[x]==num) { printf("\n O numero %d esta na posicao %d: ",num,x) ; achei=1; } if(achei!=1) printf("\n Este numero nao existe"); printf("\n\n"); system("pause"); return(0); }

Cada variável ocupa um espaço determinado na memória, em número de bits, de acordo com o seu tipo. Por exemplo, uma variável char ocupa 8 bits. (tipos de dados segundo o padrão ANSI). A quantidade de espaço necessário para armazenar um vetor é relacionada ao seu tamanho e ao seu tipo. Para calcular o espaço de memória ocupado em bytes por um vetor, temos a seguinte fórmula: total em bytes = tamanho ocupado por um elemento do vetor * tamanho do vetor

Page 65: Apostila Introdução a Programação versão 2013

65

4.6.2 - Matrizes

Um ponteiro de matriz representa o endereço de memória (ou seja, a indicação do local exato na memória do computador) onde a matriz está armazenada. Para gerar um ponteiro para o primeiro elemento de uma matriz, é necessário apenas especificar o nome da matriz, sem nenhum índice. Segue um exemplo:

int modelo [ 10 ];

Também é possível gerar um ponteiro para o primeiro elemento apenas usando o nome da variável, no caso do exemplo, modelo. No exemplo a seguir, atribui-se a p o endereço do primeiro elemento de modelo.

int *p;

int modelo [ 10 ];

p = modelo.

Pode-se utilizar o símbolo & para especificar o endereço do primeiro elemento, mas isso não é muito utilizado.

Exemplo: modelo e &modelo [ 0 ] irão produzir o mesmo resultado.

Em C, não é possível passar uma matriz inteira como argumento para uma função. É necessário passar um ponteiro de uma matriz para uma função, colocando o nome da matriz sem o índice. No exemplo abaixo, vamos observar o endereço de i sendo passado para func1( ):

void main (void)

{

int i [10];

func1 ( i );

...

}

Se uma função recebe uma matriz unidimensional, o parâmetro pode ser declarado de três maneiras. Vamos observar isso tendo como exemplo a função chamada func1( ) que está recebendo o argumento i no exemplo anterior. Essa função poderia ser declarada da seguinte forma:

Page 66: Apostila Introdução a Programação versão 2013

66

void func1 ( int *x ) /* ponteiro */

{

}

Essa declaração está usando um ponteiro. Podemos fazer também:

void func1 ( int x [10] ) /* Matriz Dimension ada */

{

...

}

Essa declaração utiliza a declaração de matriz padrão.

Ainda pode ser feito:

void func1( int x [ ]) /* Matriz não-dimensiona da */

{

...

}

Essa última declaração especifica que uma matriz do tipo int de algum tamanho será recebida.

Todos os três métodos produziram resultados similares, pois todos dizem ao compilador que um ponteiro inteiro será recebido.

4.6.3 - Strings

Strings nada mais são que vetores de chars. O uso mais comum de matrizes unidimensionais é como string de caracteres. A declaração geral para uma string é:

char nome_da_string [tamanho];

O tamanho de um string deve ser sempre um caractere mais longo do que o número de caracteres que se pretende que ele armazene. Isso porque, em todo string, ao final da sequência de caracteres armazenada, é adicionado um elemento específico, que indica o fim de string, cujo valor é '/0' (ou seja, nulo).

Vamos observar o exemplo abaixo, em que para guardar uma matriz de 10 caracteres será necessário escrever:

Page 67: Apostila Introdução a Programação versão 2013

67

char str [11];

Isso irá reservar o espaço nulo ao final da string.

Na linguagem C, não existe o tipo de dado String. Um string é declarado como um vetor de char. Porém, é possível manipular constantes string. Uma constante string é uma lista de caracteres entre aspas, vejamos:

"Olá Brasil"

O trecho acima representa uma constante string. Nesse caso, não será necessário adicionar o valor nulo ao final da string, pois o próprio compilador C fará isso automaticamente.

A função gets( ) lê uma string do teclado. Sua forma é:

gets (nome_da_string);

No exemplo do programa abaixo, é demonstrado o funcionamento da função gets( ):

int main ( )

{

char string[100];

printf ("Digite o seu nome: ");

gets (string);

printf ("\n\n Ola %s",string);

return(0);

}

Observe que é válido passar para a função printf( ) o nome da string. Como o primeiro argumento da função printf( ) é uma string, também é válido fazer:

printf (string);

Isso simplesmente imprimirá a string.

Page 68: Apostila Introdução a Programação versão 2013

68

EXERCÍCIO- 06

1 - Preencher um vetor com os números pares do número 2 a 20. 2 - Preencher um vetor com os números pares do número 2 a 20. Preencher outro or com os números de 10 a 19. Somar os dois vetores e mostrar o resultado na tela. 3 - Armazenar em Vetores, Nomes e Notas PR1 e PR2 de 6 alunos. Calcular a média de cada aluno e imprimir aprovado se a média for maior que 5 e reprovado se média for menor ou igual a 5. OBS.: 2 vetores para as notas tipo float. 1 vetor para os nomes. 1 vetor para a média. 1 vetor para situação. 4 - Fazer um programa em C que leia uma frase de até 50 caracteres(utilizar o comando gets) em minúscula e imprima a frase em maiúscula. 5 - Faça um programa que leia várias palavras pelo teclado, e armazene cada palavra em uma string. Depois, concatene todas as strings lidas numa única string. Por fim apresente esta como resultado ao final do programa. 6 - O que imprime o programa a seguir? Tente entendê-lo e responder. A seguir, execute-o e comprove o resultado. # include <stdio.h> int main() { int t, i, M[3][4]; for (t=0; t<3; ++t) for (i=0; i<4; ++i) M[t][i] = (t*4)+i+1; for (t=0; t<3; ++t) { for (i=0; i<4; ++i) printf ("%3d ", M[t][i]); printf ("\n"); } return(0); }

Page 69: Apostila Introdução a Programação versão 2013

69

Fonte: http://pt.wikipedia.org/wiki/C_(linguagem_de_programa%C3%A7%C3%A3o)

Em: 01/05/2013

ANSI C e ISO C

Durante os finais da década de 1970, a

linguagem C começou a substituir a

linguagem BASIC como a linguagem de

programação demicrocomputadores mais

usada. Durante a década de 1980, foi

adaptada para uso no PC IBM, e a sua

popularidade começou a aumentar

significativamente. Ao mesmo tempo, Bjarne

Stroustrup, juntamente com outros nos

laboratórios Bell, começou a trabalhar num

projecto onde se adicionavam construções

de linguagens de programação orientada

por objectos à linguagem C. A linguagem

que eles produziram, chamada C++, é nos

dias de hoje a linguagem de programação de aplicações mais comum no sistema operativoWindows da

companhia Microsoft; C permanece mais popular no mundo Unix.

Em 1983, o instituto norte-americano de padrões (ANSI) formou um comité, X3J11, para estabelecer uma

especificação do padrão da linguagem C. Após um processo longo e árduo, o padrão foi completo

em 1989 e ratificado como ANSI X3.159-1989 "Programming Language C". Esta versão da linguagem é

frequentemente referida como ANSI C. Em 1990, o padrão ANSI C, após sofrer umas modificações

menores, foi adotado pela Organização Internacional para Padronização (ISO) como ISO/IEC 9899:1990,

também conhecido como C89 ou C90. Um dos objetivos do processo de padronização ANSI C foi o de

produzir um sobreconjunto do K&R C, incorporando muitas das características não-oficiais

subsequentemente introduzidas. Entretanto, muitos programas tinham sido escritos e que não

compilavam em certas plataformas, ou com um certo compilador, devido ao uso de bibliotecas de funções

não-padrão e ao fato de alguns compiladores não aderirem ao ANSI C.

Após o processo da padronização ANSI, as especificações da linguagem C permaneceram relativamente estáticas por algum tempo, enquanto que a linguagem C++ continuou a evoluir. (em 1995, a Normative Amendment 1 criou uma versão nova da linguagem C mas esta versão raramente é tida em conta.) Contudo, o padrão foi submetido a uma revisão nos finais da década de 1990, levando à publicação da norma ISO 9899:1999 em 1999. Este padrão é geralmente referido como "C99".

Ken Thompson e Dennis Ritchie (da esquerda para direita), os criadores das linguagens B e C, respectivamente

Page 70: Apostila Introdução a Programação versão 2013

70

Capítulo 5

Desenvolvimento de Projetos com Microcontroladores

Em sistemas de Controle, supervisão, medição, comunicação e Automação, são raros os exemplos em que não há necessidade do uso de alguma unidade de processamento. De fato, a não ser que o sistema possua uma lógica extremamente simples, se faz necessário o uso de uma ou mais CPUs (Central Processing Unit). Isso inclui sistemas que apresentam desde uma simples interface com o usuário por meio de um display LCD (Liquid Cristal Display) até o complexo controle de um veículo aeroespacial. Estes sistemas são definidos como “Sistemas embarcados” e hoje se fazem presentes em praticamente todas as áreas de atividade humana.

Figura 16 – Exemplos de sistemas embarcados

Entretanto, definida a necessidade de se empregar um elemento processador no sistema, resta o problema de definir qual plataforma utilizar. Entre as diversas disponíveis, há CLPs (Controladores Lógico-Programáveis), FPGAs (Field-Programmable Gate Array), DSPs (Digital Signal Processing), PCs (embarcados ou não), entre outras. Assim, a escolha do ”cérebro” do sistema deve se dar a partir de um compromisso entre as diversas necessidades do

Page 71: Apostila Introdução a Programação versão 2013

71

projeto e as características apresentadas pelo elemento processador, como custo, capacidade de processamento, memória, linguagem de programação disponível, capacidade de atuar em sistemas de controle em tempo real, consumo de energia, etc. Nesse contexto, os microcontroladores geralmente se apresentam como uma das alternativas de menor custo, confiabilidade satisfatória, simplicidade, menor tempo de desenvolvimento e menor consumo; porém com limitada capacidade de processamento e memória. Em termos gerais, os microcontroladores podem ser definidos como processadores que foram encapsulados com memória, interface de entrada/saída de dados e dispositivos periféricos. Entre os periféricos estão conversores A/D (analógico/digital), temporizadores/contadores, interface para comunicação serial, Timer programável, etc. Em outras palavras, são computadores encapsulados em um único invólucro, como pode ser observado na arquitetura geral mostrada na figura 17.

Figura 17 – Microcontrolador, arquitetura típica

Uma Linguagem de Programação é na verdade uma forma de “interação” que possibilita que um determinado sistema (seja qual for, desde que programável”) compreenda o que deve ser feito através de comandos implementados de acordo com o que se conceitua "Lógica de Programação". Esta seria a visão up-down (do programador para o sistema). Numa visão down-up (do sistema para programador) uma Linguagem de Programação é aquela que permite que o sistema receba os comandos desejados, de maneira ordenada e lógica, por parte do programador. Para muitos, este é o trabalho do compilador e não da Linguagem de Programação. Um grande erro. O compilador apenas realiza o trabalho de “tradução” (da sintaxe utilizada de códigos por nós compreendido, na linguagem de máquina). Ou seja, se você não sabe como usar uma “Linguagem de Programação” e não tem ideia de como deve ser a Lógica de Programação para um determinado caso, não saberá como usar um compilador (seja qual for). É mais ou menos assim: “de nada adianta ter um dicionário bilingue em mãos, se você não souber como usar uma das Línguas

Page 72: Apostila Introdução a Programação versão 2013

72

presentes no mesmo”. As IDE’s disponíveis para o desenvolvimento de aplicações para microcontroladores, oferecem, basicamente, as funcionalidades mostradas na figura 17. O editor e compilador normalmente aceita receber códigos em assembley – que é a linguagem nativa do microcontrolador alvo e também códigos em uma linguagem de alto nível como a linguagem C/C++ que é uma das mais utilizadas. Existem IDE’s que trabalham também em diversas outras linguagens como Basic (praticamente em desuso) e Java.

Figura 18 – Configuração de uma IDE para microcontroladores

Vamos então desenvolver pequenas aplicações em linguagem C para “rodar” em um microcontrolador, buscando atender as necessidades de um projeto. Vamos utilizar como processador alvo, microcontroladores da família MSP430 da Texas Instruments. Mais especificamente, todos os nossos projetos aplicativos estarão baseados no Kit para desenvolvimento “LaunchPad – MSP-EXP430G2, fornecido pela própria Texas por ser de baixo custo (custa somente $4.30 Com frete gratuito), possuir vasta documentação e exemplos disponíveis, o que o torna ideal para a aprendizagem nesse universo da programação e desenvolvimento de sistemas dedicados ( figura 19).

Figura 19 – Ferramenta de Desenvolvimento - LaunchPad – MSP-EXP430G2

Page 73: Apostila Introdução a Programação versão 2013

73

5.1 - Metodologia de Projeto de Sistemas Embarcados O projeto de sistemas embarcados deve seguir uma metodologia precisa. Três razões principais justificam a importância de se seguir uma metodologia de projeto: 1 - permitir que o cumprimento dos requisitos de projeto possam ser assegurados de maneira formal à medida que o projeto avança; 2 - potencializar o uso de ferramentas de automatização das tarefas,tais como ferramentas de IDE e CAD, uma vez que cada etapa é conhecida e pode ser dividida em pequenas tarefas; 3 – Documentação, visando facilitar a comunicação entre as equipes de desenvolvimento, já que o estabelecimento da metodologia também auxilia a repartição de responsabilidades, permitindo que cada equipe tome ciência das atribuições das demais e da maneira como estão vinculadas no projeto. Seja qual for a metodologia adotada, ela deve ser capaz de realizar três ações comuns a todo projeto: especificação/modelagem, validação e síntese. O processo de especificação e modelagem de um sistema, sub-sistema ou componente, pode ser resumido como o processo que inicia com a descrição de uma especificação e termina com a descrição de um modelo. um modelo formal deve conter:

• Uma especificação funcional, sob a forma de um conjunto de relações explícitas ou implícitas que envolvem entradas, saídas, e possíveis estados internos;

• Um conjunto de propriedades que o projeto deve satisfazer, dadas na

forma de um conjunto de relações entre entradas, saídas e estados, que possam ser comparados com a especificação funcional;

• Um conjunto de índices de desempenho que avaliem a qualidade do

projeto em termos de custo, confiabilidade, velocidade, tamanho, etc., dados como um conjunto de equações que envolvam, entre outras coisas, entradas e saídas;

• Um conjunto de restrições sobre os índices de desempenho.

Dessa forma, o projeto durante o processo de especificação e modelagem pode ser visto como a sequência de passos que implementam o modelo Especificado, cumprindo as formalidades descritas.

Page 74: Apostila Introdução a Programação versão 2013

74

5.2 - PROJETO Título do projeto: Pisca Led com microcontrolador M SP4030 5.2.1 – Escopo do projeto: Desenvolvimento do primeiro programa para ser gravado em um microcontrolador MSP430, mais especificamente o MSPG2231, usando a ferramenta de desenvolvimento LaunchPad e o port do GNU gcc para o MSP430. 5.2.2 – Descrição do Hardware O MSPG2231 é um microcontrolador da família MSP430, são dispositivos de baixo consumo de energia, com CPU RISC de 16-bit. Este microcontrolador possui um total de 14 pinos e o que acompanha a LaunchPad vem em encapsulamento DIP. Como todo microcontrolador, além de CPU e de dispositivos de entrada e saída os microcontroladores desta família possuem uma série de recursos como memória, timers, conversores analógico-digital e digital-analógico entre outros. No momento, vamos nos concentrar em usar as saídas para acender e apagar leds. O kit de desenvolvimento possui dois leds, um ligado ao pino zero da porta um (P1.0) em um ligado ao pino seis também da porta um (P1.6). Nosso código fará com que os dois leds fiquem piscando alternadamente, quando um estiver acesso, o outro estará apagado. 5.2.3 - Desenvolvimento do código fonte

Código fonte: pisca-led

Page 75: Apostila Introdução a Programação versão 2013

75

A linha 1 contém apenas um comentário, com o nome do arquivo e o que ele faz.

1 // blink.c - Exemplo de pisca led

A linha 2 é uma diretiva para que o compilador considere o conteúdo do arquivo msp430x20x1.h durante a compilação deste código.

2 #include <msp430x20x1.h>

A linha 4 é a declaração da função Delay, que é de fato o tempo entre a alteração dos estados dos leds.

4 void Delay(void);

Na linha 6 iniciamos a função principal do programa, que vai até a linha 15.

6 int main(void) {

A linha 7, serve para parar o Watchdog Timer (Um dispositivo de segurança que reinicia o microcontrolador caso exista algum problema como por exemplo um loop infinto. De fato caso o Watchdog esteja ativado ele reinicia o microcontrolador ao passar de um determinado tempo, sendo assim softwares mais elaborados, que fazem uso do Watchdog devem se preocupar em reiniciar esta contagem antes dela acabar – uma forma de informar que o sistema está funcionando corretamente – para que o microcontrolador não seja reiniciado).

7 WDTCTL = WDTPW | WDTHOLD;

A linha 8 é a instrução que define que os pinos 0 e 6 da porta 1 serão utilizadas como pinos de saída. Na tabela abaixo isso se torna mais claro.

O número 0×41 em hexadecimal pode ser escrito como 0b01000001 em notação binária, e cada bit corresponde a um pino da porta, onde 0 configura o pino como entrada e 1 como saída.

Representação de 0×41 em binário Pino da porta Estado do pino

0 P1.7 Pino configurado como entrada

1 P1.6 Pino configurado como saída

0 P1.5 Pino configurado como entrada

Page 76: Apostila Introdução a Programação versão 2013

76

Representação de 0×41 em binário Pino da porta Estado do pino

0 P1.4 Pino configurado como entrada

0 P1.3 Pino configurado como entrada

0 P1.2 Pino configurado como entrada

0 P1.1 Pino configurado como entrada

1 P1.0 Pino configurado como saída

8 P1DIR = 0x41;

A linha 9 contém a instrução que leva os pinos da porta um para nível alto ou nível baixo de acordo com o valor atribuído à P1OUT. Neste caso, como 0×40 pode ser representado por 0b01000000 em notação binária, neste instante apenas o pino 6 da porta 1 estará em nível alto, o pino 1, que também está configurado como pino de saída, estará com nível baixo, pois seu bit correspondente está com valor 0, como pode ser visto com maior clareza na tabela abaixo.

Representação de 0×40 em binário Pino da porta Nível de tensão no pino

0 P1.7 Nível baixo

1 P1.6 Nível alto

0 P1.5 Nível baixo

0 P1.4 Nível baixo

0 P1.3 Nível baixo

0 P1.2 Nível baixo

0 P1.1 Nível baixo

0 P1.0 Nível baixo

9 P1OUT = 0x40;

A instrução da linha 11 coloca o microcontrolador em um loop infinito, fazendo com que as instruções dentro deste laço sejam executadas enquanto o programa esteja rodando. While significa enquanto, ou seja, enquanto o resultado da operação entre parênteses for verdadeira, o microprocessador ficará executando as instruções entre as chaves, no caso as instruções da linha 11 até a linha 14.

Page 77: Apostila Introdução a Programação versão 2013

77

Em C, qualquer inteiro diferente de 0 equivale a verdadeiro e um inteiro igual a 0 equivale a falso.

Desta forma while(1) é o mesmo que dizer ao microcontrolador para que fique executando as instruções dentro das chaves do while para sempre.

11 while(1){

Na linha 12, executamos novamente a instrução P1OUT para mudar o nível de tensão nos pinos da porta P1.

Vamos usar a função lógica XOR (^) para modificar o bit 0 e o bit 6 da porta 1 (P1.0 e P1.6).

Lembrando que o estado atual dos níveis de tensão da porta P1 estão definidos para 0×40, vamos executar XOR entre os pinos do estado atual (P1OUT) e 0×41 e em seguida atribuir o resultado desta operação ao estado da porta.

Para facilitar o entendimento vejamos a operação XOR com os argumentos da operação em suas representações binárias.

Numero em hexadecimal Número em binário

Estado atual da porta (P1OUT) 0×40 0b01000000

Valor fixo usado na operação 0×41 0b01000001

Resultado da operação XOR 0×01 0b00000001

Desta forma uma vez que a instrução desta linha seja executada, caso o estado da porta seja 0×40 (em binário 0b01000000, que equivale ao pino 6 da porta 1 em nível alto) ao final da execução o estado de P1OUT será alterado para 0×01 (em binário 0b00000001, que equivale ao pino 0 da porta 1 em nível alto).

12 P1OUT = P1OUT ^ 0x41;

A linha 13, desvia o fluxo do programa para a função Delay, que tem como único objetivo gastar tempo, de forma que seja perceptível a olho nú a alteração dos estados dos leds.

13 Delay();

Page 78: Apostila Introdução a Programação versão 2013

78

Entre as linhas 17 e 22 está a função Delay. Esta função não recebe nenhum argumento e não retorna nada, como já foi dito, sua utilidade é gastar tempo e para isso toda vez que ela é chamada, em seu escopo é declarada uma variável de valor inteiro e sem sinal igual a 30000 (unsigned int dly = 30000;) que é decrementada através da instrução –dly. Como condição do while o próprio valor de dly após o decremento, assim que dly chegar a 0 a função Delay é encerrada, e o fluxo do programa é redirecionado para a função principal (main).

17 void Delay(void) { 18 unsigned int dly = 30000; 19 while(--dly); { 20 // Nothing:D 21 } 22 }

Após retornar, o microcontrolador irá executar a instrução após a instrução Delay da linha 13 que, neste caso por estar em um loop infinito, será a instrução da linha 12. Novamente o XOR entre o estado atual da porta P1 (P1OUT) e 0×41.

Desta vez P1OUT é 0×01 e o resultado da operação XOR com 0×41 levará o estado de P1 de volta para 0×40.

Assim, o laço infinito em que colocamos o microcontrolador ficará alternando os estados dos pinos P1.0 e P1.6 e em seguida gastando um determinado tempo para que possamos perceber esta alteração, e forma visual.

Page 79: Apostila Introdução a Programação versão 2013

79

5.3 - PROJETO

Título do projeto: SENSOR DE TEMPERATURA COM LAUNCHPAD_MSP430

Baseado no artigo: SENSOR DE TEMPERATURA CON LAUNCHPAD MSP430 (TEXAS) W. Gómez (273558), J. Barrera (273219), C. Castañeda (416044), y K. Núñez (274345) Facultad de Ingeniería, Ciencias, Fundamentos de Electricidad y Magnetismo Grupo 12 Universidad Nacional de Colombia, Bogotá 19 de Junio de 2012 5.3.1 - Escopo do projeto: Medir a temperatura ambiente por meio de sensor LM35, cuja tensão de saída é linearmente proporcional à temperatura em graus centígrados. (-55 ° C a 150 ° C). O circuito é baseado no Kit LaunchPad MSP430. Os dados da temperatura será apresentado em um display LCD.

5.3.2 – Justificativa A temperatura é uma das grandezas físicas mais medida. Os sensores de temperatura convertem uma grandeza física em um valor de resistência ou de tensão. O uso de sensores de temperatura é muito amplo. Seja a temperatura ambiente, ou a medição precisa em um processo químico industria, a medição é muito importante. Os sensores de temperatura usam diferentes efeitos físicos para converter uma temperatura em um parâmetro elétrico. Microprocessadores são ideais para se obter estes valores e, através de um programa, realizar as adaptações e conversões necessárias, para a visualização desses valores. 5.3.3 – Fundamentação teórica O início do processo passa pela conversão do sinal analógico vindo do sensor em um valor digital, para que possa ser tratado pelo software que será desenvolvido. O circuito integrado LM35 é um sensor de temperatura calibrado com uma precisão de 1 ° C com uma faixa que se estende a partir de -55 ° a 150 ° C. O LM35 é um sensor de precisão, fabricado pela National Semiconductor que apresenta uma saída de tensão linear relativa à temperatura em que ele se encontrar no momento em que for alimentado por uma tensão de 4-20Vdc, tendo em sua saída um sinal de 10mV para cada Grau Celsius de temperatura, sendo assim, apresenta uma boa vantagem com relação aos demais sensores de temperatura calibrados em “KELVIN”, não necessitando nenhuma subtração de variáveis para que se obtenha uma escala de temperatura em Graus Celsius.

Page 80: Apostila Introdução a Programação versão 2013

80

O LM35 não necessita de qualquer calibração externa ou “trimming” para fornecer com exatidão, valores temperatura com variações de ¼ºC ou até mesmo ¾ºC dentro da faixa de temperatura de –55ºC à 150ºC. Este sensor poderá ser alimentado com alimentação simples ou simétrica, dependendo do que se desejar como sinal de saída, mas independentemente disso, a saída continuará sendo de 10mV/ºC. O sensor LM35 é apresentado com vários tipos de encapsulamentos, sendo o mais comum o TO-92, que mais se parece com um transistor, e oferece ótima relação custo benefício, por ser o mais barato dos modelos e propiciar a mesma precisão dos demais. A grande diversidade de encapsulamentos se dá devido à alta gama de aplicações deste integrado.

Figura 20 – LM35

Os conversores A/D são dispositivos que estabelecem uma relação entre o valor do sinal analógico em sua entrada e a palavra digital obtida na sua saída. A relação é estabelecida na maioria dos casos, com a ajuda de uma tensão de referência. A conversão A/D tem o seu fundamento teórico no teorema da amostragem e os conceitos de quantização e codificação. O processo para mudar o formato de sinal envolve as seguintes etapas:

• Amostragem - Sampling • quantificação • codificação

Uma vez convertido, os dados devem ser tratados pelo programa e enviados para o display.

Um módulo de display de cristal líquido apesar de internamente possuir um microcontrolador dedicado para executar suas funções,tem uma operação muito simples. A maioria dos displays, encontrados no mercado, possuem recursos internos para facilitar ao máximo o controle dos mesmos, proporcionando uma interface com qualquer microcontrolador.

Page 81: Apostila Introdução a Programação versão 2013

81

Assim quando usamos um módulo LCD em um projeto, devemos preocuar apenas com os comandos necessários para escrever um caractere, apagar uma linha, ligar o cursor, e muitos outros comandos possíveis (de acordo com cada modelo).

A tabela seguinte lista alguns padrões utilizados com suas divisões em relação a linhas e colunas.

Indicação do fabricante Número de linhas

Número de colunas

Total de caracteres

16 x 1 1 16 16 16 x 2 2 16 32 16 x 4 4 16 64 20 x 4 4 20 80 40 x 2 2 40 80

O total de caracteres refere-se ao número total de elementos que podem ser demonstrados de uma única vez, inclusive espaços em branco.

Também é importante salientar que existem muitos outros padrões referentes ao número total de caracteres, sendo recomendável uma consulta aos fabricantes. Sempre que possível deve-se consultar os datasheets fornecidos pelo fabricante.

Finalmente a figura 21 mostra o esquema geral de conexões para o projeto .

Figura 21 – Diagrama geral do cicuito O programa de controle do termômetro, baseado no microcontrolador MSP430G2553 pode ser visto a seguir.

Page 82: Apostila Introdução a Programação versão 2013

82

5.3.4 - Código do Programa // PROGRAMA DE CONTROLE DO TERMOMETRO COM LM35 E LCD #include "io430.h" #include <msp430g2553.h> #include "ADC10_2553.h" void write_SegC (char value) // LCD Port assignement #define LCD_DIR P1DIR #define LCD_OUT P1OUT // Lcd Pin assignement #define LCD_PIN_RS BIT5 //#define LCD_PIN_RW BIT7 #define LCD_PIN_EN BIT6 #define LCD_PIN_D4 BIT1 #define LCD_PIN_D5 BIT2 #define LCD_PIN_D6 BIT3 #define LCD_PIN_D7 BIT4 //#define MAT_PIN BIT6 #define forever for(;;) // Procedure to strobe data to LCD register void LCDPulseEN(void) { // Set Enable active __delay_cycles(20); LCD_OUT |= LCD_PIN_EN; __delay_cycles(20); // Release Strobe LCD_OUT &= (~LCD_PIN_EN); } // this send 4 bit of data void SendNibble(char data) { // Clear all data bit LCD_OUT &= ~(LCD_PIN_D4|LCD_PIN_D5|LCD_PIN_D6|LCD _PIN_D7); // Set data bit on port bit if(data & 0x01) LCD_OUT |= LCD_PIN_D4; if(data & 0x02) LCD_OUT |= LCD_PIN_D5; if(data & 0x04) LCD_OUT |= LCD_PIN_D6; if(data & 0x08) LCD_OUT |= LCD_PIN_D7; // Nibble set complete, send to LCD LCDPulseEN(); __delay_cycles(500); } // Send a byte of data to LCD register void SendByte(unsigned char data) { SendNibble((data>>4) & 0x0F); SendNibble((data) & 0x0F); __delay_cycles(500); } // send a byte to command register void SendInstruction(unsigned char data) { // Set Register to command LCD_OUT &= ~LCD_PIN_RS; SendByte(data); __delay_cycles(80000); } // Send a byte of data to LCD register void LCDputch(unsigned char data) { // Set Register to data

Page 83: Apostila Introdução a Programação versão 2013

83

LCD_OUT |= LCD_PIN_RS; SendByte(data); __delay_cycles(500); } void InitLCD(void) { // clear all bit of LCD control & data Lines LCD_OUT &= ~(LCD_PIN_EN|LCD_PIN_RS); //|LCD_PIN_R W); // Set LCD pins to output LCD_DIR |=(LCD_PIN_EN|LCD_PIN_RS|LCD_PIN_D4|LCD_PIN_D5|LCD_ PIN_D6|LCD_PIN_D7); // |LCD_PIN_RW // wait Powerup __delay_cycles(100000); // LCD can be in an unknown state so set to a kno wn state sending 3 times LCD set to 8 bit mode SendNibble(3); __delay_cycles(16000); // Wait for init SendNibble(3); __delay_cycles(400); SendNibble(3); __delay_cycles(400); // now is 8 bit, sending 2 set mode to 4 bit (0x2 n) SendNibble(2); __delay_cycles(800); // Now set to mode 4 bit 2 line 5x7 char SendInstruction(0x28); __delay_cycles(8000); // Make cursor visible one line set to 0x0c to in visible cursor SendInstruction(0x0e);//c __delay_cycles(800); // Clear screen SendInstruction(0x01); __delay_cycles(8000); // Increment address mode SendInstruction(0x06); __delay_cycles(8000); // Set write data address to 0 SendInstruction(0x80); } // Set write cursor to Row and Col void LCDSetPosition(char Row, char Col) { // if row is not 0 add 0x40 (4 line models requir e adding 0 20 60 //40) if(Row) Col+=0x40; SendInstruction(0x80 | Col); __delay_cycles(800); } // Clear LCD void LCDClear(void) { SendInstruction(0x01); __delay_cycles(100000); } // Lcd cursor to first row first column void LCDGoToHome(void) { SendInstruction(0x02); __delay_cycles(100000); } // Shift left mode void LCDShiftLeft(void) { SendInstruction(0x18); } // Shift right mode void LCDShiftRight(void) { SendInstruction(0x1C); } // Cursor blinking mode

Page 84: Apostila Introdução a Programação versão 2013

84

void LCDBlinkCursor(void) { SendInstruction(0x0F); } // Print a text line to LCD screen void LCDPrintString(const char * Text) { while (*Text) LCDputch(*Text++); } void delay0(unsigned long i);//function for delays int temperatura; char temperaturad,temperaturau,temperaturaReal; char temperature; //char *pointer=&temperatura; void main (void) { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; InitLCD(); ADC10_Init(); //configure TIMER A TACTL = TASSEL_2 + ID_3 + MC_1; // Set up T imer A: Clock : SMCLK/8; //Mode : Up (counts from zero to the value of CCR0) CCR0 = 65000; // TAR counts up to CCR0 and resets to 0 (313*8 = 2504 us : ~ 2.5 ms) CCTL0 = CCIE; // CCR0 interrupt enabled _EINT(); // enable interrupts temperatura=ADC10_Read(0);///LECTURA DEL CANA L LCDClear(); ////////////////PROGRAMA PRINCIPAL forever{ temperature = (3.6*(float)temperatura*100)/10 24.0; temperaturaReal=temperatura+48; //2-1; temperaturad=temperature/10+48; temperaturau= temperature%10+48; //LCDputch(temperature); //LCDputch(temperaturaReal); LCDputch('T'); LCDputch('e'); LCDputch('m'); LCDputch('p'); LCDputch('e'); LCDputch('r'); LCDputch('a'); LCDputch('t'); LCDputch('u'); LCDputch('r'); LCDputch('a'); LCDputch(':'); LCDSetPosition(2,1); LCDputch(temperaturad); LCDputch(temperaturau);

Page 85: Apostila Introdução a Programação versão 2013

85

LCDputch('.'); LCDputch(temperaturau+2); LCDputch(temperaturad+3); LCDGoToHome(); delay0(140000); // LCDClear(); }//end forever }//end main void delay0(unsigned long i){ do (i--); while (i != 0); } //////////////////////////// Timer_A Interrupt Vect or handler//////////////// #pragma vector=TIMER0_A0_VECTOR //Interrupt vector for channel CCR0 __interrupt void Timer_A(void) { temperatura=ADC10_Read(0); }

. VER: MAIO-2013