fenglogo
Laboratório de Processadores
Programação do LPC2378 usando o arm-elf-gcc
Parte 4: Timer e display LCD
puclogo

Neste exemplo vamos fazer o programa a04_timer_lcd.tgz para configurar o Kit como um relógio que mostra as horas, minutos e segundos no display LCD e na porta serial e pisca os LEDs de forma cadenciada usando o timer T0.

Timers

Os microcontroladores tipo LPC23xx tem 4 timers (T0, T1, T2 e T3) de 32 bits, que diferem apenas no endereço de acesso. Estes timers tem recursos poderosos, mas na configuração básica são fáceis de usar. Com eles pode-se medir tempos, gerar interrupções cadenciadas ou contar eventos externos.

Aqui vamos configurar o timer para contar com base no clock externo de 12MHz, incrementando a contagem 1000 vezes por segundo. Isto será usado na função void espera(int t) para esperar t milisegundos e no programa principal para fazer piscar o LED1 ficando apagado durante 600ms e aceso durante 400ms. Os registradores usados na configuração do timer são os seguintes:
T0TCR
0xE0004004
Timer Control Register. Habilita ou Inicializa o Timer
bit 0: Habilita o Timer.
bit 1: Inicializa o timer com zero.
T0TC
0xE0004008
T0 Timer Count. Neste registrador está o valor da contagem do timer.
T0PR
0xE000400C
T0 Prescale Register: Configura o divisor da frequência de incremento do timer. O registrador T0PC é incrementado até ficar igual ao T0PR. Neste momento a contagem T0TC é incrementada e T0PC é zerado. Portanto configura-se este registrador com o divisor de freqência menos um.

Assim a configuração do timer para incrementar T0TC 1000 vezes por segundo é:

T0TCR = 0;		/* Desabilita T0 */
T0PR = CRYSTALFREQ/1000 - 1; /* Incrementa o contador T0TC 1000 vezes por segundo */
T0TCR = 2;	/* Inicializa T0 */
T0TCR = 1;	/* Habilita T0	*/

Nesta configuração a palavra CRYSTALFREQ é a frequência em Hertz do clock usado no timer. Inicialmente o LPC2378 usa um clock interno de 4MHz com um divisor por 4, resultando que CRYSTALFREQ=1000000. Fazendo a configuração feita na função int PLL_Init(void), temos que CRYSTALFREQ=12000000. Esta função tambem tem outro efito: Antes de usar int PLL_Init(void), o acesso aos pinos GPIO das portas P0 e P1 é feito da forma tradicional, com IOPIN1. Depois deve-se usar as portas com acessos tipo FIO1PIN.

Existem vários outros registradores relacionados com os timers que não vou mencionar porque não foram usados neste programa.

A rotina de espera usa o valor da contagem do timer T0TC para esperar durante um tempo determinado de milisegundos:

/* Espera t milisegundos */
void espera(unsigned int t)
{
unsigned int tf;
tf = T0TC + t;		/* tf = Valor futuro do T0TC */
while(tf != T0TC);	/* espera ate que tf==T0TC */
}

Display LCD

O Kit de Lab. Processadores tem um display LCD de 2 linhas por 16 colunas conectado aos pinos GPIO do LPC2378 de acordo com a tabela a seguir:
Nome do sinalPino do LPC2378MáscaraDescrição
LCD_EP4.240x01000000 Habilitação do Latch de entrada do LCD.
Normalmente LCD_E = 0
Admite dado quando LCD_E = 1
LCD_RSP4.250x02000000 Seleciona Dado/Comando.
LCD_RS = 0 Comando.
LCD_RS = 1 Escreve caractere.
LCD_DP3.0 a P3.70x000000ff Barramento de dados do LCD (8 bits).

Para facilitar o entendimento do programa vamos dar nomes para as máscaras de bits:

#define LCD_E  0x01000000
#define LCD_RS 0x02000000
#define LCD_D  0x000000ff

O display é controlado escrevendo comandos com RS=0 ou escrevendo caracteres ASCII com RS=1. A tabela a seguir apresenta alguns comandos do LCD.
ComandoExplicação
0x38Configura o display para 2 linhas com interface de 8 bits
0x01Limpa o display
0x0eLiga o cursor como um traço em baixo _
0x0fLiga o cursor como um bloco sólido
0x0cEsconde o cursor
0x80+xPosiciona o cursor na primeira linha, coluna x
0xc0+xPosiciona o cursor na segunda linha, coluna x
0x10Move o cursor 1 charactere para a esquerda
0x14Move o cursor 1 charactere para a direita
0x18Scroll horizontal para a esquerda
0x1EScroll horizontal para a direita

Conforme foi visto no capítulo 2, podemos controlar os bits do display usando os registradores:
FIO3DIR
0x3fffc060
Especifica a direção dos bits da GPIO P3:
0: Entrada
1: Saida
O processador inicia com todos os bits configurados como entrada.
FIO3MASK
0x3fffc070
Habilita a escrita nos pinos da P3:
Escrevendo uma máscara de bits em FIO3MASK pode-se inibir a escrita nos bits onde a máscara é 1 (um). O processador inicia com FIO3MASK=0, deixando todos os bits liberados para escrita.
FIO3PIN
0x3fffc074
Na escrita escreve um valor nos bits de GPIO
Na leitura le o estado dos bits.
FIO3SET
0x3fffc078
Liga bits da P3. Os bits onde se escreve 1 são ligados e os bits onde se escreve 0 ficam inalterados.
FIO3CLR
0x3fffc07c
Desiga bits da P3. Os bits onde se escreve 1 são desligados e os bits onde se escreve 0 ficam inalterados.

O procedimento para escrever um comando no LCD fica assim:

/* Escreve um comando para o LCD */
void LCDcomando(int c)
{
FIO3PIN0 = c;		/* Escreve dados do LCD nos bits 0 a 7 do FIO3	*/
FIO4CLR = LCD_RS;	/* Zera o sinal LCD_RS para indicar comando	*/
FIO4SET = LCD_E;	/* Liga a habilitacao do latch de dados do LCD	*/
c++; c--;		/* Tempo */
FIO4CLR = LCD_E;	/* E=0 */
espera(20);		/* espera 20ms */
}

O procedimento para escrever caracteres no display é similar. A ´nica diferença é que o sinal RS deve ser ligado.

/* Escreve um caractere no LCD */
void LCDputchar(int c)
{
FIO3PIN0 = c;		/* Escreve dados do LCD nos bits 0 a 7 do FIO3	*/
FIO4SET = LCD_RS;	/* Liga o sinal LCD_RS para escrever caractere	*/
FIO4SET = LCD_E;	/* Liga a habilitacao do latch de dados do LCD	*/
c++; c--;		/* Tempo */
FIO4CLR = LCD_E;	/* E=0 */
espera(8);		/* espera 8ms */
}

A inicialização do display é feita configurando as portas de GPIO e escrevendo os comandos de configuração do LCD:

/* Inicializa o display LCD */
void LCDinit(void)
{
FIO3DIR |= 0xff;	/* Dados do LCD como saidas */
FIO4DIR |= (LCD_RS | LCD_E);	/* LCD_RS e LCD_E como saídas */
FIO3CLR = LCD_E;	/* LCD_E deve ficar normalmente em 0 */
espera(40);
LCDcomando(0x38);	/* Configura LCD */
LCDcomando(1);		/* Limpa */
LCDcomando(0x0c);	/* Cursor oculto */
}

Bibliografia