40
Material auxiliar para curso Avançado I de MSP430 – Prof. Alessandro F. Cunha Página 95 19. Funções 19.1. Forma Geral As funções em linguagem C podem ser encaradas como algo similar as sub-rotinas em programas escritos em Assembly, guardadas as suas devidas proporções. Sua forma geral, descrita pelo padrão ANSI C, é mostrada a seguir: {tipo da função} nome_da_função ({parâmetros}) { comandoA; comandoB; .... } Onde: Tipo da função: especifica o tipo de dado (int, char, float, doble, etc.) que a função irá devolver para o local de onde ela foi chamada. Nome_da_função: identificador a ser utilizado para referenciar aquela função. Ela passará a ser reconhecida pelo resto do programa por este nome. Parâmetros: são utilizados para a passagem de valores para que a função possa utilizá-los e efetuar os procedimentos para o qual foi escrita. Veja um exemplo de funções no programa (E-0-14): //****************************************************************************** // Exemplo de funções // // Alessandro Ferreira da Cunha // Tech Training - Engenharia e Treinamentos // Janeiro 2009 // Extraído do Livro "PIC - Programação em C", do Fábio Pereira // Editora Érica - Página 139 // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> int soma ( int a , int b) { return a + b; } main ( ) { printf("1 + 1 = %d \n", soma (1,1)); }

095 A 134 Material Auxiliar Para Curso AvançAdo I Msp430

Embed Size (px)

DESCRIPTION

terceira parte do material do curso avançado I

Citation preview

Page 1: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 95

19. Funções

19.1. Forma Geral As funções em linguagem C podem ser encaradas como algo similar as sub-rotinas em programas escritos em Assembly, guardadas as suas devidas proporções. Sua forma geral, descrita pelo padrão ANSI C, é mostrada a seguir:

{tipo da função} nome_da_função ({parâmetros})

{

comandoA;

comandoB;

....

}

Onde:

• Tipo da função: especifica o tipo de dado (int, char, float, doble, etc.) que a função irá devolver para o local de onde ela foi chamada.

• Nome_da_função: identificador a ser utilizado para referenciar aquela função. Ela passará a ser reconhecida pelo resto do programa por este nome.

• Parâmetros: são utilizados para a passagem de valores para que a função possa utilizá-los e efetuar os procedimentos para o qual foi escrita.

Veja um exemplo de funções no programa (E-0-14): //****************************************************************************** // Exemplo de funções // // Alessandro Ferreira da Cunha // Tech Training - Engenharia e Treinamentos // Janeiro 2009 // Extraído do Livro "PIC - Programação em C", do Fábio Pereira // Editora Érica - Página 139 // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> int soma ( int a , int b) { return a + b; } main ( ) { printf("1 + 1 = %d \n", soma (1,1)); }

Page 2: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 96

19.1.1. Funções do tipo void

Um dos usos de void é declarar explicitamente funções que não devolvem valores. Isso evita seu uso em expressões e ajuda a afastar um mau uso acidental. Antes de poder usar qualquer função como void, você deve declarar seu protótipo. Se isto não for feito, o C assumirá que ela devolve um valor inteiro e, quando o compilador encontrar de fato a função, ela declarará um erro de incompatibilidade.

19.1.2. O comando return O comando return tem dois importantes usos. Primeiro, ele provoca uma saída imediata da função que o contém. Isto é, faz com que a execução do programa retorne ao código que o chamou. Se o comando return for executado na função main, então o programa será encerrado. Segundo, ele pode ser utilizado para devolver um valor a função que o chamou. O primeiro programa exemplo (E-0-1) dá uma demonstração de como as funções podem trocar valores entre si: //****************************************************************************** // Exemplo de variáveis globais e locais // 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 3: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 97

19.2. Passagem de parâmetros

19.2.1. Fixo (por valor)

Exatamente como vem sendo executado até agora nos programas exemplos.

19.2.2. Variável (por referência) Utilizando ponteiros. Veja o exemplo abaixo (E-0-15): //****************************************************************************** // Exemplo de funções // // Alessandro Ferreira da Cunha // Tech Training - Engenharia e Treinamentos // Janeiro 2009 // Extraído do Livro "PIC - Programação em C", do Fábio Pereira // Editora Érica - Página 141 // Built with IAR Embedded Workbench Version: 4.11.2.9 //****************************************************************************** #include <msp430xG46x.h> #include <stdio.h> float divide ( float a , float b) { if (!b) return 0; a /= b; return a; } main ( ) { float a , b , c ; a = 7 ; b = 3 ; c = divide ( a , b ); printf("a = %f , b = %f , c = %f \n", a , b , c); }

19.3. Protótipos de função

Em programas profissionais, muito extensos, com diversas funções, pode acontecer de determinada função ser chamada e ainda não ter sido definida. Isto irá gerar um erro no compilador. Para evitar que isto ocorra, utiliza-se o protótipo da função, que será uma declaração prévia com o intuito de informar ao compilador que mais adiante no programa esta função será definida. Para isto basta colocar a primeira linha da função, que contem os dados do tipo da função, do nome da função e os parâmetros da função, como pode ser visto abaixo:

{tipo da função} nome_da_função ({parâmetros})

Page 4: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 98

20. Tipos de dados avançados

20.1. Ponteiros Ponteiros são um dos recursos mais poderosos da linguagem C. Qualquer programa de utilidade prática escrito em C dificilmente dispensará o uso de ponteiros. A tentativa de evitá-los implicará quase sempre códigos maiores e de execução mais lenta. Para quem está começando, pode parecer (e algumas vezes é) um tanto difícil. Mas não há outro caminho senão enfrentar a realidade. São muitas as aplicações de ponteiros. A seguir, relação das mais comuns.

• Acessar endereços de memória que o programa aloca em tempo de execução. • Acessar variáveis que não são visíveis em uma função. • Manipulação de arrays. • Manipulação de strings. • Passar o endereço de uma função para outra. • Retornar mais de um valor para uma função.

Genericamente, um ponteiro é uma variável utilizada para guardar o endereço de outra variável, ou seja, um ponteiro é um apontador de outra variável. Veja um exemplo de ponteiros no programa (E-0-17): //****************************************************************************** // Exemplo de ponteiro // // 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> int main() { char letra = 's'; int idade = 35; char nome[10] = "samuel"; float peso = 87.8; float altura = 1.82; printf("Exibindo o endereço de memória de variáveis\n\n"); printf("O valor da variável letra é %c e seu endereço é %x\n",letra,&letra); printf("O valor da variável idade é %d e seu endereço é %x\n",idade,&idade); printf("O valor da variável nome é %s e seu endereço é %x\n",nome,&nome); printf("O valor da variável peso é %2.1f e seu endereço é %x\n",peso,&peso); printf("O valor da variável altura é %1.2f e seu endereço é %x\n",altura,&altura); }

Para entender exatamente como os ponteiros podem ser utilizados, execute os exemplos que vão de (E-0-18) a (E-0-23).

Page 5: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 99

20.2. Matrizes de dados

Uma matriz é uma estrutura de dados que pode armazenar vários valores do mesmo tipo. A sintaxe para declarar uma matriz é:

TIPO nome_da_matriz [QUANTIDADE];

Onde:

• TIPO: é o tipo dos dados que serão armazenados na matriz. Todos os dados colocados na matriz devem ser deste tipo.

• NOME: é o nome a ser dado a matriz. Este nome identificará a matriz no código do programa.

• QUANTIDADE: é a quantidade máxima de itens a ser armazenados. Exemplo:

int nr_de_livros [50];

//esta matriz pode armazenar até 50 valores do tipo int

float nota [30];

//esta matriz pode armazenar até 30 valores do tipo float

Os valores armazenados na matriz são chamados de "elementos da matriz". O primeiro elemento da matriz é indexado como item zero e o último é indexado como QUANTIDADE menos 1. Assim, para nossa matriz nota, mostrada no exemplo acima, o primeiro elemento é nota[0] e o último elemento é nota[29]. Você pode inicializar os elementos de uma matriz na sua declaração usando a sintaxe:

int notas [5] = {60,70,35,50,68};

// No exemplo acima o elemento zero da matriz notas

receberá o valor 60, o elemento 1 receberá o valor 70, e

assim por diante. Para melhorar o entendimento observe o

código do exemplo (E-0-24). Esta matriz pode armazenar até

50 valores do tipo int

Page 6: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 100

//****************************************************************************** // Exemplo de matriz // // 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> int main() { int notas[5] = {60,70,35,50,68}; printf("Analisando os elementos da matriz notas\n"); printf("O primeiro elemento tem o valor %d\n",notas[0]); printf("O segundo elemento tem o valor %d\n",notas[1]); printf("O terceiro elemento tem o valor %d\n",notas[2]); printf("O quarto elemento tem o valor %d\n",notas[3]); printf("O quinto e último elemento tem o valor %d\n",notas[4]); return(0); }

Praticamente o mesmo efeito obtido pelo exemplo anterior pode ser obtido de modo muito mais eficiente pelo exemplo (E-0-25): //****************************************************************************** // Exemplo de matriz // // 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> int main() { int notas[5] = {60,70,35,50,68}; int contador; printf("Analisando os elementos da matriz notas\n"); for(contador = 0;contador < 5;contador++) printf("O %do elemento tem o valor %d\n",contador+1,notas[contador]); return(0); }

Para entender exatamente como as matrizes podem ser utilizadas, execute os exemplos que vão de (E-0-26) a (E-0-27).

20.2.1. Matrizes bi-dimensionais Imagine uma matriz bidimensional como uma tabela de linhas e colunas. Por exemplo, a matriz:

pesos [3][5];

Page 7: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 101

Ela pode ser imaginada como o seguinte arranjo de linhas e colunas, formando células:

Observe que o primeiro índice ([3]) indica as linhas da matriz e o segundo ([5]) indica as colunas. Como sabemos que [3] varia de zero a 2 e [5] varia de zero a 4, fica fácil determinar os índices de cada posição da matriz:

0,0 0,1 0,2 0,3 0,4

1,0 1,1 1,2 1,3 1,4

2,0 2,1 2,2 2,3 2,4

Visto a posição de cada índice vamos preencher nossa matriz pesos com valores:

10 30 45 70 36

86 44 63 82 80

70 61 52 63 74

De tudo que foi exposto acima podemos entender que:

pesos [1][3] = 82;

pesos [0][4] = 36;

pesos [0][0] = 10;

pesos [2][4] = 74;

Para preencher nossa matriz com os valores mostrados na tabela acima podemos usar uma declaração como:

int pesos [3][5] =

{{10,30,45,70,36},{86,44,63,82,80},{70,61,52,63,74}};

Podemos manipular os elementos de nossa matriz bidimensional usando duas variáveis e um laço for da mesma maneira que fizemos com as matrizes comuns. Observe o código do exemplo (E-0-28):

Page 8: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 102

//****************************************************************************** // Exemplo de matriz // // 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> /* manipulando uma matriz bidimensional */ int main() { int pesos[3][5] = {{10,30,45,70,36}, {86,44,63,82,80}, {70,61,52,63,74}}; int linha,coluna; for(linha = 0;linha < 3;linha++) for(coluna = 0;coluna < 5; coluna++) printf("elemento[%d][%d] = %d\n",linha,coluna,pesos[linha][coluna]); return(0); }

20.2.2. Passando uma matriz bi-dimensional para uma função

Uma função que manipula uma matriz bidimensional deve receber a matriz e o número de linhas desta matriz. O número de colunas da matriz também deve estar especificado nesta declaração. Ao chamar a função, deve-se passar a matriz e o número de linhas. Como isto funciona? Veja o exemplo (E-0-29): //****************************************************************************** // Exemplo de matriz // // 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> /* manipulando uma matriz bidimensional */ void exibe(int matriz[][5], int linhas) { int linha,coluna; for(linha = 0;linha < 3;linha++) for(coluna = 0;coluna < 5; coluna++) printf("elemento[%d][%d] = %d\n",linha,coluna,matriz[linha][coluna]); } int main() { int pesos[3][5] = {{10,30,45,70,36}, {86,44,63,82,80}, {70,61,52,63,74}}; exibe(pesos,3); return(0); }

Page 9: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 103

20.3. Estruturas de dados

As estruturas são utilizadas para agrupar informações relacionadas de tipos de dados diferentes. Digamos que você precisa controlar os seguintes dados relacionados ao estoque de um pequeno estabelecimento comercial:

• código • nome do produto • quantidade estocada • valor de compra • valor a ser vendido • lucro • observacões sobre o produto

Este seria um caso para o uso de estruturas, pois relacionados a cada produto teremos dados do tipo int(código,quantidade), char(nome, observações) e float(valor de compra, valor de venda, lucro). A sintaxe para a declaração (ou criação) de uma estrutura é:

struct nome_da_estrutura

{

tipo campo1;

tipo campo1;

....

tipo campoN;

}

Para o caso exemplificado no item anterior poderíamos ter algo como:

struct produto

{

int codigo;

char nome[50];

int quantidade;

float valor_compra;

float valor_venda;

float lucro;

char obs[200];

}

Page 10: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 104

É importante observar que a declaração da estrutura não cria, ainda, uma variável. A declaração da estrutura apenas cria um novo tipo de dado. Após criar a estrutura você pode declarar variáveis do tipo de estrutura criado.

20.3.1. Declarando variáveis do tipo de uma estrutura criada Após a declaração da estrutura você pode declarar variáveis do tipo da estrutura com a sintaxe:

struct nome_da_estrutura nome_da_variável

struct produto item

Observe que esta sintaxe obedece a sintaxe normal para a declaração de variáveis:

tipo nome_da_variável

sendo que o TIPO da variável, a nova estrutura criada. Você também pode declarar a variável logo após a declaração da estrutura com uma sintaxe do tipo:

struct produto

{

int codigo;

char nome[50];

int quantidade;

float valor_compra;

float valor_venda;

float lucro;

char obs[200];

} item;

20.3.2. Acessando os campos de uma estrutura

A sintaxe para acessar e manipular campos de estruturas é a seguinte:

nome_da_estrutura.campo

Observe o código do exemplo (E-0-30), mostrado a seguir, para um melhor esclarecimento:

Page 11: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 105

//****************************************************************************** // Exemplo de struct // // 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> /* acessando os campos de uma estrutura */ /* criando um novo tipo de dado "produto" */ struct produto { int codigo; char nome[50]; int quantidade; float valor_compra; float valor_venda; }; int main() { struct produto item; /* declarando uma variável "item" do tipo "struct produto" */ printf("Preenchendo a variável \"item\"\n"); printf("Item............:\n"); fgets(item.nome,50,stdin); printf("Código..........:\n"); scanf("%d",&item.codigo); printf("Quantidade......:\n"); scanf("%d",&item.quantidade); printf("Valor de compra.:\n"); scanf("%f",&item.valor_compra); printf("Valor de revenda:\n"); scanf("%f",&item.valor_venda); printf("\n"); printf("Exibindo os dados\n"); printf("Código..........:%d\n",item.codigo); printf("Item............:%s\n",item.nome); printf("Quantidade......:%d\n",item.quantidade); printf("Valor de compra.:%.2f\n",item.valor_compra); printf("Valor de revenda:%.2f\n",item.valor_venda); return(0); }

20.3.3. Acessando uma estrutura com ponteiros

Para acessar uma estrutura usando ponteiros você pode usar duas sintaxes:

(*nome_da_estrutura).campo

nome_da_estrutura -> campo

Observe o código do exemplo (E-0-31), mostrado a seguir, para um melhor esclarecimento:

Page 12: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 106

//****************************************************************************** // Exemplo de struct // // 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> /* acessando uma estrutura com ponteiros */ struct registro { char nome[30]; int idade; }; altera_estrutura1(struct registro *ficha) { (*ficha).idade -= 10; } altera_estrutura2(struct registro *ficha) { ficha->idade += 20; } int main() { struct registro ficha; printf("Entre com seu nome:\n"); fgets(ficha.nome,30,stdin); printf("Qual sua idade?\n"); scanf("%d",&ficha.idade); printf("\nExibindo os dados iniciais\n"); printf("Nome: %s \n",ficha.nome); printf("Idade: %d.\n",ficha.idade); altera_estrutura1(&ficha); printf("\nExibindo os dados após a primeira alteração\n"); printf("Nome: %s \n",ficha.nome); printf("Idade: %d.\n",ficha.idade); altera_estrutura2(&ficha); printf("\nExibindo os dados após a segunda alteração\n"); printf("Nome: %s \n",ficha.nome); printf("Idade: %d.\n",ficha.idade); return(0); }

Page 13: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 107

20.4. Uniões

Em C uma union é uma posição de memória que é compartilhada por duas ou mais variáveis diferentes, geralmente de tipo de diferentes, em momentos diferentes. A definição de uma union é semelhante à definição de estrutura. Sua forma geral é:

union identificador

{

tipo nome_da_variável;

tipo nome_da_variável;

tipo nome_da_variável;

...

} variáveis_união;

Exemplo:

union teste

{

int i;

char ch;

};

Page 14: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 108

21. EXERCÍCIO4: Tipos de dados avançados

21.1. Armazenamento e tratamento de dados 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 escreva um programa que execute o algoritmo mostrado abaixo, 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 atividades pedidas.

1. Aguardar o usuário pressionar o botão S1 para iniciar as atividades. Enquanto o botão não for pressionado, a Experimenter Board deve ficar em LPM3.

2. Ao pressionar o botão S1 deve ser aceso o LED1 e o terminal I/O deve mostrar a

mensagem: “Insira o dado 01:”

E o programa deve ficar aguardando, com o LED1 aceso, o usuário inserir, via terminal I/O, um número entre 0 e 65535.

3. Ao término da digitação, o programa deve apagar o LED1, acender o LED2 e

aguardar o usuário pressionar o botão S2. Enquanto o usuário não pressionar o botão S2, a Experimenter Board deve ficar em LPM3.

4. Ao pressionar o botão S2 deve ser aceso o LED1 e o terminal I/O deve mostrar a

mensagem: “Insira o dado 02:”

E o programa deve ficar aguardando, com o LED1 aceso, o usuário inserir, via terminal I/O, um número entre 0 e 65535.

5. O ciclo composto pelos passos 2, 3 e 4 deve se repetir até que o usuário entre com o

vigésimo dado.

6. Ao final da entrada do vigésimo dado o LED4 deve ficar aceso e a Experimenter Board deve ficar em LPM3 enquanto o usuário não pressionar o botão S1.

Page 15: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 109

7. Ao pressionar o botão S1, o LED4 deve ser apagado, o LED1 deve ser aceso e o

terminal I/O deve mostrar a mensagem:

“O dado 01 é XX”

Onde XX é exatamente o mesmo valor que foi inserido pelo usuário no passo 2.

8. Um segundo após mostrar a mensagem, o LED1 deve ser apagado, o LED4 aceso e a Experimenter Board deve ficar em LPM3 enquanto o usuário não pressionar o botão S1.

9. Ao pressionar o botão S1, o LED4 deve ser apagado, o LED1 deve ser aceso e o

terminal I/O deve mostrar a mensagem:

“O dado 02 é YY”

Onde YY é exatamente o mesmo valor que foi inserido pelo usuário no passo 4.

10. Um segundo após mostrar a mensagem, o LED1 deve ser apagado, o LED4 aceso e a Experimenter Board deve ficar em LPM3 enquanto o usuário não pressionar o botão S1.

11. O ciclo composto pelos passos 7, 8, 9 e 10 deve se repetir até que seja mostrado no

terminal I/O o último dado armazenado.

12. Ao final da amostragem do vigésimo dado o programa deve retornar ao passo 1, e recomeçar tudo novamente.

Page 16: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 110

22. REAL TIME CLOCK Este periférico presente nos chips da família 4 é composto de registradores de propósito geral que podem ser configurados como um timer de 32 bits ou como um relógio de tempo real. Dentre as funcionalidades deste módulo estão:

• Modos de funcionamento como relógio e calendário • Contador de 32 bits com fonte de clock de contagem selecionável • Quando configurado no modo calendário é feito o incremento automático dos

segundos, minutos, horas, dias da semana, dia do mês, mês e ano • Capacidade de gerar interrupções • Capacidade de trabalhar em BCD

O diagrama deste módulo é mostrado na figura abaixo:

Todos os valores dos registradores que pertencem ao módulo RTC tem valor inicial em estado X. Isto significa que o programador deve inicializar cada um deles adequadamente.

Page 17: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 111

Os modos de funcionamento são ajustáveis pelo registrador RTCCTL (Real Time Clock Control Register), mostrado a seguir:

Page 18: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 112

22.1. Operação como contador

Os bits RTCMODEx com qualquer valor diferente de 11 fazem o módulo RTC operar como um contador de 32 bits, totalmente acessível via software. Caso haja uma troca do modo de operação de contador para RTC todos os registradores com valores serão resetados. Quatro resitradores de 8 bits são cascateados (RTCNTx), formando um contador de 32 bits. Com esta arquitetura é possível obter interrupções quando ocorre um estourou em qualquer um destes quatro registradores (em 8 bits, 16 bits, 24 bits ou 32 bits). Qualquer um destes registradores são totalmente acessíveis para escrita ou leitura.

22.2. Operação como calendário Quando os bits RTCMODEx são ajustados com 11 módulo RTC opera como calendário. Neste modo de operação o RTC fornecerá segundos, minutos, horas, dia da semana, dia do mês, mês e ano. Estas informações podem ser fornecidas em formato hexadecimal ou em BCD. Caso haja uma troca do modo de operação de RTC para contador faz com que os registradores dos com valores segundos, minutos, horas, dia da semana e ano sejam restados. Já os registradores com os valores do dia do mês e do mês serão receberão os valor 1. O algoritmo interno deste módulo permite ajuste de data em qualquer dia entre os anos de 1901 e 2099, incluindo a contagem dos anos bissextos. 32 bits, totalmente acessível via software. Caso haja uma troca do modo de operação de contador para RTC ou vice-versa, todos os registradores com valores serão resetados.

22.3. Interação entre o RTC e o Basic Timer 1 Quando o RTC está ajustado para o modo de calendário, o Basic Timer 1 é automaticamente configurado como um divisor prévio para o RTC, com os dois registradores de 8 bits do Basic Timer cascateados e o ACLK selecionado como fonte de clock do Basic Timer. Os ajustes que tenham sido feitos nos bits BTSSEL, BTHOLD and BTDIV do Basic Timer serão ignorados. O bit RTCHOLD do módulo RTC passará a controlar os dois periféricos simultaneamente (RTC e BT1).

Page 19: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 113

22.4. As interrupções do RTC

O módulo RTC utiliza duas fontes de controle de interrupção:

• BT1IF • RTCIE

O RTC compartilha as flags com o BT1. Quando RTCIE = 0, o BT1 passará a controlar a interrupção através do bit BTIPx. Neste caso, os bits RTCTEVx serão responsáveis por selecionar o intervalo em que será setado o bit RTCIF, mas este bit, mesmo quando levado para nível lógico 1, não irá gerar um evento de interrupção. Mesmo assim ainda haverá a necessidade de que o software apague o bit RTCIF para que haja um novo registro de que aconteceu mais uma interrupção. Quando RTCIE = 1, o RTC passará a controlar a interrupção e os bits BTIPx serão ignorados. Neste caso, os bits RTCFG e BT1FG serão setados a cada intervalo de tempo que foi previamente ajustado pelos bits RTCEVx. Um evento de interrupção será gerado automaticamente cada vez que um destes dois bits sejam setados, desde que o bit GIE já esteja ajustado. Ao entrar na rotina de interrupção estes dois bits serão resetados automaticamente, não necessitando de intervenção do programador. Mesmo assim ainda haverá a necessidade de que o software apague o bit RTCIF para que haja um novo registro de que aconteceu mais uma interrupção.

22.5. Todos os registradores do RTC A listagem de todos os registradores utilizados no RTC são mostrados na figura a seguir.

Page 20: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 114

Page 21: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 115

Observe o código do exemplo (E-0-31), mostrado a seguir, para um melhor esclarecimento: //****************************************************************************** // MSP430xG461x Demo - Real Time Clock, Toggle P5.1 Inside ISR, 32kHz ACLK // // Description: This program toggles P5.1 by xor'ing P5.1 inside of // a Real Time Clock ISR. The Real Time Clock ISR is called once a minute using // the Alarm function provided by the RTC. ACLK used to clock basic timer. // ACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO = 32 x ACLK = 1048576Hz // //* An external watch crystal between XIN & XOUT is required for ACLK *// // // MSP430FG4619 // ----------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | P5.1|-->LED // // S.Schauer / A. Dannenberg // Texas Instruments Inc. // June 2007 // Built with IAR Embedded Workbench Version: 3.42A //****************************************************************************** #include <msp430xG46x.h> //------------------------------------------------------------------------------ void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop Watchdog Timer FLL_CTL0 = XCAP14PF; // Configure load caps RTCCTL = RTCBCD+RTCHOLD+RTCMODE_3+RTCTEV_0+RTCIE; // RTC enable, BCD mode, // alarm every Minute, // enable RTC interrupt // Init time RTCSEC = 0x00; // Set Seconds RTCMIN = 0x00; // Set Minutes RTCHOUR = 0x08; // Set Hours // Init date RTCDOW = 0x02; // Set DOW RTCDAY = 0x23; // Set Day RTCMON = 0x08; // Set Month RTCYEAR = 0x2005; // Set Year RTCCTL &= ~RTCHOLD; // Enable RTC P5DIR |= 0x02; // Set P5.1 to output direction __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/ interrupt } // Basic Timer interrupt service routine #pragma vector=BASICTIMER_VECTOR __interrupt void basic_timer(void) { P5OUT ^= 0x02; // Toggle P5.1 using exclusive-OR }

Page 22: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

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

Página 116

23. EXERCÍCIO5: Relógio digital 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 escreva um programa que execute o algoritmo mostrado abaixo, 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 atividades pedidas.

1. Aguardar o usuário pressionar o botão S1 para iniciar as atividades. Enquanto o botão não for pressionado, a Experimenter Board deve ficar em LPM3.

2. Ao pressionar o botão S1 deve ser aceso o LED1 e o terminal I/O deve mostrar a

mensagem: “Insira o ano:”

E o programa deve ficar aguardando, com o LED1 aceso, o usuário inserir, via terminal I/O, o ano atual.

3. Ao término da digitação, o programa deve apagar o LED1, acender o LED2 e

aguardar o usuário pressionar o botão S2. Enquanto o usuário não pressionar o botão S2, a Experimenter Board deve ficar em LPM3.

4. Ao pressionar o botão S2 deve ser aceso o LED1 e o terminal I/O deve mostrar a

mensagem: “Insira o mês:”

E o programa deve ficar aguardando, com o LED1 aceso, o usuário inserir, via terminal I/O, o mês atual.

5. O ciclo composto pelos passos 2, 3 e 4 deve se repetir até que o usuário entre com o

o ano, mês, dia da semana, dia do mês, hora, minuto e segundo atual.

6. Ao terminar este processo o LED4 deve ficar aceso e a Experimenter Board deve ficar em LPM3 enquanto o usuário não pressionar o botão S1.

Page 23: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 117

7. Ao pressionar o botão S1, o LED4 deve ser apagado, o LED1 deve ser aceso e o

terminal I/O deve mostrar a mensagem:

“Hora do alarme:”

E o programa deve ficar aguardando, com o LED1 aceso, o usuário inserir, via terminal I/O, a hora do alarme.

8. Ao término da digitação, o programa deve apagar o LED1, acender o LED4 e

aguardar o usuário pressionar o botão S1. Enquanto o usuário não pressionar o botão S1, a Experimenter Board deve ficar em LPM3.

9. Ao pressionar o botão S1, o LED4 deve ser apagado, o LED1 deve ser aceso e o

terminal I/O deve mostrar a mensagem:

“Minuto do alarme:”

E o programa deve ficar aguardando, com o LED1 aceso, o usuário inserir, via terminal I/O, a hora do alarme.

10. Ao término da digitação, o programa deve apagar o LED1, acender o LED4 e

aguardar o usuário pressionar o botão S1. Enquanto o usuário não pressionar o botão S1, a Experimenter Board deve ficar em LPM3.

11. Ao pressionar o botão S1, o LED4 deve ser apagado, o LED1 deve ser aceso e o

terminal I/O deve mostrar a mensagem:

“Segundo do alarme:”

E o programa deve ficar aguardando, com o LED1 aceso, o usuário inserir, via terminal I/O, a hora do alarme.

12. Ao término da digitação, o programa deve passar a piscar rapidamente os três LEDs

da placa (LED1, LED2 e LED4) a cada segundo computado pelo RTC. Quando o RTC atingir o horário estipulado pelo alarme, o buzzer deve soar por um minuto e o programa deve voltar ao passo inicial. Durante todo este processo a Experimenter Board deve ficar em LPM3 na maior parte do tempo possível.

Page 24: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 118

24. CONTROLADOR DE DISPLAY DE LCD O hardware LCD_A tem a capacidade de alimentar diretamente displays de LCD através da criação de sinais AC por segmento e tensões comuns automaticamente. Suas principais características são:

• Uma memória onde são armazenados os dados a serem exibidos no display; • Geração automática dos sinais necessários ao funcionamento do display; • Freqüência de exibição de quadro configurável; • Possibilidade de piscar o display independentemente do sinal de clock; • Fonte de alimentação regulada; • Controle de contraste via software; • Suporte a quatro tipos de displays de LCD:

o Estático; o 2-mux, ½ bias ou ⅓ bias o 3-mux, ½ bias ou ⅓ bias o 4-mux, ½ bias ou ⅓ bias.

O diagrama em blocos deste controlador pode ser visto na figura a seguir:

24.1. Memória para o LCD No mapeamento de memória do MSP 430 existe um trecho dedicado ao funcionamento do controlador de LCD, conforme mostrado na figura a seguir. Cada um dos bits deste mapeamento de memória corresponde a um segmento do display de LCD, o que pode ser utilizado ou não, dependendo do modelo do LCD e do dispositivo utilizado. Acionar um determinado segmento do display LCD corresponde a colocar um bit em nível lógico 1.

24.2. Piscando o LCD O controlador de LCD permite que todos os segmentos ativos pisquem, sem a necessidade de modificação da taxa de tempo. Isto é feito através do bit LCDSON. Quando LCDSON = 1, cada segmento que está ativo permanece ligado. Os segmentos que não estão ativos permanecem desligados. Quando LCDSON = 0, todos os do LCD são desligados, independentemente de seu estado ativo ou não.

Page 25: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 119

Page 26: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 120

24.3. Controle de tensão e de geração de sinal de offset O módulo LCD permite selecionar qual será a fonte para gerar o sinal de tensão de saída que é aplicada aos planos de fundo (back planes) do display (chamada de tensão V1), bem como a fração desta tensão que será utilizada como offset (de V2 a V5). Isto possibilita que o LCD seja alimentado através do AVCC, de um gerador interno ou de uma fonte externa ao microcontrolador. Todas as fontes de alimentação internas são desligadas quando o ACLK está desligado (OSCOFF = 1) ou quando o módulo LCD_A é desligado (LCDON = 0).

24.3.1. Selecionando as fontes de tensão Para determinar qual será a fonte de tensão a ser utilizada pelo módulo é necessário atuar sobre dois registradores de controle vistos a seguir: LCDAVCTL0 e LCDAVCTL0. Eles atuam sob o hardware de tensão mostrado a seguir.

Page 27: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 121

Page 28: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 122

24.3.2. Controle de contraste. A tensão de saída em conjunto com o modo de operação e o offset determinam qual será o contraste a ser utilizado no LCD. Assim, um ajuste de contraste via software necessitará que seja feito um ajuste no gerador de voltagem, atuando sobre os bits VLCDx, presentes no registrador LCDAVCTL0. A taxa de contraste dependerá display LCD utilizado e do offset escolhido. Um exemplo desta configuração é mostrada na tabela abaixo.

Page 29: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 123

HzHzfLCD 256128

32768== HzHzfLCD 341

9632768

==

HzHzfLCD 51264

32768==

24.4. Freqüência de operação do LCD_A O módulo LCD_A utiliza o sinal fLCD (proveniente do Basic Timer), que deve ser previamente ajustado a partir do ACLK para gerar a base de tempo necessária ao funcionamento dos displays de LCD. O valor da freqüência a ser ajustada é controlada através dos bits LCDFREQx, presentes no registrador LCDACTL. O valor correto depende do tipo de LCD que se está utilizando. Então uma consulta ao manual do fabricante do LCD se faz necessário. A taxa de quadros que serão amostrados no display quando este fizer uso de vários back planes, e tiver a necessidade de ser multiplexado, é calculada pela expressão abaixo:

FRAMELCD fmuxf ⋅⋅= 2

Por exemplo: um LCD com três back planes, que necessita de um mux de três vias, com uma freqüência de quadro entre 30 Hz e 100 Hz:

FRAMELCD ff ⋅⋅= 32

HzfHzfMÁXIMOMÍNIMO LCDLCD 600180 =⇔=

Isto faz com que o microcontrolador seja ajustado para as seguintes opções:

Page 30: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 124

24.5. Saídas do módulo LCD

Alguns dos segmentos do display de LCD são multiplexados com funções de I/O digital. Então estes pinos podem ter a função de I/O ou de LCD. Em que momento cada pino deste será ajustado para qual função dependerá exclusivamente do ajuste feito através do registrador PxSELx aplicável a porta onde o LCD está conectado.

Page 31: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 125

24.6. Modo estático (um único back plane)

Neste modo cada pino de segmento do driver do MSP430 controla apenas um segmento de LCD e apenas a linha comum COM0 é utilizada. Um exemplo dos sinais gerados seguir e da conexão a ser feita pode ser vista nas figuras abaixo.

Page 32: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 126

24.7. Modo 2-Mux (dois back planes)

Page 33: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 127

24.8. Modo 3-Mux (três back planes)

Page 34: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 128

24.9. Modo 4-Mux (quatro back planes)

Page 35: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 129

24.10. Outros registradores que controlam o LCD

Page 36: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 130

25. EXERCÍCIO 6: Configurar e utilizar o display de LCD da Experimenter

Board. O Primeiro passo para configurar e utilizar o display de LCD presente na Experimenter Board é buscar o datasheet do mesmo, o que pode ser feito através do site do fabricante.

www.softbaugh.com O modelo na placa é o SBLCDA4. O segundo passo é verificar como os terminais do display estão conectados na placa, o que é feito no próximo item.

Page 37: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 131

25.1. O display LCD da Experimenter Board

A conexão entre os pinos do Display SoftBaugh SBLCDA4 e o MSP430FG4618 são mostrados nas duas figuras a seguir. A seguir são mostrados todos os segmentos deste display e a suas respectivas numerações.

Page 38: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 132

Page 39: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 133

25.2. Exercício 6.1 Mapear a memória do MSP430

Preencha o mapeamento de memória do MSP430 mostrado abaixo adequadamente. Para isto você deve indicar onde cada bit da memória representa cada um dos segmentos do display SBLCDA4 da SoftBaugh.

Page 40: 095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430

Material auxiliar para curso Básico de MSP430 – Prof. Alessandro F. Cunha

Página 134

25.3. Exercício 6.1 Relógio Digital com display de LCD

Aproveite o exercício 5, que foi desenvolvido para o RTC, e faça com que as mensagens que são enviadas ao Terminal I/O, para entrada e saída de dados, sejam mostradas no Display de LCD. Para isto, crie imagens que substituam adequadamente as mensagens e que possibilitem ao usuário o entendimento do que se está pedindo para fazer. Não formataremos qual é esta mensagem. Deixaremos que utilizem sua criatividade!

25.4. Exercício 6.2 Relógio Digital com display de LCD Utilize o exercício anterior e acrescente a seguinte funcionalidade a ele: Para ativar o programa (sair do estado inicial de Low Power Mode), o usuário deve manter pressionado o botão S1 por 30 segundos. Somente após este tempo é que o software deve iniciar os procedimentos de entrada para ajuste do relógio e do despertador.