Você está na página 1de 41

10.

BREVE INTRODUO A LINGUAGEM C


(http://pt.wikipedia.org/wiki/c_(linguagem_de_programaao))

C uma linguagem de programao compilada de propsito geral, estruturada, imperativa,


procedural, de alto nvel, 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 nvel pela prpria definio desse tipo de
linguagem. A programao em linguagens de alto nvel tem como caracterstica no ser
necessrio conhecer o processador, ao contrrio das linguagens de baixo nvel. As
linguagens de baixo nvel esto fortemente ligadas ao processador. A linguagem C permite
acesso de baixo nvel com a utilizao de cdigo Assembly no meio do cdigo fonte. Assim,
o baixo nvel realizado por Assembly e no C. Desde ento, espalhou-se por muitos outros
sistemas, e tornou-se uma das linguagens de programao mais usadas, e influenciou
muitas outras linguagens, especialmente C++, que foi originalmente desenvolvida como uma
extenso para C.

10.1. Histria

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 caractersticas derivaram da linguagem B.

C foi originalmente desenvolvido, para a implementao do sistema UNIX (originalmente


escrito em PDP-7 Assembly, por Dennis Ritchie e Ken Thompson). Em 1973, com a adio
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 no o Assembly, sendo exemplos anteriores, os sistemas: Multics
(escrito em PL/I) e TRIPOS (escrito em BCPL). Segundo Ritchie, o perodo mais criativo
ocorreu em 1972.

Pgina 55
10.2. K&R C

Em 1978, Brian Kernighan e Dennis Ritchie publicaram a primeira edio do livro The C
Programming Language. Esse livro, conhecido pelos programadores de C, como K&R,
serviu durante muitos anos como uma especificao informal da linguagem. A verso da
linguagem C que ele descreve usualmente referida como K&R C. A segunda edio do
livro, cobriu o padro posterior, o ANSI C. K&R C introduziu as seguintes caractersticas na
linguagem:

Biblioteca padro 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 lxico do compilador
fazia confuso entre i =+ 10 e i = +10. O mesmo acontecia com =-).

K&R C freqentemente considerado a parte mais bsica da linguagem, cujo suporte deve
ser assegurado por um compilador C. Durante muitos anos, mesmo aps a introduo do
padro ANSI C, K&R C foi considerado o menor denominador comum, em que
programadores de C se apoiavam quando uma portabilidade mxima era desejada, j que
nem todos os compiladores eram atualizados o bastante para suportar o padro ANSI C.
Nos anos que se seguiram publicao do K&R C, algumas caractersticas no-oficiais
foram adicionadas linguagem, suportadas por compiladores da AT&T e de outros
vendedores. Estas incluam:

Funes void e tipos de dados void *;


Funes que retornam tipos struct ou union;
Campos de nome struct num espao de nome separado para cada tipo struct;
Atribuio a tipos de dados struct;
Qualificadores const para criar um objecto s de leitura;
Biblioteca padro, que incorpora grande parte da funcionalidade implementada por
vrios vendedores;
Enumeraes;
Clculos de ponto-flutuante em preciso simples (no K&R C, os clculos
intermedirios eram feitos sempre em double, porque era mais eficiente na mquina
onde a primeira implementao do C foi feita).

Pgina 56
10.3. ANSI C e ISO C

Durante os finais da dcada de 1970, a linguagem C comeou a substituir a linguagem


BASIC como a linguagem de programao de microcomputadores mais usada. Durante a
dcada de 1980, foi adaptada para uso no PC IBM, e a sua popularidade comeou a
aumentar significativamente. Ao mesmo tempo, Bjarne Stroustrup, juntamente com outros
nos laboratrios Bell, comeou a trabalhar num projecto onde se adicionavam construes
de linguagens de programao orientada por objectos linguagem C. A linguagem que eles
produziram, chamada C++, nos dias de hoje a linguagem de programao de aplicaes
mais comum no sistema operativo Windows da companhia Microsoft; C permanece mais
popular no mundo UNIX.

Em 1983, o instituto norte-americano de padres (ANSI) formou um comit, X3J11, para


estabelecer uma especificao do padro da linguagem C. Aps um processo longo e rduo,
o padro foi completo em 1989 e ratificado como ANSI X3.159-1989 Programming
Language C. Esta verso da linguagem freqentemente referida como ANSI C. Em 1990,
o padro ANSI C, aps sofrer umas modificaes menores, foi adotado pela Organizao
Internacional de Padres (ISO) como ISO/IEC 9899:1990, tambm conhecido como C89 ou
C90. Um dos objetivos do processo de padronizao ANSI C foi o de produzir um
sobreconjunto do K&R C, incorporando muitas das caractersticas no-oficiais
subseqentemente introduzidas. Entretanto, muitos programas tinham sido escritos e que
no compilavam em certas plataformas, ou com um certo compilador, devido ao uso de
bibliotecas de funes no-padro e ao fato de alguns compiladores no aderirem ao ANSI
C.

10.4. C99

Aps o processo da padronizao ANSI, as especificaes da linguagem C permaneceram


relativamente estticas por algum tempo, enquanto que a linguagem C++ continuou a
evoluir. (em 1995, a Normative Amendment 1 criou uma verso nova da linguagem C mas
esta verso raramente tida em conta.) Contudo, o padro foi submetido a uma reviso nos
finais da dcada de 1990, levando publicao da norma ISO 9899:1999 em 1999. Este
padro geralmente referido como C99. O padro foi adoptado como um padro ANSI em
Maro de 2000. As novas caractersticas do C99 incluem:

funes em linha
remoo de restries sobre a localizao da declarao de variveis (como em C++)
adio de vrios tipos de dados novos, incluindo o long long int (para minimizar
problemas na transio de 32-bits para 64-bits), um tipo de dados boolean explicito
(chamado _Bool) e um tipo complex que representa nmeros complexos

Pgina 57
vetores de dados de comprimento varivel (o vetor pode ter um tamanho diferente a
cada execuo de uma funo, mas no cresce depois de criado)
suporte oficial para comentrios de uma linha iniciados por //, emprestados da
linguagem C++
vrias funes de biblioteca novas, tais como snprintf()
vrios ficheiros-cabealho novos, tais como stdint.h

O interesse em suportar as caractersticas novas de C99 parece depender muito das


entidades. Apesar do GCC e vrios outros compiladores suportarem grande parte das novas
caractersticas do C99, os compiladores mantidos pela Microsoft e pela Borland suportam
pouqussimos recursos do C99, e estas duas companhias no 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. Viso Geral

C uma linguagem imperativa e procedural, para implementao de sistemas. Seus pontos


de design foram para ele ser compilado, fornecendo acesso de baixo nvel memria e
baixos requerimentos do hardware. Tambm foi desenvolvido para ser uma linguagem de
alto nvel, para maior reaproveitamento do cdigo. C foi til para muitas aplicaes que
foram codificadas originalmente em Assembly.

Essa propriedade no foi acidental; a linguagem C foi criada com o objetivo principal em
mente: facilitar a criao de programas extensos com menos erros, recorrendo ao
paradigma da programao algortmica ou procedimental, mas sobrecarregando menos o
autor do compilador, cujo trabalho complica-se ao ter de realizar as caractersticas
complexas da linguagem. Para este fim, a linguagem C possui as seguintes caractersticas:

Uma linguagem nuclear extremamente simples, com funcionalidades no-essenciais,


tais como funes matemticas ou manuseamento de arquivos, fornecida por um
conjunto de bibliotecas de rotinas padronizada;
A focalizao no paradigma de programao procedimental;
Um sistema de tipos simples que evita vrias operaes que no fazem sentido
Uso de uma linguagem de pr-processamento, o pr-processador de C, para tarefas
tais como a definio de macros e a incluso de mltiplos ficheiros de cdigo fonte;
Ponteiros do maior flexibilidade linguagem;
Acesso de baixo-nvel, atravs de incluses de cdigo Assembly no meio do
programa C;

Pgina 58
Parmetros que so sempre passados por valor para as funes e nunca por
referncia ( possvel simular a passagem por referncia com o uso de ponteiros);
Definio do alcance lexical de variveis;
Estruturas de variveis, (structs), que permitem que dados relacionados sejam
combinados e manipulados como um todo.

Algumas caractersticas teis, que faltam em C, podem ser encontradas em outras


linguagens, que incluem:

Segurana de tipo;
Coletor de lixo (mais comum em linguagens interpretadas);
Vetores que crescem automaticamete;
Classes ou objectos com comportamento (ver orientao 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);
Funes aninhadas;
Programao genrica;
Sobrecarga de operadores;
Meta-programao;
Apoio nativo de multithreading e comunicao por rede.

Apesar da lista de caractersticas teis que C no possui, ser longa, isso no tem sido um
impedimento sua aceitao, pois isso permite que novos compiladores de C sejam escritos
rapidamente para novas plataformas, e tambm permite que o programador permanea
sempre em controle do que o programa est a fazer. Isto o que por vrias vezes permite o
cdigo de C correr de uma forma mais eficiente que muitas outras linguagens. Tipicamente,
s cdigo de assembly afinado mo que corre mais rapidamente, pois possui um
controle completo da mquina, mas avanos na rea de compiladores juntamente com uma
nova complexidade nos processadores modernos permitiram que a diferena tenha sido
rapidamente eliminada. Uma consequncia da aceitao geral da linguagem C que
freqentemente os compiladores, bibliotecas e at intrpretes de outras linguagens de nvel
maior sejam eles prprios implementados em C.

C tem como ponto forte, a sua eficincia, e a linguagem de programao preferida para o
desenvolvimento de sistemas e softwares de base, apesar de tambm ser usada para
desenvolver programas de computador. tambm muito usada no ensino de cincia da
computao, mesmo no tendo sido projetada para estudantes e apresentando algumas
dificuldades no seu uso. Outra caracterstica importante de C, sua proximidade do cdigo
de mquina, que permite que um projetista seja capaz de fazer algumas previses de como
o software ir se comportar, ao ser executado.

Pgina 59
C tem como ponto fraco, a falta de proteo que d ao programador. Praticamente tudo que
se expressa em um programa em C, pode ser executado, como por exemplo, pedir o
vigsimo membro de um vetor com apenas dez membros. Os resultados so muitas vezes
totalmente inesperados, e os erros, difceis de encontrar.

10.6. Palavras reservadas na Linguagem C

A linguagem C do tipo case sensitive. E alm disto, algumas palavras so reservadas,


sendo seu uso limitado apenas as funes ou comandos que elas executam:

O compilador IAR tem tambm algumas palavras reservadas, o que veremos ao longo deste
treinamento.

11. VARIVEIS, TIPOS DE DADOS E OPERADORES EM C

11.1. Tipos de dados

Basicamente apenas 5 tipos de dados que so 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 preciso dupla 64 bits, 8 bytes;
void sem valor.

Cada uma destes tipos pode ainda ter os seguintes modificadores:

Pgina 60
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 no informa se o dado tem valor positivo ou negativo. Por conseqncia
todos os bits do dado podem ser utilizados como informao;
short faz com que o dado passe a ter um tamanho menor do que especificado
em sua definio. 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 definio. Por exemplo: utilizar o long int pode faz-lo assumir o valor de 65536
bits, dependendo do compilador utilizado

11.1.1. Detalhes sobre nmeros em ponto flutuante

A base numrica no padro IEEE754 a binria. Neste padro so adotados dois formatos
para representao de nmeros: preciso simples e preciso dupla. (Na base binria, um
dgito binrio denominado bit e um byte um conjunto de 8 bits).

Pgina 61
Ficou estabelecido que no padro IEEE754, em preciso simples, um nmero real seria
representado por 32 bits, (4 bytes), sendo que:

1 bit reservado para o sinal do nmero (positivo ou negativo);


8 bits so reservados para o expoente da base, que um nmero inteiro;
23 bits so reservados para a mantissa:

Pelo mesmo padro IEEE754, em preciso dupla, um nmero real seria representado por 64
bits, (8 bytes), sendo que:

1 bit reservado para o sinal do nmero (positivo ou negativo);


11 bits so reservados para o expoente da base, que um nmero inteiro;
52 bits so 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

Pgina 62
11.2. Declarando variveis
necessrio, durante o fluxo do programa, declarar as variveis que sero utilizadas de
acordo com os tipos de dados mostrados anteriormente. Isto pode ser feito das seguintes
maneiras:

TIPO nome_da_varivel {,outras_variveis};


unsigned int tempo;

As variveis podem ser inicializadas com um determinado valor durante a sua declarao:

unsigned int tempo = 100;

11.2.1. Variveis locais e globais


Dependendo do local onde declarada a varivel, esta pode assumir uma funo global ou
local:

Variveis globais so acessveis de qualquer ponto do programa, por qualquer


funo, e devem ser declaradas no corpo principal do programa, fora de qualquer
funo, inclusive da main;
Variveis locais s podem ser acessadas dentro das funes onde foram criadas. Ao
sair desta funo, a linguagem C destri uma varivel local e, portanto ela no ser
acessvel por outras funes.

O programa a seguir (EXEMPLO-1) d uma demonstrao de como as variveis podem ser


declaradas localmente ou globalmente:
//******************************************************************************
// Exemplo de variveis globais e locais
// Alessandro Ferreira da Cunha
// Tech Training - Engenharia e Treinamentos
// Dezembro 2008 Extrado do Livro PIC Programao em C, do Fbio Pereira
// Built with IAR Embedded Workbench Version: 4.11.2.9
//******************************************************************************
#include <msp430xG46x.h>
#include <stdio.h>

int somatorio; // VARIVEL GLOBAL! SER ACESSADA POR TODAS AS FUNES

void soma (int valor) //AO ACESSAR ESTA FUNO, O PARMETRO VALOR RECEBE DADOS DE QUEM O CHAMOU
{
int conta; // VARIVEL LOCAL! SER ACESSADA APENAS PELA FUNO 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; // VARIVEL LOCAL! SER ACESSADA APENAS PELA FUNO MAIN
somatorio = 0; // A VARIVEL GLOBAL INICIALIZADA
for (conta=1;conta<20;conta++)
{
soma(conta); // CHAMADA A FUNO SOMA, ONDE PASSADO O VALOR DE CONTA
}
}

Pgina 63
Alguns comentrios 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 possvel visualizar estes dados atravs do Terminal
I/O, acessvel em: View Terminal I/O, onde ser aberta a janela mostrada abaixo.
Para que ele funcione necessrio incluir a biblioteca padro stdio.h

O formato do comando printf :


printf (string, varivel);
printf (O nmero de tentativas foi %d, contador);
Onde:
string: uma constate de caracteres, sempre declarado entre aspas;
varivel: a declarao de uma ou mais variveis que devem ser impressas
juntamente com os caracteres. Para tanto necessrio seguir a formatao %wt,
onde w o nmero de caracteres que se deseja imprimir e t uma das seguintes
opes:
c = caractere;
s = string ou caractere;
u = inteiro sem sinal;
x = inteiro em formato hexadecimal com letras minsculas;
X = inteiro em formato hexadecimal com letras maisculas;
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 minsculas;
LX = hexadecimal longo (16 ou 32 bits) com letras maisculas;
Lu = decimal longo (16 ou 32 bits) sem sinal;
Ld = decimal longo (16 ou 32 bits) com sinal;
% = smbolo de porcentagem;

Pgina 64
Para que todos os caracteres a serem impressos na janela Terminal I/O no fiquem na
mesma linha, so utilizados os caracteres especiais de barra invertida, que so:
\b = retrocesso (backspace);
\f = alimentao de formulrio;
\n = nova linha;
\r = retorno do carro;
\t = tabulao horizontal;
\ = aspas duplas;
\ = aspas simples;
\0 = nulo;
\\ = barra invertida;
\v = tabulao vertical;
\a = alerta (beep);
\N = constante octal, onde N o nmero em octal;
\xN = constante hexadecimal, onde N o nmero em hexadecimal;

Agora observe o programa exemplo EXEMPLO-2:

//******************************************************************************
// Exemplo de uso da funo 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; // VARIVEL LOCAL! SER ACESSADA APENAS PELA FUNO 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, tambm pela porta serial.

Isto tambm ser possvel visualizar atravs do Terminal I/O, acessvel em: View
Terminal I/O. Assim como no comando anterior, para que ele funcione tambm necessrio
incluir a biblioteca padro stdio.h

Pgina 65
O formato do comando scanf :
scanf (string, varivel);
scanf (%d, contador);
Tendo as mesmas caractersticas e controladores vistos no printf.

11.2.2. Modificadores de acesso


Alm das declaraes como global ou local, as variveis podem receber dois tipos de
modificadores de acesso, que especificam a forma como o compilador ir acessar o
contedo das variveis:
const: determina que a varivel ser tratada como uma constante, no podendo ser
modificada ou alteradas durante a execuo do programa. Faz, ento, com que a
varivel passe a ter um valor fixo, pr-estabelecido durante a declarao da varivel.
volatile: utilizado para indicar ao compilador que a varivel por ele indicada pode ter
seu contedo alterado a qualquer momento.
volatile unsigned int tempo = 100;

11.2.3. Modificadores de armazenamento

Indicam como o compilador ir tratar o armazenamento das variveis. So quatro tipos:

auto: serve para declarar que uma varivel local. Porm, todas as variveis
declaradas internamente j so locais. Com isto, este modificador de armazenamento
quase nunca utilizado.
extern: utilizado para fazer referncia a outras variveis globais que foram declaradas
em outros mdulos do programa. Isto muito til quando se tem programas extensos
onde mdulos cuidam de funcionamentos especficos e precisam passar parmetros
para outras partes do programa.
static: indica que a varivel ocupar uma posio permanente de memria. Isto
tambm ocorre quando uma varivel declarada de modo global. Mas numa
declarao de static, a varivel reconhecida apenas localmente, dentro da funo
em que foi criada. Se o modificador de armazenamento static for aplicado a uma
varivel que j global, isto far com que ela seja reconhecida apenas pelo programa
em que est inserida. Caso haja interao deste programa com outros externos, esta
varivel no estar acessvel.
register: faz com que o compilador tente gravar esta varivel diretamente em um dos
registradores que tem acesso direto a CPU do microcontrolador, ao invs de
armazen-la em uma posio de memria RAM. Com isto, ganha-se em velocidade
de processamento.

static volatile unsigned int tempo = 100;

Pgina 66
11.3. Operadores

11.3.1. Operador atribuio

utilizado para atribuir um determinado valor a uma varivel. Seu smbolo o = e alguns
exemplos de atribuio so mostrados a seguir:
unsigned int x, y;
x = 10;
y = x;
A atribuio sempre avaliada da direita para a esquerda. Isto significa que ao final deste
programa o valor da varivel y ser igual a 10.

11.3.2. Operadores aritmticos

Indica ao compilador que ele deve fazer determinada operao aritmtica entre duas
variveis. So os seguintes:

Um exemplo de utilizao 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

So utilizados em testes condicionais para determinar a relao existente entre os dados:

Pgina 67
11.3.4. Operadores lgicos

So utilizados para fazer conjunes, disjunes ou negaes entre elementos durante um


teste condicional.

11.3.5. Operadores lgicos bit a bit

11.3.6. Operadores de memria, ou de ponteiro

Os ponteiros sero tratados em detalhes no estudo dos dados avanados. possvel 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 so os smbolos utilizados como operadores de memria, ou de ponteiros, e suas
funcionalidades. As aplicaes sero desenvolvidas mais a frente. So dois os smbolos:
& endereo do operando. um operador unrio utilizado para retornar o
endereo de memria do seu operando. Isto significa que se escrevermos:

endereo_a = &a;

teremos que a varivel endereo_a conter o endereo em que est armazenada a


varivel a.
* contedo do endereo apontado pelo operando. Este um operador
unrio utilizado para retornar o contedo da posio de memria
endereada pelo operando que segue. Isto significa que se escrevermos:

a = *endereo_a;

teremos que o valor armazenado no local apontado pela varivel endereo_a seja
atribudo varivel a.

Pgina 68
11.3.7. Outros operadores
Outros operadores, que no se encaixam em nenhum dos tipos citados anteriormente, mas
que podem ser utilizados em linguagem C so:
? (ponto de interrogao) Operador ternrio condicional: pode fazer
um teste condicional, substituindo o comando IF. Sua forma geral :

varivel = expresso1 ? expresso2 : expresso3;

Ele funciona da seguinte maneira: avalie a expresso1. Se ela for verdadeira, atribua
a varivel o valor da expresso2. Caso a expresso1 seja falsa, ento a varivel
recebe o valor da expresso3.
, (vrgula) Separador de expresses: utilizado para enfileirar duas ou
mais expresses. Sua forma geral :

varivel = (expresso1 , expresso2 , expresso3);

Uma aplicao, 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 avanados.
-> (seta) Ponteiro de elementos de estruturas: utilizado em
estruturas de dados como ponteiro dos elementos e ser estudado quando
abordarmos os tipos de dados avanados.
(tipo) Operador modelagem de dado: possvel forar que uma
expresso seja de determinado tipo utilizando um cast cujo formato geral :

(tipo) expresso;

Onde tipo qualquer um dos tipos de dados permitidos pela linguagem C e


expresso a que se quer que resulte no tipo especificado. Por exemplo: para
realizar um clculo 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;

Pgina 69
sizeof Retorna o tamanho de uma varivel: para ter um melhor
controle da quantidade de memria utilizada, pode-se aplicar o operador
sizeof a qualquer varivel. Isto far retornar qual o tamanho que esta
varivel ocupa em bytes.

12. EXERCCIOS: Operadores, tipos e variveis

12.1. Calculadora bsica (EXERCCIO-1)

Escreva um programa em que o usurio entre com dois nmeros e seja realizada uma
operao matemtica bsica (multiplicao), 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 usurio digite o
primeiro nmero. Depois uma mensagem solicita a digitao de um segundo nmero.
Finalmente, o resultado da multiplicao mostrado em uma nova linha do Terminal I/O.

12.2. Conversor de moeda do dia (EXERCCIO-2)

Escreva um programa em que o usurio entre com a cotao do dlar do dia, digite qual a
quantidade de dlares 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 usurio I (EXERCCIO-3)

Escreva um programa em que o usurio entre com a data de nascimento no formato na


seguinte seqncia:
DIA (DD);
MS (MM);
ANO (AAAA).
Na seqncia, o usurio deve digitar a data de hoje, entrando com os valores de dia, ms e
ano no mesmo formato.

O programa deve, ento, calcular a idade do usurio, informando a idade em ANOS, cujo
valor deve ser um inteiro.

12.4. Calcular a idade de um usurio II (EXERCCIO-4)

Modifique o programa anterior de modo que seja mostrado na tela tambm o valor da idade
em DIAS e MESES.

Pgina 70
13. Declaraes de controle e repetio

As declaraes de controle e repetio so algumas das estruturas mais importantes da


linguagem C. Elas que garantem um fluxo de programa capaz de tomar decises e desviar
o programa de acordo com determinadas regras. Veremos neste treinamento estas
estruturas, definidas pelo padro ANSI C e como utiliz-las.

Seleo (condicional): if e switch;


Iterao (lao): while, for e do-while;
Desvio (salto): break, continue, goto e return;
Rtulo: case, default e label;

13.1. Verdadeiro ou Falso em linguagem C

Diversos destes comandos de controle e repetio acontecem apenas aps um teste


condicional, onde verificado o status de VERDADEIRO ou FALSO de uma varivel.
necessrio entender como o C observa esta condio para compreender perfeitamente
como as decises so tomadas:

VERDADEIRO: considerada uma condio verdadeira para uma varivel quando


esta tem qualquer valor diferente de zero, inclusive valores negativos.
FALSO: considerada uma condio falsa para uma varivel quando esta tem valor
igual a zero.

13.2. If

if (condio) comandoA; {else comandoB}

if (condio)
{
comandoA;
comandoB;
comandoC;
}
else
{
comandoD;
comandoE;
comandoF
}

Pgina 71
Veja um exemplo de utilizao da funo if rodando o programa EXEMPLO-3:
//******************************************************************************
// Exemplo de uso da funo 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; // nmero mgico


int palpite; // chute do usurio

numero = rand(); // gera um nmero aleatrio

printf("ADIVINHE QUAL O NMERO... \n \n ");


scanf("%d",&palpite);

if (palpite == numero) printf ("****CERTO!!!****\n\n");


else printf ("### ERRADO ###\n\n");

}
}

Note que para conseguir gerar um nmero randmico, foi necessrio incluir mais uma
biblioteca de funes, a stdlib.h.

13.2.1. If Else If comandos aninhados

if (condio1) comandoA;
else if (condio2) comandoB;
else if (condio3) comandoC;

Veja um exemplo de utilizao da funo if aninhadas no programa EXEMPLO-4:

//******************************************************************************
// Exemplo de uso da funo 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; // nmero mgico
int palpite; // chute do usurio
numero = rand(); // gera um nmero aleatrio
for ( ; ; ) // cria um loop infinito
{
printf("ADIVINHE QUAL O NMERO... \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");
}
}
}

Pgina 72
13.2.2. Uma alternativa: o comando ?

varivel = expresso1 ? expresso2 : expresso3;

Ele funciona da seguinte maneira: avalie a expresso1. Se ela for verdadeira, atribua a
varivel o valor da expresso2. Caso a expresso1 seja falsa, ento a varivel recebe o
valor da expresso3.

13.3. Switch

O comando switch difere do comando if porque somente pode testar igualdades. O


comando if pode avaliar uma expresso lgica ou relacional.

switch (varivel)
{
case constante1:
comandoA;
comandoB;
....
break;
case constante2:
comandoC;
comandoD;
....
break;
....
default:
comandoE;
comandoF;
....
}

Veja no programa EXEMPLO-5 como utilizar o comando switch case:

Pgina 73
//******************************************************************************
// Exemplo de uso da funo 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 NMERO ENTRE 0 E 5: \n \n ");
scanf("%d",&digitado);
switch (digitado)
{
case 0:
printf("O NMERO DIGITADO FOI %d ! \n \n ",digitado);
break;
case 1:
printf("O NMERO DIGITADO FOI %d ! \n \n ",digitado;
break;
case 2:
printf("O NMERO DIGITADO FOI %d ! \n \n ",digitado;
break;
case 3:
printf("O NMERO DIGITADO FOI %d ! \n \n ",digitado;
break;
case 4:
printf("O NMERO DIGITADO FOI %d ! \n \n ",digitado;
break;
case 5:
printf("O NMERO DIGITADO FOI %d ! \n \n ",digitado;
break;
default:
printf("O NMERO DIGITADO NO EST ENTRE 0 E 5! \n \n ");
}
}
}

13.4. Lao for (para)

for (inicializao ; condio ; incremento) comando;

for (inicializao ; condio ; incremento)


{
comandoA;
comandoB;
....
}

Veja no programa EXEMPLO-6 como utilizar o lao for:

//******************************************************************************
// Exemplo de uso da lao 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);
}

Pgina 74
13.4.1. Lao infinito

for ( ; ; );

13.4.2. Clusula break no comando for

Como sair de um lao infinito? Execute o programa EXEMPLO-7 e verifique seu efeito em
um lao infinito:

//******************************************************************************
// Exemplo de uso do comando BREAK em um lao 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 lao
}
printf ("voc digitou um A");
}

13.4.3. Clusula continue no comando for

Qual o efeito de trocar uma clusula break por uma clusula continue? Execute o programa
EXEMPLO-8 e verifique seu efeito:

//******************************************************************************
// Exemplo de uso da clusula CONTINUE em um lao 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 incio \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 --- ");
}

Pgina 75
13.5. Lao while (enquanto)
while (condio) comando;

while (condio)
{
comandoA;
comandoB;
....
}

Veja no programa EXEMPLO-9 como utilizar o lao while:


//******************************************************************************
// Exemplo de uso lao 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. Clusulas break e continue no lao while


As clusulas break e continue podem ser utilizadas tambm no comando while, tendo o
mesmo efeito que se obteve de seu uso no lao for. Veja o exemplo E-0-10.

//******************************************************************************
// Exemplo de uso das clusulas break e continue no lao 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 NMERO \n");
scanf("%d",&x);
printf("ENTRE COM OUTRO NMERO \n");
scanf("%d",&y);
printf("ENTRE COM A QUANT. DE IMPRESSES \n");
scanf("%d",&z);
while (w < z)
{
if (x == 0 || y == 0) break;
w++;
x = x * y;
printf("A MULTIPLICAO %d \n",x);
if (x < 1000) continue;
printf(" ACABOU ");
}
}

Pgina 76
13.5.2. Lao infinito

while (1)
{
......
}

13.6. Lao do-while (faa-enquanto)

do comando while (condio);

do
{
comandoA;
comandoB;
....
} while (condio);

Veja no programa EXEMPLO-11 como utilizar o lao do-while:

//******************************************************************************
// Exemplo de uso lao do-while
// Built with IAR Embedded Workbench Version: 4.11.2.9
//******************************************************************************
#include <msp430xG46x.h>
#include <stdio.h>

/* PROGRAMA PARA LANAMENTO DE FOGUETES DA NASA. */

void main()
{
WDTCTL = WDTPW+WDTHOLD; // Stop WDT
int start;
printf("ENTRE COM O TEMPO PARA LANAMENTO \n");
scanf("%d",&start);
/* O LAO DE CONTAGEM REGRESSIVA */
do
{
printf("FALTAM %d SEGUNDOS \n",start);
start--;
}
while(start>0);
printf("Zero!\n FOGO!!\n");
}

13.7. Usar um lao while (enquanto) ou um lao for (para)?

Os dois laos, while e for, tem vrias similaridades. Na grande maioria das situaes o
mesmo problema poder ser resolvido tanto com um tipo de lao quanto com o outro. Para
uma melhor compreenso do que estamos dizendo, vamos fazer uma equivalncia entre os
parmetros que so ajustados para fazer rodar um lao for e os mesmos parmetros para
fazer exatamente o mesmo efeito, mas com um lao while.

Pgina 77
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 visualizao mais fcil 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 aplicao em microcontroladores deve ser analisada com cuidado.

Dependendo do compilador e da forma como o lao gerado, pode ser obtido programas
em assembly maiores ou menores para executar a mesma tarefa. A velocidade com que o
programa executa o lao tambm influenciada pelo estilo de converso que o compilador
far para cada um deles.

Um excelente exerccio modificar as opes de otimizao do IAR (por velocidade ou por


tamanho de cdigo) e compilar programas com resultados de sada iguais mas que faam
uso de laos diferentes, observando o comportamento do cdigo assembly gerado pelo
compilador.

Pgina 78
13.8. Tudo junto?

Veja no programa EXEMPLO-12 todos os conceitos deste captulo 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 opes:\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 so:\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 carto.\n");
done=1;
break;
default:
printf("Seleo inadequada.\n");
} /* end switch */
} /* end while */
}/* end main */

13.9. Comando GOTO (v para)

goto label;

Pgina 79
14. EXERCCIOS: Declaraes de controle e repetio

14.1. Configurao bsica dos I/Os

As seguintes configuraes devem ser observadas para fazer os exerccios 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 vlida as seguintes
informaes:
Bit = 0: A entrada est em nvel lgico baixo (0 V).
Bit = 1: A entrada est em nvel lgico alto (+Vcc).

REGISTRADOR DE SADA (Output Registers PxOUT)


Cada bit escrito neste registrador refletir em um valor de tenso no pino de sada. Isto
ocorre quando a porta est configurada para sada, sendo vlida as seguintes informaes:.
Bit = 0: A sada ser levada a nvel lgico baixo (0 V).
Bit = 1: A sada ser levada a nvel lgico alto (+Vcc).

REGISTRADOR DE DIREO (Direction Registers PxDIR)


Este registrador indicar se um pino de I/O ser utilizado como entrada ou sada, de acordo
com a seguinte configurao:
Bit = 0: A porta ser configurada como entrada.
Bit = 1: A porta ser configurada como sada.

REGISTRADORES DE PULL UP / PULL DOWN (Pullup/Pulldown Resistor Enable


Registers PxREN (MSP430x47x only))
Apenas nos dispositivos das famlias MSP430x47x todas as portas tem resistores
programveis de pull-up/down, cuja habilitao ou no feita do seguinte modo:
Bit = 0: Os resistores estaro desabilitados.
Bit = 1: Os resistores estaro habilitados.

REGISTRADORES DE SELEO DE FUNO (Function Select Registers PxSEL)


Como os pinos de um microcontrolador pode ter mltiplas funes, hora funcionando como
terminal de I/O, hora como interface de algum perifrico, necessrio ajustar qual funo
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 perifrico.
Nota: as interrupes por P1 e P2 so desabilitadas quando PxSEL = 1

Pgina 80
REGISTRADOR DE SINALIZAO DE INTERRUPO (Flag Register PxIFG)
Sinalizam que uma interrupo aconteceu. A mudana de nvel zero para nvel um acontece
por hardware. O contrrio (de 1 0) deve ser executada por software:
Bit = 0: no h interrupo pendente neste pino (0 V).
Bit = 1: h uma interrupo pendente neste pino (+Vcc).

REGISTRADOR DE SELEO DE BORDA DE INTERRUPO (Edge Select PxIES)


Este registrador far a seleo entre as bordas de transio no sinal dos pinos que
acionaro a interrupo:
Bit = 0: PxIFG 1 quando houver uma transio de zero para um no pino (0 V +Vcc).
Bit = 1: PxIFG 1 quando houver uma transio de um para zero no pino (+Vcc 0 V).

REGISTRADOR HABILITAO DE INTERRUPO (Interrupt Enable Register PxIE)


Este registrador far a habilitao de interrupo para aquele pino:
Bit = 0: interrupes esto desabilitadas neste pino (0 V).
Bit = 1: interrupes esto habilitadas neste pino (+Vcc).

14.2. Alocao de pinos nas portas de I/O

/************************************************************
* STANDARD BITS FOR DIGITAL I/O
************************************************************/

#define BIT0 (0x0001); PINO 0 DA PORTA


#define BIT1 (0x0002); PINO 1 DA PORTA
#define BIT2 (0x0004); PINO 2 DA PORTA
#define BIT3 (0x0008); PINO 3 DA PORTA
#define BIT4 (0x0010); PINO 4 DA PORTA
#define BIT5 (0x0020); PINO 5 DA PORTA
#define BIT6 (0x0040); PINO 6 DA PORTA
#define BIT7 (0x0080); PINO 7 DA PORTA

14.3. Exemplos de configurao de portas de I/O

Configurando um boto:

SetupP2 bis.b #002h,&P2DIR ; P2.1 output - LED

SetupP1 bis.b #001h,&P1IE ; P1.0 Interrupt enabled


bis.b #001h,&P1IES ; P1.0 hi/low edge
bic.b #001h,&P1IFG ; P1.0 IFG Cleared

Configurando dois botes:

SetupP2 bis.b #006h,&P2DIR ; P2.1 & P2.2 output - LED

SetupP1 bis.b #003h,&P1IE ; P1.0 & P1.1 Interrupt enabled


bis.b #003h,&P1IES ; P1.0 & P1.1 hi/low edge
bic.b #003h,&P1IFG ; P1.0 & P1.1 IFG Cleared

Pgina 81
Identifique no diagrama eltrico da Experimenter Board, mostrado no item 9, as seguintes
conexes, envolvendo pinos do MSP430FG4618 e hardwares externos:

a) Boto S1 pino P1.0; d) LED2 pino P2.2;


b) Boto S2 pino P1.1; e) LED4 pino P5.1.
c) LED1 pino P2.1;

Com estas informaes escrevam programas em linguagem C de modo que aconteam as


operaes solicitadas nos itens a seguir.

14.4. 1 boto e 1 Led (EXERCCIO-5)

Ao pressionar o boto S1 deve acender o LED1. Se o boto no estiver pressionado, o


LED1 deve se manter apagado.

14.5. 2 botes e 2 Leds (EXERCCIO-6)

Ao pressionar o boto S1 deve apagar o LED1. Se o boto S1 no estiver pressionado, o


LED1 deve se manter aceso. Ao mesmo tempo se o boto S2 for pressionado, o LED2
deve se apagar. Se o boto S2 no estiver pressionado, o LED2 deve se manter aceso.

14.6. 1 boto, 1 Led e temporizao simples (EXERCCIO-7)

Ao pressionar o boto S2 deve acender o LED1, que deve permanecer aceso por alguns
milissegundos (tempo suficiente para perceber a reteno da informao). Se o boto no
estiver pressionado, o LED1 deve se manter apagado.

14.7. 2 botes, 2 Leds e temporizao simples (EXERCCIO-8)

Ao pressionar o boto S2 deve apagar o LED1, o que deve acontecer por alguns
milissegundos (tempo suficiente para perceber a reteno da informao). Se o boto no
estiver pressionado, o LED1 deve se manter aceso. Ao mesmo tempo, se o boto S1
estiver pressionado o LED2 deve ficar apagado, o que tambm deve acontecer por alguns
milissegundos (tempo suficiente para perceber a reteno da informao). Se o boto no
estiver pressionado, o LED2 deve se manter aceso

Pgina 82
15. Diretivas e funes do Compilador IAR

Alm de todos os comandos, controles e funes da linguagem C, tem-se ainda uma srie
de diretivas que so intrnsecas ao Compilador IAR. Para estud-las, o melhor caminho so
os arquivos de HELP que acompanham o compilador, alm dos arquivos USER GUIDE, em
formato .pdf, que podem ser acessados diretamente atravs do menu Help do compilador.
Dentre estes arquivos destacamos alguns que faro parte do CD que compe o material
didtico deste treinamento.

Apesar da grande quantidade de informao que estes arquivos fornecem, interessante t-


los sempre a mo, como uma fonte de consulta, toda vez que se est desenvolvendo um
novo programa.

Dentre as diversas diretivas e funes do compilador IAR, vamos listar dois tipos, que sero
utilizados ao longo do treinamento: as PRAGMAS e as FUNES INTRINSECAS. As
demais funes devero ser consultadas pelos estudantes diretamente nos arquivos.

15.1. Pragmas

Pragmas so um modo de passar informaes especiais para o compilador e para adicionar


extenses especficas de vendedor biblioteca do microcontrolador, garantindo assim sua
portabilidade entre diversos chips.

As diretivas #pragma so definidas pelo ISO/ANSI C e fazem, entre outras coisas, o


controle do comportamento do compilador. Por exemplo, ela pode determinar que
quantidade de memria alocada para cada varivel ou funo, permitir o uso de palavras
chaves, fornecer mensagens de alerta, etc.

A lista a seguir mostra todas as diretivas #pragma que esto disponveis no IAR, para a
famlia MSP430.

necessrio o uso do pr processador #pragma para que estas diretivas sejam entendidas
pelo compilador e passem a ser tratadas como tal.

Pgina 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

Pgina 84
15.2. Funes intrnsecas

So um conjunto de funes predefinidas que esto disponveis no compilador IAR. Elas


permitem um acesso direto ao processamento de baixo nvel e podem ser extremamente
teis em, por exemplo, rotinas que envolvam tempo crtico de execuo.

Para serem reconhecidas, necessrio acrescentar o arquivo intrinsics.h, atravs de um


comando include. Note que o nome destas funes 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

Pgina 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 exerccios propostos anteriormente no fizemos uso da principal


caracterstica do MSP430, que o baixo consumo de energia. Execute o programa
EXEMPLO-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
}

Pgina 86
17. Interrupes

As interrupes no MSP430 so fixas e definidas pelo arranjo modular mostrado na figura


abaixo.

Quanto mais prximo for um mdulo da CPU/NMIRS, maior a sua prioridade em interromper
o sistema. Esta prioridade define quem ser tratado primeiramente caso ocorram duas
interrupes simultaneamente.

Para o MSP430 so considerados trs tipos de interrupo:


Reset do sistema;
NMI: interrupes no mascarveis;
Interrupes mascarveis.
E funcionam de acordo com a lgica mostrada na figura a seguir.

17.1. Reset do sistema

O circuito de reset do sistema mostrado na figura a seguir. Ele fornece como sada 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.

Pgina 87
O POR um reset do dispositivo. Um POR s pode ser gerado caso ocorra um destes trs
eventos:
O dispositivo alimentado (Powering up);
Um nvel baixo (0 V) inserido no terminal RST/NMI, quando este pino est
configurado para o modo de reset;
Um baixo nvel de tenso detectado pelo mdulo SVS, quando PORON = 1.

Um PUC sempre gerado quando um POR gerado, porm um POR no 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 violao de segurana do Watchdog timer;
Houve uma violao de segurana no acesso a memria Flash.

O Brownout Reset (BOR) um hardware capaz de detectar se existem variaes na


tenso de alimentao do dispositivo, resetando-o a fim de evitar problemas de
funcionamento.

Pgina 88
17.2. NMI Interrupes no mascarveis

Estas trs interrupes no podem ser desabilitadas pelo bit de controle geral de
interrupes (GIE). Elas tm bits especficos para isto (ACCVIE, NMIIE, OFIE). Quando uma
destas interrupes aceita, todas as demais tem o seu bit de habilitao resetado.

O programa dar um salto em sua execuo para o endereo armazenado no vetor de


interrupo no mascarvel (0FFFCh). Ser necessrio que o software do usurio set
novamente os bits destas interrupes para que elas possam ocorrer novamente.

As interrupes no mascarveis so:


Um borda de descida/subida no pino RST/NMI pin, quando este configurado para o
modo NMI;
Ocorre um falha no oscilador;
Ocorre uma violao de acesso a memria flash.

17.3. Interrupes mascarveis

As interrupes mascarveis so geradas por todos os perifricos que possuem capacidade


de interrupo, incluindo o watchdog timer. Cada fonte de interrupo mascarvel 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 interrupo

Quando uma interrupo solicitada por um perifrico, necessrio que os bits de


habilitao individual e geral (GIE) estejam setados. Isto far com que o programa sofra um
desvio para uma rotina de interrupo.

Pgina 89
17.4.1. Entrada em uma interrupo

A latncia para o tratamento de um interrupo dura 6 ciclos de mquina, comeando pela


aceitao de uma interrupo e terminando com a execuo da primeira instruo contida
na rotina de atendimento de interrupo. A execuo lgica descrita a seguir:

1) Qualquer instruo que esteja sendo executada finalizada;

2) O valor do PC, que aponta para a prxima instruo 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 interrupo que tiver a maior prioridade selecionada, caso multiplas


interrupes ocorram simultaneamente;

5) Uma requisio de interrupo reseta o flag de interrupo dos perifricos que tem
fonte nica de interrupo (o conversor AD de 12 bits, por exemplo). Se o
perifrico tiver mltiplas flags de interrupo (portas P1 e P2, por exemplo), ento
o reset destas flags dever acontecer por software;

6) O registrador SR tem todos os seus bits zerados, com excesso do SCG0, que
no alterado. Isto retira o microcontrolador de qualquer LPM em que ele se
encontra. Como o GIE tambm zerado, as prximas interrupes ficam
desabilitadas.

7) O contedo do vetor de interrupo correspondente a quem fez a solicitao


carregado no PC, que passar a executar o programa a partir do que houver escrito
ali.

17.4.2. Sada de uma interrupo

Toda interrupo terminada quando uma instruo RETI (return from an interrupt service
routine) encontrada. Este retorno gasta 5 ciclos de mquina para executar as seguintes
aes:

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 execuo no


ponto exato em que parou ao ser interrompido.
Pgina 90
O aninhamento de interrupes habilitado quando, durante o tratamento de uma
interrupo, o usurio seta o bit GIE. Neste caso, havendo uma nova interrupo os
procedimentos mostrados ocorrero novamente, seguindo a ordem de prioridades de
atendimento de interrupes.

17.5. Os vetores de interrupo

Os vetores de interrupo tem um endereamento fixo e conhecido em todos os dispositivos


das famlias MSP430, indo de 0FFFFh at 0FFC0h. Nestes dados, que tem 16 bits, so
salvos os endereos onde estaro os programas que faro o atendimento as rotinas de
interrupo. Dependendo do nmero de perifricos, os dispositivos MSP430 podem ter mais
ou menos vetores de interrupo, por isto sempre necessria uma consulta ao datasheet
de cada dispositivo.

Pgina 91
17.5.1. Vetores de interrupo na famlia 2 (MSP430F2013)

NOTES:
1. Um reset gerado toda vez que a CPU tenta carregar um endereo no PC que esteja for
a do range de memria disponvel no dispositivo.
2. Fonte de mltiplos flags.
3. A flag de interrupo alocada no mdulo.
4. No mascarvel: o bit de interrupo individual pode ser desabilitado por um evento de
interrupo, mas geralmente isto no possvel.
5. Os endereos de vetores de interrupo entre 0FFDEh e 0FFC0h no so utilizados neste
dispositivo, podendo ser utilizado como rea de cdigo regular, onde ser armazenado o
programa.

Pgina 92
17.5.2. Declarao dos Vetores de interrupo 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 interrupo na famlia 4 (MSP430FG4618)

Pgina 93
NOTES:
1. Fonte de mltiplos flags.
2. A flag de interrupo alocada no mdulo.
3. Um reset gerado toda vez que a CPU tenta carregar um endereo no PC que esteja for
a do range de memria disponvel no dispositivo. (No mascarvel: o bit de interrupo
individual pode ser desabilitado por um evento de interrupo, mas geralmente isto no
possvel.
4. Os endereos de vetores de interrupo entre 0FFDAh e 0FFC0h no so utilizados neste
dispositivo, podendo ser utilizado como rea de cdigo regular, onde ser armazenado o
programa.
5. Violao na chave de acesso (KEYV e ACCVIFG), somente so aplicveis aos
dispositivos do tipo F.

17.5.4. Declarao dos Vetores de interrupo 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] */

Pgina 94
18. EXERCCIOS: BOTES E LEDS EM LOW POWER MODE.

J foi identificado no diagrama eltrico da Experimenter Board, mostrado no item 9, as


seguintes conexes, envolvendo pinos do MSP430FG4618 e hardwares externos:

a) Boto S1 pino P1.0; d) LED2 pino P2.2;


b) Boto S2 pino P1.1; e) LED4 pino P5.1.
c) LED1 pino P2.1;

Com estas informaes faa modificaes na segunda seqncia de exerccios, de modo


que o programa fique em Low Power Mode e apenas saia deste estado para executar
aes, fazendo economia de energia e realizando as mesmas atividades anteriores.

18.1. 1 boto e 1 Led (EXERCCIO9)

Ao pressionar o boto S1 deve acender o LED1. Se o boto no estiver pressionado, o


LED1 deve se manter apagado.

18.2. 2 botes e 2 Leds (EXERCCIO10)

Ao pressionar o boto S1 deve apagar o LED1. Se o boto S1 no estiver pressionado, o


LED1 deve se manter aceso. Ao mesmo tempo se o boto S2 for pressionado, o LED2
deve se apagar. Se o boto S2 no estiver pressionado, o LED2 deve se manter aceso.

18.3. 1 boto, 1 Led e temporizao com Basic Timer 1


(EXERCCIO11)

Ao pressionar o boto S2 deve acender o LED1, que deve permanecer aceso por 500 ms.
Se o boto no estiver pressionado, o LED1 deve se manter apagado.

18.4. 2 botes, 2 Leds e temporizao Basic Timer 1 (EXERCCIO12)

Ao pressionar o boto S2 deve apagar o LED1, o que deve acontecer por 500 ms. Se o
boto no estiver pressionado, o LED1 deve se manter aceso. Ao mesmo tempo, se o
boto S1 estiver pressionado o LED2 deve ficar apagado, o que tambm deve acontecer
por 500 ms. Se o boto no estiver pressionado, o LED2 deve se manter aceso

Pgina 95

Você também pode gostar