055 a 094 material auxiliar para curso avançado i msp430

40
Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha Página 55 10. BREVE INTRODUÇÃO A LINGUAGEM C (http://pt.wikipedia.org/wiki/c_(linguagem_de_programaçao) ) C é uma linguagem de programação compilada de propósito geral , estruturada , imperativa , procedural , de alto nível , e padronizada , criada em 1972 , por Dennis Ritchie , no AT&T Bell Labs , para desenvolver o sistema operacional UNIX (que foi originalmente escrito em Assembly ). A linguagem C é classificada de alto nível pela própria definição desse tipo de linguagem. A programação em linguagens de alto nível tem como característica não ser necessário conhecer o processador, ao contrário das linguagens de baixo nível. As linguagens de baixo nível estão fortemente ligadas ao processador. A linguagem C permite acesso de baixo nível com a utilização de código Assembly no meio do código fonte. Assim, o baixo nível é realizado por Assembly e não C. Desde então, espalhou-se por muitos outros sistemas, e tornou-se uma das linguagens de programação mais usadas, e influenciou muitas outras linguagens, especialmente C++ , que foi originalmente desenvolvida como uma extensão para C. 10.1. História Ken Thompson e Dennis Ritchie (da esquerda pra direita), os criadores das linguagens B e C, respectivamente. O desenvolvimento inicial de C, ocorreu no AT&T Bell Labs, entre 1969 e 1973 . Deu-se o nome “C” à linguagem, porque muitas de suas características derivaram da linguagem B . C foi originalmente desenvolvido, para a implementação do sistema UNIX (originalmente escrito em PDP-7 Assembly, por Dennis Ritchie e Ken Thompson ). Em 1973, com a adição do tipo struct, C tornou-se poderoso o bastante para a maioria das partes do Kernel do UNIX, serem reescritas em C. Este foi um dos primeiros sistemas que foram implementados em uma linguagem, que não o Assembly, sendo exemplos anteriores, os sistemas: Multics (escrito em PL/I ) e TRIPOS (escrito em BCPL ). Segundo Ritchie , o período mais criativo ocorreu em 1972.

Upload: texas-instruments

Post on 03-Jul-2015

476 views

Category:

Education


3 download

DESCRIPTION

segunda parte do material do curso avançado I

TRANSCRIPT

Page 1: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 55

10. BREVE INTRODUÇÃO A LINGUAGEM C (http://pt.wikipedia.org/wiki/c_(linguagem_de_programaçao)) C é uma linguagem de programação compilada de propósito geral, estruturada, imperativa, procedural, de alto nível, e padronizada, criada em 1972, por Dennis Ritchie, no AT&T Bell Labs, para desenvolver o sistema operacional UNIX (que foi originalmente escrito em Assembly). A linguagem C é classificada de alto nível pela própria definição desse tipo de linguagem. A programação em linguagens de alto nível tem como característica não ser necessário conhecer o processador, ao contrário das linguagens de baixo nível. As linguagens de baixo nível estão fortemente ligadas ao processador. A linguagem C permite acesso de baixo nível com a utilização de código Assembly no meio do código fonte. Assim, o baixo nível é realizado por Assembly e não C. Desde então, espalhou-se por muitos outros sistemas, e tornou-se uma das linguagens de programação mais usadas, e influenciou muitas outras linguagens, especialmente C++, que foi originalmente desenvolvida como uma extensão para C.

10.1. História

Ken Thompson e Dennis Ritchie (da esquerda pra direita), os criadores das linguagens B e C, respectivamente. O desenvolvimento inicial de C, ocorreu no AT&T Bell Labs, entre 1969 e 1973. Deu-se o nome “C” à linguagem, porque muitas de suas características derivaram da linguagem B. C foi originalmente desenvolvido, para a implementação do sistema UNIX (originalmente escrito em PDP-7 Assembly, por Dennis Ritchie e Ken Thompson). Em 1973, com a adição do tipo struct, C tornou-se poderoso o bastante para a maioria das partes do Kernel do UNIX, serem reescritas em C. Este foi um dos primeiros sistemas que foram implementados em uma linguagem, que não o Assembly, sendo exemplos anteriores, os sistemas: Multics (escrito em PL/I) e TRIPOS (escrito em BCPL). Segundo Ritchie, o período mais criativo ocorreu em 1972.

Page 2: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 56

10.2. K&R C

Em 1978, Brian Kernighan e Dennis Ritchie publicaram a primeira edição do livro The C Programming Language. Esse livro, conhecido pelos programadores de C, como “K&R”, serviu durante muitos anos como uma especificação informal da linguagem. A versão da linguagem C que ele descreve é usualmente referida como “K&R C”. A segunda edição do livro, cobriu o padrão posterior, o ANSI C. K&R C introduziu as seguintes características na linguagem:

• Biblioteca padrão de E/S; • Tipos de dado struct; • Tipos de dado long int; • Tipos de dado unsigned int; • O operador =+ foi alterado para +=, e =- para -= (o analisador léxico do compilador

fazia confusão entre i =+ 10 e i = +10. O mesmo acontecia com =-). K&R C é freqüentemente considerado a parte mais básica da linguagem, cujo suporte deve ser assegurado por um compilador C. Durante muitos anos, mesmo após a introdução do padrão ANSI C, K&R C foi considerado o “menor denominador comum”, em que programadores de C se apoiavam quando uma portabilidade máxima era desejada, já que nem todos os compiladores eram atualizados o bastante para suportar o padrão ANSI C. Nos anos que se seguiram à publicação do K&R C, algumas características “não-oficiais” foram adicionadas à linguagem, suportadas por compiladores da AT&T e de outros vendedores. Estas incluíam:

• Funções void e tipos de dados void *; • Funções que retornam tipos struct ou union; • Campos de nome struct num espaço de nome separado para cada tipo struct; • Atribuição a tipos de dados struct; • Qualificadores const para criar um objecto só de leitura; • Biblioteca padrão, que incorpora grande parte da funcionalidade implementada por

vários vendedores; • Enumerações; • Cálculos de ponto-flutuante em precisão simples (no K&R C, os cálculos

intermediários eram feitos sempre em double, porque era mais eficiente na máquina onde a primeira implementação do C foi feita).

Page 3: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 57

10.3. 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 de microcomputadores 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 operativo Windows 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 é freqüentemente referida como ANSI C. Em 1990, o padrão ANSI C, após sofrer umas modificações menores, foi adotado pela Organização Internacional de Padrões (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 subseqüentemente 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.

10.4. C99 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”. O padrão foi adoptado como um padrão ANSI em Março de 2000. As novas características do C99 incluem:

• funções em linha • remoção de restrições sobre a localização da declaração de variáveis (como em C++) • adição de vários tipos de dados novos, incluindo o long long int (para minimizar

problemas na transição de 32-bits para 64-bits), um tipo de dados boolean explicito (chamado _Bool) e um tipo complex que representa números complexos

Page 4: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 58

• vetores de dados de comprimento variável (o vetor pode ter um tamanho diferente a

cada execução de uma função, mas não cresce depois de criado) • suporte oficial para comentários de uma linha iniciados por //, emprestados da

linguagem C++ • várias funções de biblioteca novas, tais como snprintf() • vários ficheiros-cabeçalho novos, tais como stdint.h

O interesse em suportar as características novas de C99 parece depender muito das entidades. Apesar do GCC e vários outros compiladores suportarem grande parte das novas características do C99, os compiladores mantidos pela Microsoft e pela Borland suportam pouquíssimos recursos do C99, e estas duas companhias não parecem estar muito interessadas em adicionar tais funcionalidades, ignorando por completo as normas internacionais. A Microsoft parece preferir dar mais ênfase ao C++.

10.5. Visão Geral C é uma linguagem imperativa e procedural, para implementação de sistemas. Seus pontos de design foram para ele ser compilado, fornecendo acesso de baixo nível à memória e baixos requerimentos do hardware. Também foi desenvolvido para ser uma linguagem de alto nível, para maior reaproveitamento do código. C foi útil para muitas aplicações que foram codificadas originalmente em Assembly. Essa propriedade não foi acidental; a linguagem C foi criada com o objetivo principal em mente: facilitar a criação de programas extensos com menos erros, recorrendo ao paradigma da programação algorítmica ou procedimental, mas sobrecarregando menos o autor do compilador, cujo trabalho complica-se ao ter de realizar as características complexas da linguagem. Para este fim, a linguagem C possui as seguintes características:

• Uma linguagem nuclear extremamente simples, com funcionalidades não-essenciais, tais como funções matemáticas ou manuseamento de arquivos, fornecida por um conjunto de bibliotecas de rotinas padronizada;

• A focalização no paradigma de programação procedimental; • Um sistema de tipos simples que evita várias operações que não fazem sentido • Uso de uma linguagem de pré-processamento, o pré-processador de C, para tarefas

tais como a definição de macros e a inclusão de múltiplos ficheiros de código fonte; • Ponteiros dão maior flexibilidade à linguagem; • Acesso de baixo-nível, através de inclusões de código Assembly no meio do

programa C;

Page 5: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 59

• Parâmetros que são sempre passados por valor para as funções e nunca por

referência (É possível simular a passagem por referência com o uso de ponteiros); • Definição do alcance lexical de variáveis; • Estruturas de variáveis, (structs), que permitem que dados relacionados sejam

combinados e manipulados como um todo. Algumas características úteis, que faltam em C, podem ser encontradas em outras linguagens, que incluem:

• Segurança de tipo; • Coletor de lixo (mais comum em linguagens interpretadas); • Vetores que crescem automaticamete; • Classes ou objectos com comportamento (ver orientação a objetos); • Closures (a closure is a function that is evaluated in an environment containing one or

more bound variables. When called, the function can access these variables); • Funções aninhadas; • Programação genérica; • Sobrecarga de operadores; • Meta-programação; • Apoio nativo de multithreading e comunicação por rede.

Apesar da lista de características úteis que C não possui, ser longa, isso não tem sido um impedimento à sua aceitação, pois isso permite que novos compiladores de C sejam escritos rapidamente para novas plataformas, e também permite que o programador permaneça sempre em controle do que o programa está a fazer. Isto é o que por várias vezes permite o código de C correr de uma forma mais eficiente que muitas outras linguagens. Tipicamente, só código de assembly “afinado à mão” é que corre mais rapidamente, pois possui um controle completo da máquina, mas avanços na área de compiladores juntamente com uma nova complexidade nos processadores modernos permitiram que a diferença tenha sido rapidamente eliminada. Uma consequência da aceitação geral da linguagem C é que freqüentemente os compiladores, bibliotecas e até intérpretes de outras linguagens de nível maior sejam eles próprios implementados em C. C tem como ponto forte, a sua eficiência, e é a linguagem de programação preferida para o desenvolvimento de sistemas e softwares de base, apesar de também ser usada para desenvolver programas de computador. É também muito usada no ensino de ciência da computação, mesmo não tendo sido projetada para estudantes e apresentando algumas dificuldades no seu uso. Outra característica importante de C, é sua proximidade do código de máquina, que permite que um projetista seja capaz de fazer algumas previsões de como o software irá se comportar, ao ser executado.

Page 6: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 60

C tem como ponto fraco, a falta de proteção que dá ao programador. Praticamente tudo que se expressa em um programa em C, pode ser executado, como por exemplo, pedir o vigésimo membro de um vetor com apenas dez membros. Os resultados são muitas vezes totalmente inesperados, e os erros, difíceis de encontrar.

10.6. Palavras reservadas na Linguagem C A linguagem C é do tipo “case sensitive”. E além disto, algumas palavras são reservadas, sendo seu uso limitado apenas as funções ou comandos que elas executam:

O compilador IAR tem também algumas palavras reservadas, o que veremos ao longo deste treinamento. 11. VARIÁVEIS, TIPOS DE DADOS E OPERADORES EM C

11.1. Tipos de dados Basicamente apenas 5 tipos de dados que são utilizadas em linguagem C:

• char – caractere – 8 bits, 1 byte; • int – inteiro – 16 bits, 2 bytes; • float – ponto flutuante – 32 bits, 4 bytes; • double – ponto flutuante de precisão dupla – 64 bits, 8 bytes; • void – sem valor.

Cada uma destes tipos pode ainda ter os seguintes modificadores:

Page 7: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 61

• signed – utilizará o último bit para sinalizar se um dado é positivo ou negativo. Com

isto, o dado sempre estará com um tamanho menor em um bit. • unsigned – não informa se o dado tem valor positivo ou negativo. Por conseqüência

todos os bits do dado podem ser utilizados como informação; • short – faz com que o dado passe a ter um tamanho menor do que especificado

em sua definição. Por exemplo: utilizar o shot int pode fazê-lo assumir o valor de apenas um bit, dependendo do compilador utilizado;

• long – faz com que o dado passe a ter um tamanho maior do que especificado em sua definição. Por exemplo: utilizar o long int pode fazê-lo assumir o valor de 65536 bits, dependendo do compilador utilizado

11.1.1. Detalhes sobre números em ponto flutuante A base numérica no padrão IEEE754 é a binária. Neste padrão são adotados dois formatos para representação de números: precisão simples e precisão dupla. (Na base binária, um dígito binário é denominado bit e um byte é um conjunto de 8 bits).

Page 8: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 62

Ficou estabelecido que no padrão IEEE754, em precisão simples, um número real seria representado por 32 bits, (4 bytes), sendo que:

• 1 bit é reservado para o sinal do número (positivo ou negativo); • 8 bits são reservados para o expoente da base, que é um número inteiro; • 23 bits são reservados para a mantissa:

Pelo mesmo padrão IEEE754, em precisão dupla, um número real seria representado por 64 bits, (8 bytes), sendo que:

• 1 bit é reservado para o sinal do número (positivo ou negativo); • 11 bits são reservados para o expoente da base, que é um número inteiro; • 52 bits são reservados para a mantissa:

Qualquer valor em ponto flutuante é sempre escrito no seguinte formato:

v = S × M × 2E Onde:

• S = 1 − 2 × sinal • M = 1 + mantissa × 2-23 • E = expoente − 127

Page 9: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 63

11.2. Declarando variáveis

É necessário, durante o fluxo do programa, declarar as variáveis que serão utilizadas de acordo com os tipos de dados mostrados anteriormente. Isto pode ser feito das seguintes maneiras:

TIPO nome_da_variável {,outras_variáveis};

unsigned int tempo;

As variáveis podem ser inicializadas com um determinado valor durante a sua declaração:

unsigned int tempo = 100;

11.2.1. Variáveis locais e globais

Dependendo do local onde é declarada a variável, esta pode assumir uma função global ou local:

• Variáveis globais são acessíveis de qualquer ponto do programa, por qualquer função, e devem ser declaradas no corpo principal do programa, fora de qualquer função, inclusive da main;

• Variáveis locais só podem ser acessadas dentro das funções onde foram criadas. Ao sair desta função, a linguagem C destrói uma variável local e, portanto ela não será acessível por outras funções.

O programa a seguir (E-0-1) dá uma demonstração de como as variáveis podem ser declaradas localmente ou globalmente: //****************************************************************************** // Exemplo de variáveis globais e locais // Alessandro Ferreira da Cunha // Tech Training - Engenharia e Treinamentos // Dezembro 2008 – Extraído do Livro “PIC – Programação em C”, do Fábio Pereira // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> int somatorio; // VARIÁVEL GLOBAL! SERÁ ACESSADA POR TODAS AS FUNÇÕES void soma (int valor) //AO ACESSAR ESTA FUNÇÃO, O PARÂMETRO VALOR RECEBE DADOS DE QUEM O CHAMOU { int conta; // VARIÁVEL LOCAL! SERÁ ACESSADA APENAS PELA FUNÇÃO SOMA somatorio = somatorio + valor; printf("0"); for (conta = 1;(conta<(valor+1));conta++) { printf("+%u",conta); } printf(" = %u\r\n",somatorio); } void main() { WDTCTL = WDTPW+WDTHOLD; // Stop WDT int conta; // VARIÁVEL LOCAL! SERÁ ACESSADA APENAS PELA FUNÇÃO MAIN somatorio = 0; // A VARIÁVEL GLOBAL É INICIALIZADA for (conta=1;conta<20;conta++) { soma(conta); // É CHAMADA A FUNÇÃO SOMA, ONDE É PASSADO O VALOR DE CONTA } }

Page 10: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 64

Alguns comentários importantes sobre o programa E-0-1:

• O comando printf chama uma biblioteca que emula o envio de dados pela porta serial do MSP430. No IAR será possível visualizar estes dados através do Terminal I/O, acessível em: View Terminal I/O, onde será aberta a janela mostrada abaixo. Para que ele funcione é necessário incluir a biblioteca padrão stdio.h

O formato do comando printf é:

printf (string, variável);

printf (“O número de tentativas foi %d”, contador);

Onde: • string: é uma constate de caracteres, sempre declarado entre aspas; • variável: é a declaração de uma ou mais variáveis que devem ser impressas

juntamente com os caracteres. Para tanto é necessário seguir a formatação %wt, onde w é o número de caracteres que se deseja imprimir e t é uma das seguintes opções:

• c = caractere; • s = string ou caractere; • u = inteiro sem sinal; • x = inteiro em formato hexadecimal com letras minúsculas; • X = inteiro em formato hexadecimal com letras maiúsculas; • d = inteiro decimal com sinal; • i = inteiro decimal com sinal; • o = octal sem sinal; • e = ponto flutuante em formato exponencial; • f = ponto flutuante em formado decimal; • Lx = hexadecimal longo (16 ou 32 bits) com letras minúsculas; • LX = hexadecimal longo (16 ou 32 bits) com letras maiúsculas; • Lu = decimal longo (16 ou 32 bits) sem sinal; • Ld = decimal longo (16 ou 32 bits) com sinal; • % = símbolo de porcentagem;

Page 11: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 65

Para que todos os caracteres a serem impressos na janela Terminal I/O não fiquem na mesma linha, são utilizados os caracteres especiais de barra invertida, que são:

• \b = retrocesso (backspace); • \f = alimentação de formulário; • \n = nova linha; • \r = retorno do carro; • \t = tabulação horizontal; • \” = aspas duplas; • \’ = aspas simples; • \0 = nulo; • \\ = barra invertida; • \v = tabulação vertical; • \a = alerta (beep); • \N = constante octal, onde N é o número em octal; • \xN = constante hexadecimal, onde N é o número em hexadecimal;

Agora observe o programa exemplo E-0-2: //****************************************************************************** // Exemplo de uso da função scanf // // Alessandro Ferreira da Cunha // Tech Training - Engenharia e Treinamentos // Janeiro 2009 // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> void main() { WDTCTL = WDTPW+WDTHOLD; // Stop WDT char TECLA; // VARIÁVEL LOCAL! SERÁ ACESSADA APENAS PELA FUNÇÃO MAIN for ( ; ; ) { printf("DIGITE UMA TECLA... \n \n "); scanf("%c",&TECLA); printf("SUA TECLA É %c!\n \n",TECLA); } }

A novidade aqui é o comando scanf. Enquanto o comando printf, mostrado no exemplo anterior, emula obenvio de dados pela porta serial do MSP430, o scanf emula o recebimento destes dados, também pela porta serial. Isto também será possível visualizar através do Terminal I/O, acessível em: View Terminal I/O. Assim como no comando anterior, para que ele funcione também é necessário incluir a biblioteca padrão stdio.h

Page 12: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 66

O formato do comando scanf é:

scanf (string, variável);

scanf (“%d”, contador);

Tendo as mesmas características e controladores vistos no printf.

11.2.2. Modificadores de acesso Além das declarações como global ou local, as variáveis podem receber dois tipos de modificadores de acesso, que especificam a forma como o compilador irá acessar o conteúdo das variáveis:

• const: determina que a variável será tratada como uma constante, não podendo ser modificada ou alteradas durante a execução do programa. Faz, então, com que a variável passe a ter um valor fixo, pré-estabelecido durante a declaração da variável.

• volatile: utilizado para indicar ao compilador que a variável por ele indicada pode ter seu conteúdo alterado a qualquer momento.

volatile unsigned int tempo = 100;

11.2.3. Modificadores de armazenamento

Indicam como o compilador irá tratar o armazenamento das variáveis. São quatro tipos:

• auto: serve para declarar que uma variável é local. Porém, todas as variáveis declaradas internamente já são locais. Com isto, este modificador de armazenamento quase nunca é utilizado.

• extern: utilizado para fazer referência a outras variáveis globais que foram declaradas em outros módulos do programa. Isto é muito útil quando se tem programas extensos onde módulos cuidam de funcionamentos específicos e precisam passar parâmetros para outras partes do programa.

• static: indica que a variável ocupará uma posição permanente de memória. Isto também ocorre quando uma variável é declarada de modo global. Mas numa declaração de static, a variável é reconhecida apenas localmente, dentro da função em que foi criada. Se o modificador de armazenamento static for aplicado a uma variável que já é global, isto fará com que ela seja reconhecida apenas pelo programa em que está inserida. Caso haja interação deste programa com outros externos, esta variável não estará acessível.

• register: faz com que o compilador tente gravar esta variável diretamente em um dos registradores que tem acesso direto a CPU do microcontrolador, ao invés de armazená-la em uma posição de memória RAM. Com isto, ganha-se em velocidade de processamento.

static volatile unsigned int tempo = 100;

Page 13: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 67

11.3. Operadores

11.3.1. Operador atribuição

É utilizado para atribuir um determinado valor a uma variável. Seu símbolo é o “ = ” e alguns exemplos de atribuição são mostrados a seguir:

unsigned int x, y;

x = 10;

y = x;

A atribuição é sempre avaliada da direita para a esquerda. Isto significa que ao final deste programa o valor da variável y será igual a 10.

11.3.2. Operadores aritméticos Indica ao compilador que ele deve fazer determinada operação aritmética entre duas variáveis. São os seguintes:

Um exemplo de utilização pode ser visto no trecho de programa abaixo:

unsigned int x, y, z, w; x = 10; y = x ++; z = y --; w= x + y;

11.3.3. Operadores relacionais

São utilizados em testes condicionais para determinar a relação existente entre os dados:

Page 14: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 68

11.3.4. Operadores lógicos

São utilizados para fazer conjunções, disjunções ou negações entre elementos durante um teste condicional.

11.3.5. Operadores lógicos bit a bit

11.3.6. Operadores de memória, ou de ponteiro

Os ponteiros serão tratados em detalhes no estudo dos dados avançados. É possível dizer que este é um dos pilares fundamentais da linguagem C e portanto gastaremos algumas horas do nosso treinamento para explicá-los em detalhes. Por hora, vamos apenas conhecer quais são os símbolos utilizados como operadores de memória, ou de ponteiros, e suas funcionalidades. As aplicações serão desenvolvidas mais a frente. São dois os símbolos:

• & endereço do operando. É um operador unário utilizado para retornar o endereço de memória do seu operando. Isto significa que se escrevermos:

endereço_a = &a;

teremos que a variável “endereço_a” conterá o endereço em que está armazenada a variável a.

• * conteúdo do endereço apontado pelo operando. Este é um operador unário utilizado para retornar o conteúdo da posição de memória endereçada pelo operando que segue. Isto significa que se escrevermos:

a = *endereço_a;

teremos que o valor armazenado no local apontado pela variável “endereço_a” seja atribuído à variável a.

Page 15: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 69

11.3.7. Outros operadores

Outros operadores, que não se encaixam em nenhum dos tipos citados anteriormente, mas que podem ser utilizados em linguagem C são:

• ? (ponto de interrogação) Operador ternário condicional: pode fazer um teste condicional, substituindo o comando IF. Sua forma geral é:

variável = expressão1 ? expressão2 : expressão3;

Ele funciona da seguinte maneira: avalie a expressão1. Se ela for verdadeira, atribua a variável o valor da expressão2. Caso a expressão1 seja falsa, então a variável recebe o valor da expressão3.

• , (vírgula) Separador de expressões: é utilizado para enfileirar duas ou mais expressões. Sua forma geral é:

variável = (expressão1 , expressão2 , expressão3);

Uma aplicação, como a seguir, resulta em y = 5.

y = ( x = 0 , x + 5 );

• . (ponto) Separador de estruturas: é utilizado em estruturas de dados

como separador dos elementos e será estudado quando abordarmos os tipos de dados avançados.

• -> (seta) Ponteiro de elementos de estruturas: é utilizado em estruturas de dados como ponteiro dos elementos e será estudado quando abordarmos os tipos de dados avançados.

• (tipo) Operador modelagem de dado: é possível forçar que uma expressão seja de determinado tipo utilizando um cast cujo formato geral é:

(tipo) expressão;

Onde tipo é qualquer um dos tipos de dados permitidos pela linguagem C e expressão é a que se quer que resulte no tipo especificado. Por exemplo: para realizar um cálculo e obrigar que o resultado seja apresentado em ponto flutuante, pode-se utilizar o seguinte cast:

unsigned int x, y;

x = 10;

y = (float) x / 2;

Page 16: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 70

• sizeof Retorna o tamanho de uma variável: para ter um melhor

controle da quantidade de memória utilizada, pode-se aplicar o operador sizeof a qualquer variável. Isto fará retornar qual o tamanho que esta variável ocupa em bytes.

12. EXERCÍCIO 1: Operadores, tipos e variáveis

12.1. Calculadora básica (E-1-1) Escreva um programa em que o usuário entre com dois números e seja realizada uma operação matemática básica (multiplicação), mostrando o resultado na tela. Este programa deve rodar dentro de um loop infinito no formato for ( ; ; );. O programa deve conter uma mensagem no Terminal I/O solicitando que o usuário digite o primeiro número. Depois uma mensagem solicita a digitação de um segundo número. Finalmente, o resultado da multiplicação é mostrado em uma nova linha do Terminal I/O.

12.2. Conversor de moeda do dia (E-1-2) Escreva um programa em que o usuário entre com a cotação do dólar do dia, digite qual é a quantidade de dólares que quer converter e seja apresentado na tela do Terminal I/O apresente o valor convertido em reais.

12.3. Calcular a idade de um usuário – I (E-1-3) Escreva um programa em que o usuário entre com a data de nascimento no formato na seguinte seqüência:

• DIA (DD); • MÊS (MM); • ANO (AAAA).

Na seqüência, o usuário deve digitar a data de hoje, entrando com os valores de dia, mês e ano no mesmo formato. O programa deve, então, calcular a idade do usuário, informando a idade em ANOS, cujo valor deve ser um inteiro.

12.4. Calcular a idade de um usuário – II (E-1-4) Modifique o programa anterior de modo que seja mostrado na tela também o valor da idade em DIAS e MESES.

Page 17: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 71

13. Declarações de controle e repetição As declarações de controle e repetição são algumas das estruturas mais importantes da linguagem C. Elas é que garantem um fluxo de programa capaz de tomar decisões e desviar o programa de acordo com determinadas regras. Veremos neste treinamento estas estruturas, definidas pelo padrão ANSI C e como utilizá-las.

• Seleção (condicional): if e switch; • Iteração (laço): while, for e do-while; • Desvio (salto): break, continue, goto e return; • Rótulo: case, default e label;

13.1. Verdadeiro ou Falso em linguagem C

Diversos destes comandos de controle e repetição acontecem apenas após um teste condicional, onde é verificado o status de VERDADEIRO ou FALSO de uma variável. É necessário entender como o C observa esta condição para compreender perfeitamente como as decisões são tomadas:

• VERDADEIRO: é considerada uma condição verdadeira para uma variável quando esta tem qualquer valor diferente de zero, inclusive valores negativos.

• FALSO: é considerada uma condição falsa para uma variável quando esta tem valor igual a zero.

13.2. If

if (condição) comandoA; {else comandoB}

if (condição)

{

comandoA;

comandoB;

comandoC;

}

else

{

comandoD;

comandoE;

comandoF

}

Page 18: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 72

Veja um exemplo de utilização da função if rodando o programa exemplo E-0-3: //****************************************************************************** // Exemplo de uso da função if // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> #include <stdlib.h> void main() { WDTCTL = WDTPW+WDTHOLD; // Stop WDT for ( ; ; ) // cria um loop infinito { int numero; // número mágico int palpite; // chute do usuário numero = rand(); // gera um número aleatório printf("ADIVINHE QUAL É O NÚMERO... \n \n "); scanf("%d",&palpite); if (palpite == numero) printf ("****CERTO!!!****\n\n"); else printf ("### ERRADO ###\n\n"); } }

Note que para conseguir gerar um número randômico, foi necessário incluir mais uma biblioteca de funções, a stdlib.h.

13.2.1. If – Else – If comandos aninhados

if (condição1) comandoA;

else if (condição2) comandoB;

else if (condição3) comandoC;

//****************************************************************************** // Exemplo de uso da função if aninhada // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> #include <stdlib.h> void main() { WDTCTL = WDTPW+WDTHOLD; // Stop WDT int numero; // número mágico int palpite; // chute do usuário numero = rand(); // gera um número aleatório for ( ; ; ) // cria um loop infinito { printf("ADIVINHE QUAL É O NÚMERO... \n \n "); scanf("%d",&palpite); if (palpite == numero) printf ("****CERTO!!!****\n\n"); else { printf ("### ERRADO ###\n\n"); if (palpite < numero) printf (" --- valor alto --- \n\n"); else printf (" +++ valor baixo +++ \n\n"); } } }

Page 19: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 73

13.2.2. Uma alternativa: o comando ?

variável = expressão1 ? expressão2 : expressão3;

Ele funciona da seguinte maneira: avalie a expressão1. Se ela for verdadeira, atribua a variável o valor da expressão2. Caso a expressão1 seja falsa, então a variável recebe o valor da expressão3.

13.3. Switch O comando switch difere do comando if porque somente pode testar igualdades. O comando if pode avaliar uma expressão lógica ou relacional.

switch (variável)

{

case constante1:

comandoA;

comandoB;

....

break;

case constante2:

comandoC;

comandoD;

....

break;

....

default:

comandoE;

comandoF;

....

}

Veja no exemplo E-0-5 como utilizar o comando switch case:

Page 20: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 74

//****************************************************************************** // Exemplo de uso da função switch case // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> void main() { WDTCTL = WDTPW+WDTHOLD; // Stop WDT int digitado; // digitado for ( ; ; ) // cria um loop infinito { printf("DIGITE UM NÚMERO ENTRE 0 E 5: \n \n "); scanf("%d",&digitado); switch (digitado) { case 0: printf("O NÚMERO DIGITADO FOI %d ! \n \n ",digitado); break; case 1: printf("O NÚMERO DIGITADO FOI %d ! \n \n ",digitado; break; case 2: printf("O NÚMERO DIGITADO FOI %d ! \n \n ",digitado; break; case 3: printf("O NÚMERO DIGITADO FOI %d ! \n \n ",digitado; break; case 4: printf("O NÚMERO DIGITADO FOI %d ! \n \n ",digitado; break; case 5: printf("O NÚMERO DIGITADO FOI %d ! \n \n ",digitado; break; default: printf("O NÚMERO DIGITADO NÃO ESTÁ ENTRE 0 E 5! \n \n "); } } }

13.4. Laço for (para)

for (inicialização ; condição ; incremento) comando;

for (inicialização ; condição ; incremento)

{

comandoA;

comandoB;

....

}

Veja no exemplo E-0-6 como utilizar o laço for: //****************************************************************************** // Exemplo de uso da laço for // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> void main() { WDTCTL = WDTPW+WDTHOLD; // Stop WDT int conta; for (conta = 0 ; conta <= 10 ; conta++) printf("%u\r\n",conta); }

Page 21: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 75

13.4.1. Laço infinito

for ( ; ; );

13.4.2. Cláusula break no comando for

Como sair de um laço infinito? Execute o programa E-0-7 e verifique seu efeito em um laço infinito: //****************************************************************************** // Exemplo de uso do comando BREAK em um laço for // // Alessandro Ferreira da Cunha // Tech Training - Engenharia e Treinamentos // Janeiro 2009 // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> void main() { WDTCTL = WDTPW+WDTHOLD; // Stop WDT char caractere; for ( ; ; ) { printf ("digite algo \n"); scanf("%c",&caractere); //pega um caractere if (caractere == 'A') break; //sai do laço } printf ("você digitou um A"); }

13.4.3. Cláusula continue no comando for

Qual o efeito de trocar uma cláusula break por uma cláusula continue? Execute o programa E-0-8 e verifique seu efeito: //****************************************************************************** // Exemplo de uso da cláusula CONTINUE em um laço for // // Alessandro Ferreira da Cunha // Tech Training - Engenharia e Treinamentos // Janeiro 2009 // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> void main() { WDTCTL = WDTPW+WDTHOLD; // Stop WDT int inicio, fim, x; printf ("digite o início \n"); scanf("%d",&inicio); printf ("digite o fim \n"); scanf("%d",&fim); for ( x = inicio ; x <= fim ; x++ ) { if ( x == fim) continue; printf("%u\r\n",x); } printf (" --- ACABOU --- "); }

Page 22: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 76

13.5. Laço while (enquanto)

while (condição) comando;

while (condição)

{

comandoA;

comandoB;

....

}

Veja no exemplo E-0-9 como utilizar o laço while: //****************************************************************************** // Exemplo de uso laço while // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> void main() { WDTCTL = WDTPW+WDTHOLD; // Stop WDT int i; i = 1; while(i < 6) { printf ("ainda está em %d \n",i); i++; } printf ("acabou"); }

13.5.1. Cláusulas break e continue no laço while

As cláusulas break e continue podem ser utilizadas também no comando while, tendo o mesmo efeito que se obteve de seu uso no laço for. Veja o exemplo E-0-10. //****************************************************************************** // Exemplo de uso das cláusulas break e continue no laço while // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> void main() { WDTCTL = WDTPW+WDTHOLD; // Stop WDT int x, y, w, z; w = 0 ; printf("ENTRE COM UM NÚMERO \n"); scanf("%d",&x); printf("ENTRE COM OUTRO NÚMERO \n"); scanf("%d",&y); printf("ENTRE COM A QUANT. DE IMPRESSÕES \n"); scanf("%d",&z); while (w < z) { if (x == 0 || y == 0) break; w++; x = x * y; printf("A MULTIPLICAÇÃO É %d \n",x); if (x < 1000) continue; printf(" ACABOU "); } }

Page 23: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 77

13.5.2. Laço infinito

while (1)

{

......

}

13.6. Laço do-while (faça-enquanto)

do comando while (condição);

do

{ comandoA; comandoB; .... } while (condição);

Veja no exemplo E-0-11 como utilizar o laço do-while: //****************************************************************************** // Exemplo de uso laço do-while // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> /* PROGRAMA PARA LANÇAMENTO DE FOGUETES DA NASA. */ void main() { WDTCTL = WDTPW+WDTHOLD; // Stop WDT int start; printf("ENTRE COM O TEMPO PARA LANÇAMENTO \n"); scanf("%d",&start); /* O LAÇO DE CONTAGEM REGRESSIVA */ do { printf("FALTAM %d SEGUNDOS \n",start); start--; } while(start>0); printf("Zero!\n FOGO!!\n"); }

13.7. Usar um laço while (enquanto) ou um laço for (para)?

Os dois laços, while e for, tem várias similaridades. Na grande maioria das situações o mesmo problema poderá ser resolvido tanto com um tipo de laço quanto com o outro. Para uma melhor compreensão do que estamos dizendo, vamos fazer uma equivalência entre os parâmetros que são ajustados para fazer rodar um laço for e os mesmos parâmetros para fazer exatamente o mesmo efeito, mas com um laço while.

Page 24: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 78

for ( A ; B ; C) printf (“%d\t”,i);

A;

while (B)

{

printf (“%d\t”,i);

C;

}

A escolha por um ou outro modelo dependerá apenas do estilo do programador. A forma for é mais compacta. Já a forma while permite uma visualização mais fácil de todas as partes envolvidas. Enfim: ambos geram os mesmos efeitos na linguagem C pura e podem ser considerados iguais pelo programador. Já a sua aplicação em microcontroladores deve ser analisada com cuidado. Dependendo do compilador e da forma como o laço é gerado, pode ser obtido programas em assembly maiores ou menores para executar a mesma tarefa. A velocidade com que o programa executa o laço também é influenciada pelo estilo de conversão que o compilador fará para cada um deles. Um excelente exercício é modificar as opções de otimização do IAR (por velocidade ou por tamanho de código) e compilar programas com resultados de saída iguais mas que façam uso de laços diferentes, observando o comportamento do código assembly gerado pelo compilador.

Page 25: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 79

13.8. Tudo junto?

Veja no exemplo E-0-12 todos os conceitos deste capítulo reunidos em um único programa: //****************************************************************************** // Exemplo COM TUDO JUNTO // // Alessandro Ferreira da Cunha // Tech Training - Engenharia e Treinamentos // Janeiro 2009 // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> /* Controle de venda no lobby de um cinema */ void main() { WDTCTL = WDTPW+WDTHOLD; // Stop WDT char c; int done; float total = 0; printf("Por favor, escolha suas opções:\n"); printf("1 -> Refrigerante.\n"); printf("2 -> Balas.\n"); printf("3 -> Cachorro Quente.\n"); printf("4 -> Pipocas.\n"); printf("= -> Fechar o pedido.\n"); printf("Suas escolhas são:\n"); done = 0; while(!done) { scanf("%c",&c); switch(c) { case '1': printf("Refrigerante\tR$8.00\n"); total+=8; break; case '2': printf("Balas\t\t$R5.50\n"); total+=5.5; break; case '3': printf("Cachorro Quente\t\tR$10.00\n"); total+=10; break; case '4': printf("Pipocas\t\t$7.50\n"); total+=7.5; break; case '=': printf("= Total R$%.2f\n",total); printf("Por favor passe o cartão.\n"); done=1; break; default: printf("Seleção inadequada.\n"); } /* end switch */ } /* end while */ }/* end main */

13.9. Comando GOTO (vá para)

goto label;

Page 26: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 80

14. EXERCÍCIO 2: Declarações de controle e repetição

14.1. Configuração básica dos I/Os As seguintes configurações devem ser observadas para fazer os exercícios propostos: REGISTRADOR DE ENTRADA (Input Register PxIN) Cada bit colocado em um pino do microcontrolador tem seu valor refletido neste registrador. Isto ocorre quando a porta está configurada para entrada, sendo válida as seguintes informações: Bit = 0: A entrada está em nível lógico baixo (0 V). Bit = 1: A entrada está em nível lógico alto (+Vcc). REGISTRADOR DE SAÍDA (Output Registers PxOUT) Cada bit escrito neste registrador refletirá em um valor de tensão no pino de saída. Isto ocorre quando a porta está configurada para saída, sendo válida as seguintes informações:. Bit = 0: A saída será levada a nível lógico baixo (0 V). Bit = 1: A saída será levada a nível lógico alto (+Vcc). REGISTRADOR DE DIREÇÃO (Direction Registers PxDIR) Este registrador indicará se um pino de I/O será utilizado como entrada ou saída, de acordo com a seguinte configuração: Bit = 0: A porta será configurada como entrada. Bit = 1: A porta será configurada como saída. REGISTRADORES DE PULL UP / PULL DOWN (Pullup/Pulldown Resistor Enable Registers PxREN (MSP430x47x only)) Apenas nos dispositivos das famílias MSP430x47x todas as portas tem resistores programáveis de pull-up/down, cuja habilitação ou não é feita do seguinte modo: Bit = 0: Os resistores estarão desabilitados. Bit = 1: Os resistores estarão habilitados. REGISTRADORES DE SELEÇÃO DE FUNÇÃO (Function Select Registers PxSEL) Como os pinos de um microcontrolador pode ter múltiplas funções, hora funcionando como terminal de I/O, hora como interface de algum periférico, é necessário ajustar qual função será realizada a cada momento. Isto é feito de acordo com os seguintes ajustes: Bit = 0: O terminal funcionará como um I/O. Bit = 1: O terminal funcionará como um periférico. Nota: as interrupções por P1 e P2 são desabilitadas quando PxSEL = 1

Page 27: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 81

Identifique no diagrama elétrico da Experimenter Board, mostrado no item 9, as seguintes conexões, envolvendo pinos do MSP430FG4618 e hardwares externos:

a) Botão S1 pino P1.0; b) Botão S2 pino P1.1; c) LED1 pino P2.1;

d) LED2 pino P2.2; e) LED4 pino P5.1.

Com estas informações escrevam programas em linguagem C de modo que aconteçam as operações solicitadas nos itens a seguir.

14.2. 1 botão e 1 Led (E-2-1) Ao pressionar o botão S1 deve acender o LED1. Se o botão não estiver pressionado, o LED1 deve se manter apagado.

14.3. 2 botões e 2 Leds (E-2-2) Ao pressionar o botão S1 deve apagar o LED1. Se o botão S1 não estiver pressionado, o LED1 deve se manter aceso. Ao mesmo tempo se o botão S2 for pressionado, o LED2 deve se apagar. Se o botão S2 não estiver pressionado, o LED2 deve se manter aceso.

14.4. 1 botão, 1 Led e temporização simples (E-2-3) Ao pressionar o botão S2 deve acender o LED1, que deve permanecer aceso por alguns milissegundos (tempo suficiente para perceber a retenção da informação). Se o botão não estiver pressionado, o LED1 deve se manter apagado.

14.5. 2 botões, 2 Leds e temporização simples (E-2-4) Ao pressionar o botão S2 deve apagar o LED1, o que deve acontecer por alguns milissegundos (tempo suficiente para perceber a retenção da informação). Se o botão não estiver pressionado, o LED1 deve se manter aceso. Ao mesmo tempo, se o botão S1 estiver pressionado o LED2 deve ficar apagado, o que também deve acontecer por alguns milissegundos (tempo suficiente para perceber a retenção da informação). Se o botão não estiver pressionado, o LED2 deve se manter aceso

Page 28: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 82

15. Diretivas e funções do Compilador IAR Além de todos os comandos, controles e funções da linguagem C, tem-se ainda uma série de diretivas que são intrínsecas ao Compilador IAR. Para estudá-las, o melhor caminho são os arquivos de HELP que acompanham o compilador, além dos arquivos USER GUIDE, em formato .pdf, que podem ser acessados diretamente através do menu Help do compilador. Dentre estes arquivos destacamos alguns que farão parte do CD que compõe o material didático deste treinamento. Apesar da grande quantidade de informação que estes arquivos fornecem, é interessante tê-los sempre a mão, como uma fonte de consulta, toda vez que se está desenvolvendo um novo programa. Dentre as diversas diretivas e funções do compilador IAR, vamos listar dois tipos, que serão utilizados ao longo do treinamento: as PRAGMAS e as FUNÇÕES INTRINSECAS. As demais funções deverão ser consultadas pelos estudantes diretamente nos arquivos.

15.1. Pragmas Pragmas são um modo de passar informações especiais para o compilador e para adicionar extensões específicas de vendedor à biblioteca do microcontrolador, garantindo assim sua portabilidade entre diversos chips. As diretivas #pragma são definidas pelo ISO/ANSI C e fazem, entre outras coisas, o controle do comportamento do compilador. Por exemplo, ela pode determinar que quantidade de memória é alocada para cada variável ou função, permitir o uso de palavras chaves, fornecer mensagens de alerta, etc. A lista a seguir mostra todas as diretivas #pragma que estão disponíveis no IAR, para a família MSP430. É necessário o uso do pré processador #pragma para que estas diretivas sejam entendidas pelo compilador e passem a ser tratadas como tal.

Page 29: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 83

Pragma directive Description

basic_template_matching Makes a template function fully memory-attribute aware

bis_nmi_ie1 Generates a BIS instruction just before the RETI instruction

bitfields Controls the order of bitfield members

constseg Places constant variables in a named segment

data_alignment Gives a variable a higher (more strict) alignment

dataseg Places variables in a named segment

diag_default Changes the severity level of diagnostic messages

diag_error Changes the severity level of diagnostic messages

diag_remark Changes the severity level of diagnostic messages

diag_suppress Suppresses diagnostic messages

diag_warning Changes the severity level of diagnostic messages

include_alias Specifies an alias for an include file

inline Inlines a function

language Controls the IAR Systems language extensions

location Specifies the absolute address of a variable, or places groups of functions or variables in named segments

message Prints a message

no_epilogue Performs a local return sequence

object_attribute Changes the definition of a variable or a function

optimize Specifies the type and level of an optimization

pack Specifies the alignment of structures and union members

required Ensures that a symbol that is needed by another symbol is included in the linked output

rtmodel Adds a runtime model attribute to the module

segment Declares a segment name to be used by intrinsic functions

type_attribute Changes the declaration and definitions of a variable or function

vector Specifies the vector of an interrupt or trap function

Page 30: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 84

15.2. Funções intrínsecas

São um conjunto de funções predefinidas que estão disponíveis no compilador IAR. Elas permitem um acesso direto ao processamento de baixo nível e podem ser extremamente úteis em, por exemplo, rotinas que envolvam tempo crítico de execução. Para serem reconhecidas, é necessário acrescentar o arquivo intrinsics.h, através de um comando include. Note que o nome destas funções sempre iniciam-se com um duplo undeline.

Intrinsic function Description

__bcd_add_type Performs a binary coded decimal operation

__bic_SR_register Clears bits in the SR register

__bic_SR_register_on_exit Clears bits in the SR register when an interrupt or monitor function returns

__bis_SR_register Sets bits in the SR register

__bis_SR_register_on_exit Sets bits in the SR register when an interrupt or monitor function returns

__data16_read_addr Reads data to a 20-bit SFR register

__data16_write_addr Writes data to a 20-bit SFR register

__data20_read_type Reads data which has a 20-bit address

__data20_write_type Writes data which has a 20-bit address

__delay_cycles Provides cycle accurate code size minimized delay functionality

__disable_interrupt Disables interrupts

__enable_interrupt Enables interrupts

__even_in_range Makes switch statements rely on the specified value being even and within the specified range

__get_interrupt_state Returns the interrupt state

__get_R4_register Returns the value of the R4 register

__get_R5_register Returns the value of the R5 register

__get_SP_register Returns the value of the stack pointer

__get_SR_register Returns the value of the SR register

Page 31: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 85

__get_SR_register_on_exit Returns the value that the processor status register will have when the current interrupt or monitor function returns

__low_power_mode_n Enters a MSP430 low power mode

__low_power_mode_off_on_exit Turns off low power mode when a monitor or interrupt function returns

__no_operation Inserts a NOP instruction

__op_code Inserts a constant into the instruction stream

__set_interrupt_state Restores the interrupt state

__set_R4_register Writes a specific value to the R4 register

__set_R5_register Writes a specific value to the R5 register

__set_SP_register Writes a specific value to the SP register

__swap_bytes Executes the SWPB instruction

16. ECONOMIZANDO ENERGIA PARA PISCAR O LED Ao resolver os exercícios propostos anteriormente não fizemos uso da principal característica do MSP430, que é o baixo consumo de energia. Execute o programa exemplo E-0-13 em seu kit. Veja o seu funcionamento. //****************************************************************************** // MSP430xG46x Demo - Software Port Interrupt on P1.4 from LPM4 // // Description: A hi/low transition on P1.4 will trigger P1_ISR which, // toggles P5.1. Normal mode is LPM4 ~ 0.1uA. LPM4 current can be measured // with the LED removed, all unused P1.x/P2.x configured as output or inputs // pulled high or low, and ensure the P2.0 interrupt input does not float. // ACLK = 32.768kHz, MCLK = SMCLK = default DCO // // K. Quiring/ M. Mitchell // Texas Instruments Inc. // October 2006 // Built with IAR Embedded Workbench Version: 3.41A //****************************************************************************** #include <msp430xG46x.h> void main(void) { WDTCTL = WDTPW+WDTHOLD; // Stop WDT P5DIR |= 0x002; // P5.1 output P1IE |= 0x010; // P1.4 Interrupt enabled P1IES |= 0x010; // P1.4 hi/low edge P1IFG &= ~0x010; // P1.4 IFG Cleared _BIS_SR(LPM4_bits + GIE); // LPM4, enable interrupts } // Port 1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port1_ISR (void) { P5OUT ^= 0x02; // P5.1 = toggle P1IFG &= ~0x010; // P1.4 IFG Cleared }

Page 32: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 86

17. Interrupções As interrupções no MSP430 são fixas e definidas pelo arranjo modular mostrado na figura abaixo.

Quanto mais próximo for um módulo da CPU/NMIRS, maior a sua prioridade em interromper o sistema. Esta prioridade define quem será tratado primeiramente caso ocorram duas interrupções simultaneamente. Para o MSP430 são considerados três tipos de interrupção:

• Reset do sistema; • NMI: interrupções não mascaráveis; • Interrupções mascaráveis.

E funcionam de acordo com a lógica mostrada na figura a seguir.

17.1. Reset do sistema O circuito de reset do sistema é mostrado na figura a seguir. Ele fornece como saída duas fontes de reset: o power-on reset (POR) e o power-up clear (PUC). Diferentes fontes de eventos e sinais podem disparar o circuito de reset do sistema.

Page 33: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 87

O POR é um reset do dispositivo. Um POR só pode ser gerado caso ocorra um destes três eventos:

• O dispositivo é alimentado (Powering up); • Um nível baixo (0 V) é inserido no terminal RST/NMI, quando este pino está

configurado para o modo de reset; • Um baixo nível de tensão é detectado pelo módulo SVS, quando PORON = 1.

Um PUC sempre é gerado quando um POR é gerado, porém um POR não é gerado quando acontece um PUC. Um PUC pode ser disparado pelos seguintes eventos:

• Um sinal POR; • Expirou o tempo estipulado pelo Watchdog timer quando estava em modo watchdog; • Houve uma violação de segurança do Watchdog timer; • Houve uma violaçào de segurança no acesso a memória Flash.

O Brownout Reset (BOR) é um hardware capaz de detectar se existem variações na tensão de alimentação do dispositivo, resetando-o a fim de evitar problemas de funcionamento.

Page 34: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 88

17.2. NMI – Interrupções não mascaráveis

Estas três interrupções não podem ser desabilitadas pelo bit de controle geral de interrupções (GIE). Elas têm bits específicos para isto (ACCVIE, NMIIE, OFIE). Quando uma destas interrupções é aceita, todas as demais tem o seu bit de habilitação resetado. O programa dará um salto em sua execução para o endereço armazenado no vetor de interrupção não mascarável (0FFFCh). Será necessário que o software do usuário set novamente os bits destas interrupções para que elas possam ocorrer novamente. As interrupções não mascaráveis são:

• Um borda de descida/subida no pino RST/NMI pin, quando este é configurado para o modo NMI;

• Ocorre um falha no oscilador; • Ocorre uma violação de acesso a memória flash.

17.3. Interrupções mascaráveis

As interrupções mascaráveis são geradas por todos os periféricos que possuem capacidade de interrupção, incluindo o watchdog timer. Cada fonte de interrupção mascarável tem um bit que habilita ou desabilita seu funcionamento, sendo que existe ainda um bit de controle geral, chamado de GIE (General Interrupt Enable), presente no status register (SR).

17.4. O processamento de uma interrupção Quando uma interrupção é solicitada por um periférico, é necessário que os bits de habilitação individual e geral (GIE) estejam setados. Isto fará com que o programa sofra um desvio para uma rotina de interrupção.

Page 35: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 89

17.4.1. Entrada em uma interrupção

A latência para o tratamento de um interrupção dura 6 ciclos de máquina, começando pela aceitação de uma interrupção e terminando com a execução da primeira instrução contida na rotina de atendimento de interrupção. A execução lógica é descrita a seguir:

1) Qualquer instrução que esteja sendo executada é finalizada;

2) O valor do PC, que aponta para a próxima instrução que deveria ser executada, é salvo na pilha (pushed onto the stack);

3) O valor do SR é salvo na pilha (pushed onto the stack);

4) A interrupção que tiver a maior prioridade é selecionada, caso multiplas

interrupções ocorram simultaneamente;

5) Uma requisição de interrupção reseta o flag de interrupção. As demais interrupções permanecem com seus flags setados;

6) O registrador SR tem todos os seus bits zerados, com excessão do SCG0, que

não é alterado. Isto retira o microcontrolador de qualquer LPM em que ele se encontra. Como o GIE também é zerado, as próximas interrupções ficam desabilitadas.

7) O conteúdo do vetor de interrupção correspondente a quem fez a solicitação é carregado no PC, que passará a executar o programa a partir do que houver escrito ali.

17.4.2. Saída de uma interrupção

Toda interrupção é terminada quando uma instrução RETI (return from an interrupt service routine) é encontrada. Este retorno gasta 5 ciclos de máquina para executar as seguintes ações:

1) O registrador SR é restaurado da pilha (pops from the stack) com todos os valores ajustados previamente (GIE, CPUOFF, etc.);

2) O valor do PC é restaurado da pilha (pops from the stack) e inicia a execução no ponto exato em que parou ao ser interrompido.

Page 36: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 90

O aninhamento de interrupções é habilitado quando, durante o tratamento de uma interrupção, o usuário seta o bit GIE. Neste caso, havendo uma nova interrupção os procedimentos mostrados ocorrerão novamente, seguindo a ordem de prioridades de atendimento de interrupções.

17.5. Os vetores de interrupção Os vetores de interrupção tem um endereçamento fixo e conhecido em todos os dispositivos das famílias MSP430, indo de 0FFFFh até 0FFC0h. Nestes dados, que tem 16 bits, são salvos os endereços onde estarão os programas que farão o atendimento as rotinas de interrupção. Dependendo do número de periféricos, os dispositivos MSP430 podem ter mais ou menos vetores de interrupção, por isto é sempre necessária uma consulta ao datasheet de cada dispositivo.

Page 37: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 91

17.5.1. Vetores de interrupção na família 2 (MSP430F2013)

NOTES: 1. Um reset é gerado toda vez que a CPU tenta carregar um endereço no PC que esteja for a do range de memória disponível no dispositivo. 2. Fonte de múltiplos flags. 3. A flag de interrupção é alocada no módulo. 4. Não mascarável: o bit de interrupção individual pode ser desabilitado por um evento de interrupção, mas geralmente isto não é possível. 5. Os endereços de vetores de interrupção entre 0FFDEh e 0FFC0h não são utilizados neste dispositivo, podendo ser utilizado como área de código regular, onde será armazenado o programa.

Page 38: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 92

17.5.2. Declaração dos Vetores de interrupção no MSP430F2013

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

* Interrupt Vectors (offset from 0xFFE0)

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

#define PORT1_VECTOR (2 * 2u) /* 0xFFE4 Port 1 */

#define PORT2_VECTOR (3 * 2u) /* 0xFFE6 Port 2 */

#define USI_VECTOR (4 * 2u) /* 0xFFE8 USI */

#define SD16_VECTOR (5 * 2u) /* 0xFFEA Sigma Delta ADC */

#define TIMERA1_VECTOR (8 * 2u) /* 0xFFF0 Timer A CC1, TA */

#define TIMERA0_VECTOR (9 * 2u) /* 0xFFF2 Timer A CC0 */

#define WDT_VECTOR (10 * 2u) /* 0xFFF4 Watchdog Timer */

#define NMI_VECTOR (14 * 2u) /* 0xFFFC Non-maskable */

#define RESET_VECTOR (15 * 2u) /* 0xFFFE Reset [Highest Priority] */

17.5.3. Vetores de interrupção na família 4 (MSP430FG4618)

Page 39: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 93

NOTES: 1. Fonte de múltiplos flags. 2. A flag de interrupção é alocada no módulo. 3. Um reset é gerado toda vez que a CPU tenta carregar um endereço no PC que esteja for a do range de memória disponível no dispositivo. (Não mascarável: o bit de interrupção individual pode ser desabilitado por um evento de interrupção, mas geralmente isto não é possível. 4. Os endereços de vetores de interrupção entre 0FFDAh e 0FFC0h não são utilizados neste dispositivo, podendo ser utilizado como área de código regular, onde será armazenado o programa. 5. Violação na chave de acesso (KEYV e ACCVIFG), somente são aplicáveis aos dispositivos do tipo F.

17.5.4. Declaração dos Vetores de interrupção no MSP430FG4618 /************************************************************

* Interrupt Vectors (offset from 0xFFC0)

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

#define DAC12_VECTOR (14 * 2u) /* 0xFFDC DAC 12 */

#define DMA_VECTOR (15 * 2u) /* 0xFFDE DMA */

#define BASICTIMER_VECTOR (16 * 2u) /* 0xFFE0 Basic Timer / RTC */

#define PORT2_VECTOR (17 * 2u) /* 0xFFE2 Port 2 */

#define USART1TX_VECTOR (18 * 2u) /* 0xFFE4 USART 1 Transmit */

#define USART1RX_VECTOR (19 * 2u) /* 0xFFE6 USART 1 Receive */

#define PORT1_VECTOR (20 * 2u) /* 0xFFE8 Port 1 */

#define TIMERA1_VECTOR (21 * 2u) /* 0xFFEA Timer A CC1-2, TA */

#define TIMERA0_VECTOR (22 * 2u) /* 0xFFEC Timer A CC0 */

#define ADC12_VECTOR (23 * 2u) /* 0xFFEE ADC */

#define USCIAB0TX_VECTOR (24 * 2u) /* 0xFFF0 USCI A0/B0 Transmit */

#define USCIAB0RX_VECTOR (25 * 2u) /* 0xFFF2 USCI A0/B0 Receive */

#define WDT_VECTOR (26 * 2u) /* 0xFFF4 Watchdog Timer */

#define COMPARATORA_VECTOR (27 * 2u) /* 0xFFF6 Comparator A */

#define TIMERB1_VECTOR (28 * 2u) /* 0xFFF8 Timer B CC1-2, TB */

#define TIMERB0_VECTOR (29 * 2u) /* 0xFFFA Timer B CC0 */

#define NMI_VECTOR (30 * 2u) /* 0xFFFC Non-maskable */

#define RESET_VECTOR (31 * 2u) /* 0xFFFE Reset [Highest Priority] */

Page 40: 055 A 094   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha

Página 94

18. EXERCÍCIO 3: BOTÕES E LEDS EM LOW POWER MODE. Já foi identificado no diagrama elétrico da Experimenter Board, mostrado no item 9, as seguintes conexões, envolvendo pinos do MSP430FG4618 e hardwares externos:

a) Botão S1 pino P1.0; b) Botão S2 pino P1.1; c) LED1 pino P2.1;

d) LED2 pino P2.2; e) LED4 pino P5.1.

Com estas informações faça modificações na seqüência de exercícios 2, de modo que o programa fique em Low Power Mode e apenas saia deste estado para executar ações, fazendo economia de energia e realizando as mesmas atividades anteriores.

18.1. 1 botão e 1 Led (E-3-1) Ao pressionar o botão S1 deve acender o LED1. Se o botão não estiver pressionado, o LED1 deve se manter apagado.

18.2. 2 botões e 2 Leds (E-3-2) Ao pressionar o botão S1 deve apagar o LED1. Se o botão S1 não estiver pressionado, o LED1 deve se manter aceso. Ao mesmo tempo se o botão S2 for pressionado, o LED2 deve se apagar. Se o botão S2 não estiver pressionado, o LED2 deve se manter aceso.

18.3. 1 botão, 1 Led e temporização com Basic Timer 1 (E-3-3) Ao pressionar o botão S2 deve acender o LED1, que deve permanecer aceso por 500 ms. Se o botão não estiver pressionado, o LED1 deve se manter apagado.

18.4. 2 botões, 2 Leds e temporização Basic Timer 1 (E-3-4) Ao pressionar o botão S2 deve apagar o LED1, o que deve acontecer por 500 ms. Se o botão não estiver pressionado, o LED1 deve se manter aceso. Ao mesmo tempo, se o botão S1 estiver pressionado o LED2 deve ficar apagado, o que também deve acontecer por 500 ms. Se o botão não estiver pressionado, o LED2 deve se manter aceso