Professional Documents
Culture Documents
Funções
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.
//******************************************************************************
// 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>
main ( )
{
printf("1 + 1 = %d \n", soma (1,1));
}
Página 95
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.
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.
//******************************************************************************
// Exemplo de variáveis globais e locais
// Built with IAR Embedded Workbench Version: 4.11.2.9
//******************************************************************************
#include <msp430xG46x.h>
#include <stdio.h>
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
}
}
Página 96
19.2. Passagem de parâmetros
Exatamente como vem sendo executado até agora nos programas exemplos.
//******************************************************************************
// 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>
main ( )
{
float a , b , c ;
a = 7 ;
b = 3 ;
c = divide ( a , b );
printf("a = %f , b = %f , c = %f \n", a , b , c);
}
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:
Página 97
20. Tipos de dados avançados
20.1. Ponteiros
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.
//******************************************************************************
// 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;
Para entender exatamente como os ponteiros podem ser utilizados, execute os programas
exemplos que vão de (EXEMPLO-18) a (EXEMPLO-23).
Página 98
(EXEMPLO-18)
//******************************************************************************
// 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()
{
int idade = 35;
int *ptr_idade;
return(0);
}
(EXEMPLO-19)
//******************************************************************************
// 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()
{
int idade = 35;
int *ptr_idade;
return(0);
}
Página 99
(EXEMPLO-20)
//******************************************************************************
// 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()
{
int numero = 35;
int *ptr;
ptr = № /* atribuindo o endereço de numero a ptr */
printf("O ponteiro ptr armazena o endereço %x que,\npor sua vez,\
armazena o valor %d\n",ptr,*ptr);
return(0);
}
(EXEMPLO-21)
//******************************************************************************
// 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()
{
int nr = 26;
int *ptr_nr;
return(0);
}
Página 100
(EXEMPLO-22)
//******************************************************************************
// 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[6] = {'a','e','i','o','u','\0'};
int contador, nr[5] = {30,12,67,13,41};
char *ptr_letra;
int *ptr_nr;
ptr_letra = letra;
ptr_nr = nr;
printf("\nIncrementando os ponteiros\n");
printf("ptr_letra + 3, ptr_nr + 2\n");
ptr_letra += 3;
ptr_nr += 2;
return(0);
}
Página 101
(EXEMPLO-23)
//******************************************************************************
// 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 *dia[] = {"Domingo","Segunda","Terça","Quarta","Quinta","Sexta","Sábado",0};
char **ptr_dia;
while(*ptr_dia)
{
printf("%s\n",*ptr_dia);
ptr_dia++;
}
return(0);
Uma matriz é uma estrutura de dados que pode armazenar vários valores do mesmo tipo.
A sintaxe para declarar uma matriz é:
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.
Página 102
Exemplo:
//******************************************************************************
// 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};
return(0);
}
Página 103
Praticamente o mesmo efeito obtido pelo exemplo anterior pode ser obtido de modo muito
mais eficiente pelo próximo programa (EXEMPLO-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 programas
(EXEMPLO-26) e (EXEMPLO-27).
(EXEMPLO-26)
//******************************************************************************
// 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()
{
char palavra[7] = "matriz";
int contador;
printf("Em C strings são matrizes de caracteres e podem ser manipuladas como tal.\n");
printf("\nA string é %s\n",palavra);
printf("\nExibindo cada elemento da matriz palavra\n");
for(contador = 0;contador < 7;contador++)
printf("%c\n",palavra[contador]);
return(0);
Página 104
(EXEMPLO-27)
//******************************************************************************
// 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;
exibe(notas,5);
return(0);
}
Imagine uma matriz bidimensional como uma tabela de linhas e colunas. Por exemplo, a
matriz:
pesos [3][5];
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:
Página 105
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
Para preencher nossa matriz com os valores mostrados na tabela acima podemos usar uma
declaração como:
//******************************************************************************
// 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 pesos[3][5] = {{10,30,45,70,36},
{86,44,63,82,80},
{70,61,52,63,74}};
int linha,coluna;
return(0);
}
Página 106
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 programa (EXEMPLO-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>
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);
}
• código
• nome do produto
• quantidade estocada
• valor de compra
• valor a ser vendido
• lucro
• observacões sobre o produto
Página 107
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).
struct nome_da_estrutura
{
tipo campo1;
tipo campo1;
....
tipo campoN;
}
struct produto
{
int codigo;
char nome[50];
int quantidade;
float valor_compra;
float valor_venda;
float lucro;
char obs[200];
}
É 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.
Após a declaração da estrutura você pode declarar variáveis do tipo da estrutura com a
sintaxe:
Página 108
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;
nome_da_estrutura.campo
Página 109
//******************************************************************************
// 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>
int main()
{
struct produto item; /* declarando uma variável "item" do tipo "struct produto" */
return(0);
}
Para acessar uma estrutura usando ponteiros você pode usar duas sintaxes:
(*nome_da_estrutura).campo
nome_da_estrutura -> campo
Página 110
//******************************************************************************
// 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>
struct registro
{
char nome[30];
int idade;
};
int main()
{
struct registro ficha;
altera_estrutura1(&ficha);
altera_estrutura2(&ficha);
return(0);
}
Página 111
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;
};
Página 112
21. EXERCÍCIO: Tipos de dados avançados
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.
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.
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.
Página 113
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.
Página 114
22. REAL TIME CLOCK
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.
Página 115
Os modos de funcionamento são ajustáveis pelo registrador RTCCTL (Real Time Clock
Control Register), mostrado a seguir:
Página 116
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.
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.
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).
Página 117
22.4. As interrupções do RTC
• BT1IF
• RTCIE
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.
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.
Página 118
Página 119
Observe o código do programa (EXEMPLO-32), 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
// Init date
RTCDOW = 0x02; // Set DOW
RTCDAY = 0x23; // Set Day
RTCMON = 0x08; // Set Month
RTCYEAR = 0x2005; // Set Year
Página 120
23. EXERCÍCIO: Relógio digital
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.
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.
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.
Página 121
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.
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.
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.
Página 122
24. CONTROLADOR DE DISPLAY DE 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.
Página 123
Página 124
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).
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.
Página 125
Página 126
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.
Página 127
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:
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:
f LCD = 2 ⋅ 3 ⋅ f FRAME
Isto faz com que o microcontrolador seja ajustado para as seguintes opções:
32768 Hz 32768 Hz
f LCD = = 256 Hz f LCD = = 341Hz
128 96
32768 Hz
f LCD = = 512 Hz
64
Página 128
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.
Página 129
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.
Página 130
24.7. Modo 2-Mux (dois back planes)
Página 131
24.8. Modo 3-Mux (três back planes)
Página 132
24.9. Modo 4-Mux (quatro back planes)
Página 133
24.10. Outros registradores que controlam o LCD
Página 134
25. EXERCÍCIO: Configurar e utilizar o display de LCD da Experimenter
Board.
www.softbaugh.com
O segundo passo é verificar como os terminais do display estão conectados na placa, o que
é feito no próximo item.
Página 135
25.1. O display LCD da Experimenter Board
Página 136
Página 137
25.2. (EXERCÍCIO-15) Æ Mapear a memória do MSP430
Página 138
25.3. (EXERCÍCIO-16) Æ 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!
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.
Página 139