quinta-feira, janeiro 01, 2009

Controlando um LED com um MSP430 - Parte III

Como curiosidade vamos ver como fica o software do nosso projeto em Assembly.

A programação em Assembly no MSP430 é simplificada por uma série de fatores:
  • mapeamento contínuo da memória através de endereços de 16 bits;
  • conjunto de instruções bastante conciso ;
  • um conjunto completo de modos de endereçamento, incluindo operando imediato (de 8 ou 16 bits) e referências diretas ou inderetas à memória para os dois operandos;
  • uma boa quantidade de registradores de uso geral.
No caso do meu programa não foi preciso nem usar os registradores de uso geral, foi possível acessar sempre a memória diretamente.

Como no caso do programa em C, usei como ambiente de desenvolvimento o IAR Embedded Workbench Kickstart.

O programa ficou assim:
#include "msp430.h"

NAME main ; nome do modulo

; Vetor de Interrupções
ORG 0FFFEh ; reset
DC16 init

ORG 0FFF0h ; timer2A
DC16 t2int

; Bits correspondentes aos pinos de E/S
#define BOTAO 01h
#define LED 40h

; Valor para contar 50ms c/ clock de 12KHz
#define TEMPO_50MS 600


RSEG CSTACK ; declara segmento da pilha

RSEG DATA16_N ; segmento de dados

; Controle do LED
ModoLed: DS8 1
#define LED_APAGADO 0
#define LED_ACESO 1
#define LED_PISCANDO 2

; Controle do Botao
ModoBotao: DS8 1
#define BOTAO_ANTERIOR 01h
#define BOTAO_APERTADO 02h


; Código

RSEG CODE ; programa vai no segmento 'CODE'

init:
MOV #SFE(CSTACK), SP ; inicia a pilha
MOV.W #WDTPW+WDTHOLD,&WDTCTL ; para o WDT

BIS.B #LFXT1S1,&BCSCTL3 ; ativa VLOCLK

MOV.B #0, &P1SEL ; todos os pinos como I/O
MOV.B #0FFh & ~BOTAO, &P1DIR ; somente o botão é entrada
MOV.B #BOTAO, &P1REN ; usar resistor no botão
MOV.B #BOTAO, &P1OUT ; usar resistor no botão

MOV.B #0, &P2SEL ; todos os pinos como I/O
MOV.B #0FFh, &P2DIR ; todos os pinos como saída
MOV.B #0, &P2OUT ; todas as saidas em zero

MOV.B #0, ModoBotao ; botao solto
MOV.B #LED_APAGADO, ModoLed ; led apagado

MOV.B &CALBC1_12MHZ, &BCSCTL1 ; configura o DCO
MOV.B &CALDCO_12MHZ, &DCOCTL

MOV #TEMPO_50MS, &TACCR0 ; interrupção a cada 50ms
MOV #TASSEL_1 + MC_1 + TAIE, &TACTL


main:
BIS #GIE+CPUOFF+SCG1+SCG0,SR ; LPM3

; não deve chegar até aqui...
JMP main ; loop sem fim


; interrupção do timer2A
t2int:
CMP #10,&TAIV
JNZ t2int_fim

CMP #LED_PISCANDO, ModoLed
JNZ trata_botao
XOR.B #LED, &P2OUT ; pisca o LED

trata_botao:
BIT.B #BOTAO, &P1IN
JNZ botao_solto

BIT.B #BOTAO_ANTERIOR, ModoBotao
JNZ continua_apertado

BIS.B #BOTAO_ANTERIOR, ModoBotao ; aguarda confirmação
JMP t2int_fim

continua_apertado:
BIT.B #BOTAO_APERTADO, ModoBotao
JNZ t2int_fim

BIS.B #BOTAO_APERTADO, ModoBotao ; confirmamos aperto

CMP.B #LED_APAGADO, ModoLed
JNZ led_nao_apagado

MOV.B #LED_ACESO, ModoLed
BIS.B #LED, &P2OUT ; acende o LED
JMP t2int_fim
led_nao_apagado:
CMP.B #LED_ACESO, ModoLed
JNZ led_piscando

MOV.B #LED_PISCANDO, ModoLed ; piscar o LED
JMP t2int_fim
led_piscando:
MOV.B #LED_APAGADO, ModoLed
BIC.B #LED, &P2OUT ; apaga o LED
JMP t2int_fim
botao_solto:
BIT.B #BOTAO_ANTERIOR, ModoBotao
JZ continua_solto
BIC.B #BOTAO_ANTERIOR, ModoBotao ; aguarda confirmação
JMP t2int_fim
continua_solto:
BIC.B #BOTAO_APERTADO, ModoBotao ; confirmado

t2int_fim:
RETI

END


Na quarta e última parte veremos como montar o circuito, compilar o código e gravá-lo no microcontrolador.

Nenhum comentário: