Você está na página 1de 27

CENTRO FEDERAL DE EDUCAO TECNOLGICA DO PARAN

Departamento de Eletrnica
disciplina de Microcontroladores
professor Moribe
















Controlador de motor de passo
utilizando o kit msp-169
da lanser sistemas eletrnicos














Cludio Luiz Kunde






Curitiba, 25 de agosto de 2005.
2

NDICE

1. Introduo ...........................................................................................................................3
2. Objetivos..............................................................................................................................4
3. Hardware.............................................................................................................................5
4. Software do Microcontrolador ............................................................................................7
5. Software do PC..................................................................................................................21
6. Concluso..........................................................................................................................27

3
1. Introduo
Este projeto trata do controle de um motor de passo, implementado atravs do kit
msp-169 da Lanser Sistemas Eletrnicos, desenvolvido para a disciplina de
microcontroladores do departamento de eletrnica do Centro Federal de Educao
Tecnolgica do Paran, o CEFET-PR.

A importncia do projeto decorre do fato da utilizao de motores de passo em um
grande nmero de aplicaes, sendo importante seu estudo para o futuro
desenvolvimento de equipamentos ou solues que envolvam o mesmo na sua
estrutura.

Atualmente encontramos motores de passo sendo usados principalmente em
impressoras, discos rgidos e drivers de disquetes, mas tambm encontramos outras
utilizaes para eles como mesas grficas, plotters e sistemas robticos de
movimentao de braos mecnicos.

O que todos esses sistemas possuem em comum a preciso, que apenas um
motor de passo consegue fornecer, alm do controle de velocidade e sentido de giro
de forma mais eficiente sem a necessidade de realimentao (motor de malha
aberta), uma vez que o uso de atuadores e amplificadores para tratar o controle por
malha fechada acabam produzindo erros e instabilidade no sistema, alm de serem
mais complexos no seu tratamento.
4
2. Objetivos
O objetivo deste projeto controlar um motor de passo, atravs do uso do kit msp-
169 da Lanser Sistemas Eletrnicos. A idia ter controle sobre todos os parmetros
apresentados pelo motor, sendo eles:

Controle de velocidade
Controle de sentido de giro do motor
Controle do passo: meio passo ou passo inteiro

Outro objetivo importante deste projeto aprender a manipular o microcontrolador
MSP430F169 que o corao do kit. Sendo um microcontrolador bastante verstil,
ser de grande importncia aprender a utilizar seus temporizadores, escrever rotinas
em assembler e comunic-lo com o PC atravs de comunicao serial.
5
3. Hardware
A seguir ser apresentado os componentes necessrios para a montagem do
projeto. Como o motor de passo controlado logicamente, veremos a seguir que no
existe grande dificuldade de lig-lo ao kit. Os componentes necessrios so os
seguintes:

1 kit msp-169 desenvolvido pela Lanser Sistemas Eletrnicos
1 motor de passo encontrado em drivers de disquete de 5 ou outro de
passo unipolar.
1 resistor de 27 de 1/2W ou uma fonte 12V
Fios para conexo
Um cabo serial para comunicar o kit com o PC via RS232.

O motor de passo utilizado para este projeto foi o MSJE200A53 da Sankyo e trabalha
em 12V. Para aliment-lo pode ser usado a sada de alimentao de 12V existente
no kit, porm como esta sada na verdade fornece em torno de 15V conveniente
colocar um resistor em srie para que seja feito um divisor de tenso com a bobina
do motor e o mesmo opere com 12V. Ao invs do resistor pode ser usado tambm
uma fonte de 12V regulada e precisa para alimentar o motor garantindo que o
mesmo no queime seus enrolamentos por sobretenso.

A tabela abaixo mostra como deve ser conectado o motor placa do kit
Motor (cor do fio) Pino na Placa do kit
Laranja P10
Amarelo P11
Marrom P12
Vermelho P13
Branco +12V (com resistor de 27 intercalado)

6
Nota Importante: A corrente drenada pelas entradas do motor so elevadas e no
devem ser conectadas diretamente aos pinos de entrada do microcontrolador sob
risco de queimar as mesmas. O ideal que seja colocado um driver de alimentao
no meio da conexo (pode ser utilizado o ULN2003A). No caso do kit msp-169 j
existe este driver de corrente entre o port 1 do controlador e os borns de conexo
P1x.

A figura abaixo ilustra como ficou o hardware aps a montagem.

Figura 1: Hardware do Projeto

A figura abaixo mostra como ficou configurado o teclado do kit para o ajuste dos
parmetros do motor.

7
4. Software do Microcontrolador
O software do microcontrolador foi programado em assembler, utilizando o ambiente
de desenvolvimento IAR Embedded WorkBench. Alguns detalhes de implementao
importantes devem ser considerados e sero apresentados a seguir.

O primeiro cuidado ao estar programando o port1, para fazer o acionamento do
motor, que a parte alta deste port tambm est sendo utilizada por rotinas de
escritas no display. Ento necessrio criar uma mscara para escrever apenas na
parte baixa do port (pinos P0 a P3).

Como dito anteriormente, o MSP430F169 um microcontrolador bastante verstil e
apresenta dois Timmers alm do Watch Dog que tambm pode ser utilizado como
timer. Desta forma, destinou-se o TimmerA para funes de varredura do teclado e o
TimmerB para funes de temporizao do passo do motor.

A estrutura do cdigo foi divida em mdulos bem definidos e sero explicadas a
seguir medida que for apresentado o cdigo de cada arquivo gerado.

Arquivo StepMotor.s43
Este mdulo pode ser entendido como o mtodo main do programa. Nele esto as
definies das variveis do teclado, display, motor e interface serial. Consiste
basicamente em uma rotina que permanece em loop infinito lendo o teclado. Para
determinada tecla pressionada executada uma operao. O display atualizado e
uma operao executada sobre o motor e a interface serial. Tambm as rotinas de
tratamento das interrupes do Timmer A e B e da UART esto neste arquivo. A
seguir apresentado o cdigo por completo do arquivo StepMotor.s43

;******************************************************************************
;ROTINAS DE DISPARO DE MOTOR DE PASSO
;CLUDIO LUIZ KUNDE
;11/08/2005
;******************************************************************************
NAME main
8
;ROTINAS EXTERNAS
EXTERN INIDISP, ESCINST, ESCDADO, GOTOXY, MSTRING, CUR_ON, CUR_OFF
EXTERN INITEC, GTEC, VARTEC, DECTEC, CHEXASC
EXTERN ROTATE, PRINT_RPM
EXTERN INIT_HW, SEND_RS232

;ROTINAS GLOBAIS
PUBLIC main

;VARIVEIS GLOBAIS
PUBLIC ESPLINHA, BOUNCE1, BOUNCE2, TECAUX, TECLA
PUBLIC PARAM, SPEED
PUBLIC BUFFER

#include "msp430x16x.h"

;******************************************************************************
;Equates do programa
;******************************************************************************
TA0 EQU 30000 ;PERODO DE 15ms = 30000 / 2MHz

;TECLAS
T1 EQU 11h ;TECLA 1
T2 EQU 21h ;TECLA 2
T3 EQU 41h ;TECLA 3
T4 EQU 81h ;TECLA 4
T5 EQU 12h ;TECLA 5
T6 EQU 22h ;TECLA 6
T7 EQU 42h ;TECLA 7
T8 EQU 82h ;TECLA 8
T9 EQU 14h ;TECLA 9
T10 EQU 24h ;TECLA 10
T11 EQU 44h ;TECLA 11
T12 EQU 84h ;TECLA 12
T13 EQU 18h ;TECLA 13
T14 EQU 28h ;TECLA 14
T15 EQU 48h ;TECLA 15
T16 EQU 88h ;TECLA 16

;******************************************************************************
;Variaveis do programa
;******************************************************************************
ORG 0200h ;ENDEREO INICIAL DA RAM MSP430F169
ESPLINHA DS8 1 ;ESPELHO DA LINHA DO TECLADO
BOUNCE1 DS8 1 ;BOUNCE1 TECLA
BOUNCE2 DS8 1 ;BOUNCE2 TECLA
TECAUX DS8 1 ;TECLA AUXILIAR
TECLA DS8 1 ;TECLA
RESERVA DS8 1 ;RESERVA DE 8 BITS

PARAM DS8 1 ;SENTIDO DE GIRO DO MOTOR
;TIPO DO PASSO: MEIO PASSO, PASSO INTEIRO
;|---------------------------|
;| VALOR | SENTIDO | PASSO |
;|---------------------------|
;| 00h | HORARIO | MEIO |
;| 01h | ANTI_H | MEIO |
;| 02h | HORARIO | INTEIRO |
;| 03h | ANTI_H | INTEIRO |
;|---------------------------|
DSP_ST DS8 1 ;STATUS DO DISPLAY
SPEED DS16 1 ;VELOCIDADE DO MOTOR
BUFFER DS8 4 ;BUFFER DA RS232

;VETORES DE INTERRUPO
ORG 0FFF2h ; VETOR DO UART0RX
DC16 UART0RX_ISR ; NOME DA FUNO DE TRATAMENTO DA INT.

ORG 0FFECh ; Timer_A0 Vector
DW TA0_ISR ; NOME DA FUNO DE TRATAMENTO DA INT.
9

ORG 0FFFAh ; VETOR DO TIMER_B0
DW TB0_INT ; NOME DA FUNO DE TRATAMENTO DA INT.

ORG 0FFFEh
DC16 main

;SEGMENTO DE CDIGO
RSEG CODE

main MOV #0A00h,SP ;INICIALIZA A PILHA
MOV #WDTPW+WDTHOLD,&WDTCTL ;PARA O WATCHDOG

; Seleciona XT2CLK para MCLK
BIC #OSCOFF,SR ; Liga o oscilador
L1 BIC.B #OFIFG,&IFG1 ; limpa OFIFG
MOV #0FFh,R15 ; Delay para estabilizao do cristal
L2 DEC R15
JNZ L2
BIT.B #OFIFG,&IFG1 ; Testa novamente OFIFG
JNZ L1 ; repete o teste se necessario
BIS.B #SELM1+SELS,&BCSCTL2 ; Seleciona XT2CLK para MCLK E SMCLK

CALL #INIT_HW ; INICIALIZA A RS232

;SETA O PORT
MOV.B #0FFh,&P1DIR ;PROGRAMA P1 COMO SAIDA
MOV.B #00h,&P1OUT ;NVEL BAIXO NAS SAIDAS

;PARMETROS INICIAIS DO MOTOR
MOV.B #00h, R15 ;INDEXAO DO VETOR (SENTIDO HORRIO)
MOV.B #00h, PARAM ;SENTIDO HORRIO E MEIO PASSO
MOV #5000, SPEED ;VELOCIDADE

;SETA VALORES DA INTERRUPO A
MOV #TASSEL_2+ID_2+MC_2,&TACTL ; SMCLK/4, continuos mode
MOV #CCIE,&CCTL0 ; CCR0 interrupt enabled
MOV #TA0,&TACCR0 ; PERODO = TA0/2MHz

;SETA VALORES DA INTERRUPO B
MOV #TBSSEL_2+ID_3+MC_2,&TBCTL ; SMCLK/8, modo continuo
MOV SPEED, &TBCCR0 ; PERODO = SPEED/1MHz

CALL #INIDISP ;INICIALIZA DISPLAY
CALL #INITEC ;INICIALIZA VARREDURA DE TECLADO

BIS #GIE, SR ;HABILITA INTERRUPO GLOBAL

;OPES TECLADO
CTR1 MOV.B #01, DSP_ST
CALL #SHOW_DSP
;PARA O MOTOR
BIC #CCIE, &TBCCTL0 ;DESABILITA A INTERRUP0
MOV.B #00h, &P1OUT ;COLOCA A PORTA EM NVEL ZERO
MOV #BUFFER, R8
MOV.B #073h, 0(R8) ;ESCREVE s PARA INDICAR INICIO DE COMANDO
BIC.B #BIT0, 1(R8)
MOV.B #066h, 2(R8) ;ESCREVE f PARA INDICAR FIM DO VETOR
CALL #SEND_RS232
CTR2 CALL #GTEC ;VERIFICA SE TEM TECLA
CMP.B #T15, R4 ;TECLA 15
JEQ CTR1
CMP.B #T2, R4
JEQ CTR3
CMP.B #T3, R4
JEQ CTR4
CMP.B #T6, R4
JEQ CTR5
CMP.B #T7, R4
JEQ CTR6
10
CMP.B #T10, R4
JEQ CTR7
CMP.B #T11, R4
JEQ CTR8
CMP.B #T14, R4
JEQ INICIA_MOTOR
CMP.B #T16, R4
JEQ INC_DSP_ST
JMP CTR2
INC_DSP_ST
INC.B DSP_ST
CMP.B #05, DSP_ST
JNZ SHOW_DSP_ST
MOV.B #01h, DSP_ST
SHOW_DSP_ST
CALL #SHOW_DSP
JMP CTR2
CTR3 MOV.B #02, DSP_ST
BIC.B #01h, PARAM ;MOTOR SENTIDO HORRIO
MOV.B #00h, R15
CALL #SHOW_DSP
MOV #BUFFER, R8
MOV.B #070h, 0(R8) ;ESCREVE p PARA INDICAR INICIO DE COMANDO
MOV.B PARAM, 1(R8)
MOV.B #066h, 2(R8) ;ESCREVE f PARA INDICAR FIM DO VETOR
CALL #SEND_RS232
JMP CTR2
CTR4 MOV.B #02, DSP_ST
BIS.B #01h, PARAM ;MOTOR SENTIDO ANTI-HORRIO
MOV.B #07h, R15
CALL #SHOW_DSP
MOV #BUFFER, R8
MOV.B #070h, 0(R8) ;ESCREVE p PARA INDICAR INICIO DE COMANDO
MOV.B PARAM, 1(R8)
MOV.B #066h, 2(R8) ;ESCREVE f PARA INDICAR FIM DO VETOR
CALL #SEND_RS232
JMP CTR2
CTR5 MOV.B #03, DSP_ST
SUB #250, SPEED ;AUMENTA VELOCIDADE
CMP #500, SPEED ;LIMITA A VELOCIDADE
JEQ LIM_VEL_SUP
CALL #SHOW_DSP
MOV #BUFFER, R8
MOV.B #076h, 0(R8) ;ESCREVE v PARA INDICAR INICIO DE COMANDO
MOV.B SPEED, 1(R8)
SWPB SPEED
MOV.B SPEED, 2(R8)
SWPB SPEED
MOV.B #066h, 3(R8) ;ESCREVE f PARA INDICAR FIM DO VETOR
CALL #SEND_RS232
JMP CTR2
LIM_VEL_SUP
MOV #750, SPEED
CALL #SHOW_DSP
JMP CTR2
CTR6 MOV.B #03, DSP_ST
ADD #250, SPEED ;DIMINUI VELOCIDADE
CMP #10250, SPEED ;LIMITA A VELOCIDADE
JEQ LIM_VEL_INF
CALL #SHOW_DSP
MOV #BUFFER, R8
MOV.B #076h, 0(R8) ;ESCREVE v PARA INDICAR INICIO DE COMANDO
MOV.B SPEED, 1(R8)
SWPB SPEED
MOV.B SPEED, 2(R8)
SWPB SPEED
MOV.B #066h, 3(R8) ;ESCREVE f PARA INDICAR FIM DO VETOR
CALL #SEND_RS232
JMP CTR2
LIM_VEL_INF
11
MOV #10000, SPEED
CALL #SHOW_DSP
JMP CTR2
CTR7 MOV.B #04, DSP_ST
BIC.B #02h, PARAM ;MEIO PASSO
CALL #SHOW_DSP
MOV #BUFFER, R8
MOV.B #070h, 0(R8) ;ESCREVE p PARA INDICAR INICIO DE COMANDO
MOV.B PARAM, 1(R8)
MOV.B #066h, 2(R8) ;ESCREVE f PARA INDICAR FIM DO VETOR
CALL #SEND_RS232
JMP CTR2
CTR8 MOV.B #04, DSP_ST
BIS.B #02h, PARAM ;PASSO INTEIRO
BIT.B #01, PARAM ;TESTA O SENTIDO DO MOTOR
JNZ CORRIGE_R15
MOV.B #00h, R15
CALL #SHOW_DSP
MOV #BUFFER, R8
MOV.B #070h, 0(R8) ;ESCREVE p PARA INDICAR INICIO DE COMANDO
MOV.B PARAM, 1(R8)
MOV.B #066h, 2(R8) ;ESCREVE f PARA INDICAR FIM DO VETOR
CALL #SEND_RS232
JMP CTR2
CORRIGE_R15
MOV.B #07h, R15
CALL #SHOW_DSP
JMP CTR2
INICIA_MOTOR
MOV #CCIE,&TBCCTL0 ;CCR0 -> habilita interrupo
MOV #BUFFER, R8
MOV.B #073h, 0(R8) ;ESCREVE s PARA INDICAR INICIO DE COMANDO
MOV.B #BIT0, 1(R8)
MOV.B #066h, 2(R8) ;ESCREVE f PARA INDICAR FIM DO VETOR
CALL #SEND_RS232
JMP CTR2


;***************************************************************************
; ROTINA QUE MOSTRA A MENSAGEM ATUALIZADA DOS PARMETROS DO MOTOR
;NOME: SHOW_DSP
;ENTRADA: DSP_ST=VALOR DA MENSAGEM QUE DEVE SER EXIBIDA
;SAIDA:
;DESTROI:
SHOW_DSP
CALL #CUR_OFF ;DESLIGA CURSOR
MOV.B #01h, R4 ;INSTRUCAO DE LIMPEZA DO DISPLAY
CALL #ESCINST ;ENVIA A INSTRUCAO
CMP.B #1, DSP_ST
JEQ M1
CMP.B #2, DSP_ST
JEQ M2
CMP.B #3, DSP_ST
JEQ M3
CMP.B #4, DSP_ST
JEQ M4
M1 MOV #0001h, R4 ;L=0 e C=1
CALL #GOTOXY
MOV #STR1, R5 ;ENDEREO DA STRING 'MOTOR DE PASSO'
CALL #MSTRING
MOV #0100h, R4 ;L=1 e C=0
CALL #GOTOXY
MOV #STR2, R5 ;ENDEREO DA STRING 'CLAUDIO L. KUNDE'
CALL #MSTRING
JMP EXIT
M2 MOV #0000h, R4 ;L=0 e C=0
CALL #GOTOXY
MOV #STR3, R5 ;ENDEREO DA STRING 'SENTIDO DE GIRO'
CALL #MSTRING
MOV #0100h, R4 ;L=1 e C=0
12
CALL #GOTOXY
BIT.B #01h, PARAM ;VERIFICA SE O SENTIDO DE GIRO ANTI-HORARIO
JNZ AHR
MOV #STR4, R5
CALL #MSTRING
JMP EXIT
AHR MOV #STR5, R5
CALL #MSTRING
JMP EXIT
M3 MOV #0000h, R4 ;L=0 e C=0
CALL #GOTOXY
MOV #STR6, R5 ;ENDEREO DA STRING 'VELOCIDADE'
CALL #MSTRING
MOV #0100h, R4 ;L=1 e C=0
CALL #GOTOXY
MOV SPEED, R6
CALL #PRINT_RPM ;ESCREVE O VALOR DA VELOCIDADE DO MOTOR

MOV #010Dh, R4 ;L=1 e C=12
CALL #GOTOXY
MOV #STR7, R5 ;ENDEREO DA STRING 'RPM'
CALL #MSTRING
JMP EXIT
M4 MOV #0000h, R4 ;L=0 e C=0
CALL #GOTOXY
MOV #STR8, R5 ;ENDEREO DA STRING 'TIPO DE PASSO'
CALL #MSTRING
MOV #0100h, R4 ;L=1 e C=0
CALL #GOTOXY
BIT.B #02h, PARAM ; VERIFICA SE O PASSO INTEIO
JNZ T_INT
MOV #STR9, R5
CALL #MSTRING
JMP EXIT
T_INT MOV #STR10, R5
CALL #MSTRING
EXIT RET

;TIMER DE 10mS
TA0_ISR
ADD #TA0,&TACCR0 ; PERODO = TA0/2MHz
CALL #VARTEC ; ROTINA DE VARREDURA DO TECLADO
RETI

;TIMER DO MOTOR DE PASSO
TB0_INT
ADD SPEED, &TBCCR0
MOV.B PARAM, R10
CALL #ROTATE ; ROTINA QUE DEVOLVE A POSIO DO
; VETOR DE PASSO QUE SER USADO NO MOTOR
MOV.B &P1OUT, R9 ; NO ESQUECER QUE A PARTE ALTA DO PORT1
AND.B #0F0h, R9 ; ESTA SENDO USADA PELO DISPLAY, POR ISSO
XOR.B STEP(R15), R9 ; FAZER ESSAS MASCARAS
MOV.B R9, &P1OUT ; RODA O MOTOR
RETI

;INTERRUPO DE RX DA UART
UART0RX_ISR
MOV.B RXBUF0, R7
CMP.B #068h, R7 ;RECEBEU SENTIDO HORARIO?
JEQ HOR
CMP.B #061h, R7 ;RECEBEU SENTIDO ANTI-HORARIO?
JEQ AHOR
CMP.B #06Dh, R7 ;RECEBEU MEIO PASSO?
JEQ MEIO
CMP.B #069h, R7 ;RECEBEU PASSO INTEIRO?
JEQ INT
CMP.B #063h, R7 ;RECEBEU INICIAR MOTOR?
JEQ INIC
CMP.B #070h, R7 ;RECEBEU PARA MOTOR?
13
JEQ PARA
CMP.B #02Bh, R7 ;RECEBEU AUMENTA VELOCIDADE?
JEQ VEL_M
CMP.B #02Dh, R7 ;RECEBEU DIMINUI VELOCIDADE?
JEQ VEL_MN

JMP FIM_RX

HOR BIC.B #BIT0, PARAM
JMP FIM_RX
AHOR BIS.B #BIT0, PARAM
JMP FIM_RX
MEIO BIC.B #BIT1, PARAM
JMP FIM_RX
INT BIS.B #BIT1, PARAM
JMP FIM_RX
INIC MOV #CCIE,&TBCCTL0 ;CCR0 -> habilita interrupo
JMP FIM_RX
PARA BIC #CCIE, &TBCCTL0 ;DESABILITA A INTERRUP0
MOV.B #00h, &P1OUT ;COLOCA A PORTA EM NVEL ZERO
JMP FIM_RX
VEL_M SUB #250, SPEED
JMP FIM_RX
VEL_MN ADD #250, SPEED
JMP FIM_RX
FIM_RX RETI


;VALORES PARA MEIO PASSO
STEP DB 00000001b, 00000011b, 00000010b, 00000110b
DB 00000100b, 00001100b, 00001000b, 00001001b

;***************************************************************************
;TABELA DAS STRINGS DO SISTEMA
STR1: DB 'MOTOR DE PASSO',00h,00h
STR2: DB 'CLAUDIO L. KUNDE',00h,00h
STR3: DB 'SENTIDO DE GIRO',00h
STR4: DB 'HORARIO',00h,00h
STR5: DB 'ANTI-HORARIO',00h
STR6: DB 'VELOCIDADE',00h,00h
STR7: DB 'RPM',00h
STR8: DB 'TIPO DE PASSO',00h
STR9: DB 'MEIO PASSO',00h,00h
STR10: DB 'PASSO INTEIRO',00h

END main


Arquivo lcd_tec.s43
Este mdulo foi desenvolvido pela Lanser Sistemas Eletrnicos e utilizado no projeto
para fazer a leitura do teclado, tratamento da tecla pressionada e tambm funes do
display, como inicializao, escrita e posicionamento do cursor. Seu cdigo
apresentado abaixo.

;******************************************************************************
;ROTINAS DE DISPLAY E TECLADO DO KIT MSP430F169
;LANSER SISTEMAS ELETRNICOS LTDA
;07/07/2005
;******************************************************************************

;VARIVEIS EXTERNAS
14
EXTERN ESPLINHA,BOUNCE1,BOUNCE2,TECAUX,TECLA

;ROTINAS GLOBAIS
PUBLIC INIDISP,ESCINST,ESCDADO,GOTOXY,MSTRING,CUR_ON,CUR_OFF
PUBLIC INITEC,GTEC,VARTEC,DECTEC,CHEXASC

#include "msp430x16x.h"

;******************************************************************************
;Equates do DISPLAY LCD
;******************************************************************************
RS EQU 20h ;REGISTER SELECT DO LCD
RW EQU 40h ;READ/WRITE DO LCD
LCD EQU 80h ;ENABLE DO LCD


RSEG CODE
;***************************************************************************
;ROTINAS DE TRATAMENTO DO DISPLAY DE CRISTAL LIQUIDO LCD 16X2
;***************************************************************************
;***************************************************************************
;ROTINA DE INICIALIZACAO DO DISPLAY LCD
INIDISP
MOV.B #38H,R4 ;INSTRUCAO DE CONDICAO DE UTILIZACAO
CALL #ESCINST ;ENVIA A INSTRUCAO
MOV.B #38H,R4 ;INSTRUCAO DE CONDICAO DE UTILIZACAO
CALL #ESCINST ;ENVIA A INSTRUCAO
MOV.B #06H,R4 ;INSTRUCAO DE MODO DE OPERACAO
CALL #ESCINST ;ENVIA A INSTRUCAO
MOV.B #0CH,R4 ;INSTRUCAO DE CONTROLE ATIVO/INATIVO
CALL #ESCINST ;ENVIA A INSTRUCAO
MOV.B #01H,R4 ;INSTRUCAO DE LIMPEZA DO DISPLAY
CALL #ESCINST ;ENVIA A INSTRUCAO
RET

;***************************************************************************
;ROTINA QUE ESCREVE INTRUCAO PARA O DISPLAY E ESPERA DESOCUPAR
;NOME; ESCINT
;ENTRADA: R4 = INSTRUCAO A SER ESCRITA NO MODULO DISPLAY
;SAIDA: -
;DESTROI: -
ESCINST BIC.B #RS+RW,&P1OUT ;SELECIONA ESCRITA NO REG. DE INSTRUES
BIS.B #LCD,&P1OUT ;HABILITA LCD=1
MOV.B #0FFh,&P2DIR ;PORT2 COMO SAIDA
MOV.B R4,&P2OUT ;ESCREVE INSTRUO NO PORT2
BIC.B #LCD,&P1OUT ;FAZ LCD=0
MOV.B #00h,&P2DIR ;PORT2 COMO ENTRADA
BIS.B #RW,&P1OUT ;SELECIONA LEITURA NO REG. DE INSTRUES
ESCI1 BIS.B #LCD,&P1OUT ;HABILITA LCD=1
BIT.B #80h,&P2IN ;TESTA SE LCD OCUPADO BIT 7
BIC.B #LCD,&P1OUT ;FAZ LCD=0
JNE ESCI1
RET

;***************************************************************************
;ROTINA QUE ESCREVE DADO PARA O DISPLAY
;NOME: ESCDADO
;ENTRADA: R4 = DADO A SER ESCRITA NO MODULO DISPLAY
;SAIDA: -
;DESTROI: -
ESCDADO BIC.B #RW,&P1OUT ;SELECIONA ESCRITA
BIS.B #RS+LCD,&P1OUT ;REGISTRADOR DE DADOS RS=1 E HABILITA LCD=1
MOV.B #0FFh,&P2DIR ;PORT2 COMO SAIDA
MOV.B R4,&P2OUT ;ESCREVE INSTRUO NO PORT2
BIC.B #LCD,&P1OUT ;FAZ LCD=0
RET

;***************************************************************************
;ROTINAS QUE POSICIONA O CURSOR
;NOME: GOTOXY
15
;ENTRADA: R4H = LINHA (0 A 1)
; R4L = COLUNA (0 A 15)
;SAIDA: -
;DESTROI: R4,R5
GOTOXY MOV R4,R5
SWPB R5
BIS.B #80h,R4 ;PRIMEIRA POSIO DA LINHA 0
CMP.B #01,R5 ;VERIFICA SE LINHA 1
JNE GTO1
BIS.B #0C0h,R4 ;PRIMEIRA POSIO DE LINHA 1
GTO1 CALL #ESCINST ;ENVIA COMANDO
RET

;*****************************************************************************
;ROTINA QUE MOSTRA UMA STRING NO DISPLAY A PARTIR DA POSICAO DO CURSOR
;NOME: MSTRING
;ENTRADA: R5 = ENDERECO INICIAL DA STRING NA MEMORIA FINALIZADA POR 00H
;SAIDA: -
;DESTROI: R4,R5
MSTRING
MST2 MOV.B @R5+,R4
TST.B R4 ;VERIFICA SE FIM DA STRING
JEQ MST1
CALL #ESCDADO
JMP MST2
MST1 RET

;******************************************************************************
; NOME: CUR_ON E CUR_OFF
; FUNCAO: ROTINA CUR_ON => LIGA CURSOR DO LCD
; ROTINA CUR_OFF => DESLIGA CURSOR DO LCD
; CHAMA: ESCINST
; ENTRADA: -
; SAIDA: -
; DESTROI: R4
CUR_ON: MOV.B #0Fh,R4 ;INST.CONTROLE ATIVO (CUR ON)
JMP CUR1
CUR_OFF: MOV.B #0Ch,R4 ;INST. CONTROLE INATIVO (CUR OFF)
CUR1: CALL #ESCINST ;ENVIA A INSTRUCAO
RET

;***************************************************************************
;ROTINAS DE TRATAMENTO DO TECLADO 4x4
;***************************************************************************
;***************************************************************************
;ROTINA DE INICIALIZAO DO TECLADO
INITEC MOV.B #08h,&P5DIR ;PROGRAMA P5.3 COMO SAIDA
MOV.B #08h,ESPLINHA ;INICIALIZA ESPELHO DE LINHA DO TECLADO
MOV.B #0F7h,&P5OUT ;INICIA VARREDURA DO TECLADO P5.3=0
CLR.B BOUNCE1
CLR.B TECAUX
CLR.B TECLA
RET

;***************************************************************************
;ROTINA OBTEM TECLA
;NOME: GTEC
;ENTRADA: TECLA
;SAIDA: R4=00 SE NO TEM TECLA OU
; R4 = TECLA APERTADA
;T1= 11h, T2= 21h, T3= 41h, T4= 81h
;T5= 12h, T6= 22h, T7= 42h, T8= 82h
;T9= 14h, T10=24h, T11=44h, T12=84h
;T13=18h, T14=28h, T15=48h, T16=88h
;DESTROI: -
GTEC CLR R4
ST.B TECLA ;VERIFICA SE TEM TECLA
JEQ GT1 ;SALTA SE NO TEM TECLA
MOV.B TECLA,R4
CLR.B TECLA
16
GT1 RET

;***************************************************************************
;ROTINA QUE DECODIFICA A TECLA
;NOME: DECTEC
;ENTRADA: R4=VALOR DA TECLA EM COLUNA/LINHA
;SAIDA: R4 DE 00H A 0FH OU R4=10h SE TECLA NO DECODIFICADA
;DESTROI: R5,R6
DECTEC MOV #TABTEC,R5 ;ENDEREO DA TABELA DE TECLAS EM R5
MOV.B #16,R6 ;CONTADOR DE TECLAS
DECT3 CMP.B @R5+,R4
JNE DECT1
DEC.B R6 ;AJUSTA VALOR
MOV.B R6,R4
JMP DECT2
DECT1 DEC.B R6
JNE DECT3
MOV.B #10h,R4 ;TECLA NO DECODIFICADA
DECT2 RET

;TABELA DE TECLA EM COLUNA/LINHA
TABTEC DB 88h,48h,28h,18h
DB 84h,44h,24h,14h
DB 82h,42h,22h,12h
DB 81h,41h,21h,11h

;***************************************************************************
;ROTINA QUE CONVERTE BYTE DE 00h A 0Fh EM ASCII
;NOME: CHEXASC
;ENTRADA: R4=VALOR HEXADECIMAL DE 00h A 0Fh
;SAIDA: R4= VALOR ASCII CORRESPONDENTE
;DESTROI:
CHEXASC CMP.B #10,R4 ;VERIFICA SE NMERO OU LETRA
JHS CHA1
ADD.B #30h,R4 ;CONVERTE NMERO
JMP CHA2
CHA1 ADD.B #37h,R4 ;CONVERTE LETRA
CHA2 RET

;***************************************************************************
;ROTINA DE VARREDURA DO TECLADO - DEVE SER EXECUTADO A CADA 10 A 20ms
;NOME: VARTEC
;ENTRADA: -
;SAIDA: TECLA
;DESTROI: R4
VARTEC MOV.B &P5IN,R4 ;LE PORT DO TECLADO
BIS.B #0Fh,R4 ;SEPARA APENAS COLUNAS
INV.B R4
JEQ VART1 ;SALTA SE NO TEM TECLA
BIS.B R4,TECAUX ;ACUMULA TECLA
BIS.B ESPLINHA,TECAUX ;UNE LINHA E COLUNA
VART1 RRA.B ESPLINHA ;MUDA DE LINHA
JNC VART5 ;SALTA SE NO VARREU TODO O TECLADO
MOV.B #08h,ESPLINHA ;MUDA PARA L3
TST.B TECAUX ;VERIFICA SE TEM TECLA ACUMULADA
JEQ VART3 ;SALTA SE NENHUMA TECLA ACUMULADA
TST.B BOUNCE1 ;VERIFICA SE BOUNCE1
JNE VART2
MOV.B TECAUX,BOUNCE1
JMP VART4
VART2 CMP.B TECAUX,BOUNCE1 ;VERIFICA SE MESMA TECLA
JNE VART3 ;SALTA SE TECLA DIFERENTE
TST.B BOUNCE2 ;VERIFICA SE BOUNCE2
JNE VART6
MOV.B TECAUX,BOUNCE2
JMP VART4
VART6 CMP.B TECAUX,BOUNCE1 ;VERIFICA SE MESMA TECLA
JNE VART3 ;SALTA SE TECLA DIFERENTE
MOV.B TECAUX,TECLA ;CONFIRMA A TECLA

17
VART3 CLR.B BOUNCE1
CLR.B BOUNCE2
VART4 CLR.B TECAUX
VART5: MOV.B ESPLINHA,&P5DIR ;PROGRAMA LINHA CORRESPONDENTE P5.X COMO SAIDA
MOV.B ESPLINHA,R4
INV.B R4
MOV.B R4,&P5OUT ;ACIONA LINHA CORRESPONDENTE P5.X
RET

END


Arquivo step.s43
Este mdulo responsvel por configurar e calcular os parmetros referentes ao
motor. A funo rotate calcula o valor da varivel de indexao que ser utilizada
pelo vetor step e disparar o passo correto no motor. O mtodo print_rpm calcula a
rotao do motor em rotaes por minuto, baseado no valor da interrupo do
TimmerB. A equao basicamente a seguinte
10
15000
rB tempoTimme
rpm =
Para o calculo da velocidade, o mtodo print_rpm invoca o mtodo divide
responsvel por fazer operaes de diviso. Uma ateno especial para este mtodo
interessante, pois as operaes de diviso so realizadas com iteraes conforme
ilustra o diagrama abaixo.


O cdigo do arquivo step.s43 apresentado a seguir.
18
;******************************************************************************
;ROTINAS DOS PARAMETROS DO MOTOR DE PASSO
;CLUDIO LUIZ KUNDE
;16/08/2005
;******************************************************************************

;VARIVEIS EXTERNAS
EXTERN ESCDADO, CHEXASC, PARAM

;ROTINAS GLOBAIS
PUBLIC ROTATE, PRINT_RPM

#include "msp430x16x.h"

;******************************************************************************
;Equates do motor
;******************************************************************************
;RS EQU 20h ;REGISTER SELECT DO LCD
;RW EQU 40h ;READ/WRITE DO LCD
;LCD EQU 80h ;ENABLE DO LCD

RSEG CODE
;***************************************************************************
;ROTINAS DE TRATAMENTO DO MOTOR DE PASSO
;***************************************************************************
;***************************************************************************
;ROTINA DE GIRO
;ENTRADA: R15 = POSICAO DO VETOR DE INDEXAO DO PASSO DO MOTOR
; R10 = VALOR DA VARIAVEL PARAM
;SAIDA: R15 = NOVA POSICAO DO VETOR DE INDEXAO DO PASSO DO MOTOR
;DESTROI: R10
ROTATE
CMP #00h, R10
JEQ INST_1
CMP #01h, R10
JEQ INST_2
CMP #02h, R10
JEQ INST_3
CMP #03h, R10
JEQ INST_4
INST_1 INC.B R15
JMP LIM_SUP
INST_2 DEC.B R15
JMP LIM_INF
INST_3 INCD.B R15
JMP LIM_SUP
INST_4 DECD.B R15
JMP LIM_INF
LIM_SUP CMP #08, R15
JNE END_FUNC
MOV.B #00h, R15
JMP END_FUNC
LIM_INF CMP #0FFh, R15
JNE END_FUNC
MOV.B #07h, R15
END_FUNC
RET

;***************************************************************************
;FUNO QUE FAZ DIVISO
;ENTRADA: R11 = DIVISOR
; R12 = RESTO
; R13 = QUOCIENTE
; R14 = DIVIDENDO (AUXILIAR)
;SAIDA: R13 = RESULTADO INTEIRO
; R12 = RESTO
;DESTROI: R11, R14
DIVIDE
MOV #00h, R13
MOV #00h, R12
19

COMPARA CMP #00h, R14
JN FIM
SUB R11, R14
INC R13
JMP COMPARA
FIM DEC R13
MOV R14, R12
ADD R11, R12
RET

;***************************************************************************
;FUNO QUE IMPRIME A VELOCIDADE DO MOTOR
;ENTRADA: R6 = VALOR DA VARIAVEL SPEED
;SAIDA:
;DESTROI: R6
PRINT_RPM
BIT.B #02h, PARAM ;TESTA SE ESTA EM PASSO INTEIRO
JNZ DOBRA
JMP NORMAL
DOBRA RRA R6
NORMAL MOV R6, R14
MOV #10, R11
CALL #DIVIDE ;DIVIDE A VELOCIDADE POR 10
MOV R13, R11 ;GUARDA O RESULTADO EM R11
MOV #15000, R14
CALL #DIVIDE ;R13 POSSUI O VALOR DA VELOCIDADE EM RPM
MOV #10, R11
MOV #00h, R6 ;CONTA EM QUANTAS PARTES O NUMERO FOI DIVIDIDO
COMP CMP #10, R13 ;PARTICIONA O NUMERO PARA MOSTRAR NO DISPLAY
JHS DIV_10
JMP SHOW
DIV_10 ;PUSH R6
MOV R13, R14
CALL #DIVIDE
;POP R6
PUSH R12 ;COLOCA O RESTO NA PILHA
INC R6 ;INCREMENTA R6
JMP COMP
SHOW MOV R13, R4 ;IMPRIME A PARTE INTEIRA DA OPERAO
CALL #CHEXASC
CALL #ESCDADO
CMP_RESTO
CMP #00h, R6
JEQ END_PRINT
DEC R6
POP R12
MOV R12, R4
CALL #CHEXASC ;IMPRIME OS RESTOS GUARDADOS NA PILHA
CALL #ESCDADO
JMP CMP_RESTO
END_PRINT
RET

END


Arquivo serial.s43
Este mdulo responsvel pela comunicao serial entre o kit e aplicativo no pc. A
comunicao foi configurada para funcionar a uma taxa de 2400 bits por segundo.
Para a interrupo da UART utilizou-se ACLK no cristal de 32768Hz. Utilizando-se
uma calculadora de taxas de bit (acesse o endereo
20
http://mspgcc.sourceforge.net/baudrate.html) chegou-se aos seguintes valores de
0Dh para U0BR0 e 6Bh para U0MCTL. O cdigo apresentado a seguir.

;******************************************************************************
;ROTINAS DA COMUNICAO SERIAL
;CLUDIO LUIZ KUNDE
;24/08/2005
;******************************************************************************

PUBLIC INIT_HW, SEND_RS232

#include "msp430x16x.h"

;******************************************************************************
;Equates do programa
;******************************************************************************
UTCTL_ACLK EQU SSEL0


RSEG CODE


;***********************************************************
;FUNO QUE INICIALIZA O HARDWARE PARA COMUNICAO SERIAL
;ENTRADA:
;SAIDA:
;DESTROI:
INIT_HW
;Setup UART0
BIS.B #BIT4, &P3SEL ;INICIALIZA FUNO NO PINO
BIS.B #BIT4, &P3DIR
BIS.B #UTXE0, &ME1 ;HABILITA MODULO DE TX
MOV.B #CHAR, &U0CTL
MOV.B #TXEPT+UTCTL_ACLK, &U0TCTL ;RESET UART
;SETA PARA TAXA DE 2400 COM ACLK
MOV.B #0Dh, &U0BR0
MOV.B #00h, &U0BR1
MOV.B #6Bh, &U0MCTL

BIS.B #UTXIFG0, &IFG1 ;SETA FLAG DO TX
BIS.B #BIT5, &P3SEL ;HABILITA FUNO DO PINO DE RX

BIS.B #URXE0, &ME1 ;HABILITA MODULODE RX
MOV.B #URXEIE, &U0RCTL ;RESETA UART
BIS.B #URXIE0, &IE1
RET

;***********************************************************
;FUNO QUE TRANSMITE O CONTEDO NA VARIAVEL BUFFER
;ENTRADA: R8 = ENDEREO DO BUFFER
;SAIDA:
;DESTROI: R8
SEND_RS232
NEXT CLR R11
MOV.B @R8+, R11 ;PEGA O DADO NA POSIO 0 DA VARIAVEL BUFFER
CMP.B #066h, R11 ;VERIFICA SE f -> FIM DA TRANSMISSAO
JEQ END_RS232
MOV.B R11, TXBUF0 ;TRANSMITE O DADO PELA SERIAL
WT BIT.B #TXEPT, &U0TCTL ;TESTA SE JA FOI TRANSMITIDO (FILA DE ESPERA)
JNZ NEXT
JMP WT
END_RS232
RET

END
21

5. Software do PC
O aplicativo do lado PC, para operar o motor e receber os comandos oriundos do kit
foi desenvolvido com o ambiente de desenvolvimento da Borland C++Builder verso
6.0. O aplicativo consiste basicamente em uma interface que apresenta o valor dos
parmetros do motor, atualizados em tempo real, e um teclado semelhante ao do kit
para fazer as mesmas operaes sobre o motor.

Toda a parte de tratamento da comunicao serial foi feita utilizando-se a API do
Windows, que permite o bom funcionamento do mesmos em vrias verses de
plataforma Windows, mas embora algumas diferenas existam recomendvel que
se utilize o programa sob o Windows XP, no qual foi compilado o projeto.

O aplicativo consiste basicamente em tres mdulos. O primeiro a configurao dos
parmetros da porta serial. Para isto apresentado uma interface ao usurio logo
que ele inicia o aplicativo para configurar estes parmetros. Por default utiliza-se a
taxa de 2400bps, 8 bits de dados, bit de parada 1 e sem paridade que a forma que
est configurado o kit para receber e transmitir os pacotes.

O segundo mdulo consiste em transmitir as informaes via rs232. E por fim, o
ltimo mdulo que um pouco mais complexo, uma Thread responsvel por ficar
monitorando a porta para verificar se algum pacote chegou na mesma.

A seguir apresentado o cdigo do arquivo Main.cpp responsvel por controlar o
aplicativo e inicializar a comunicao com a porta serial.
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Main.h"
#include "ReadThread.h"
#include "SerialCfg.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

22
//Variveis Globais
HANDLE hComm = NULL;
TRead *ReadThread;
COMMTIMEOUTS ctmoNew = {0}, ctmoOld;
AnsiString ComName;
AnsiString ComParam;
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
Form2 = new TForm2(Application);
Form2->ShowModal();
delete Form2;

DCB dcbCommPort;

// Abre a porta com.
hComm = CreateFile(ComName.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
0);

// Se a porta no pode ser aberta sai do programa.
if(hComm == INVALID_HANDLE_VALUE) {
Application->MessageBox("No foi possvel abrir a porta de comunicao. Verifique se a mesma esta em uso e tente
novamente", "Erro ao abrir a porta", MB_OK+MB_ICONERROR);
Application->Terminate();
}

// Seta os tempos da porta com
GetCommTimeouts(hComm,&ctmoOld);
ctmoNew.ReadTotalTimeoutConstant = 10;
ctmoNew.ReadTotalTimeoutMultiplier = 0;
ctmoNew.WriteTotalTimeoutMultiplier = 0;
ctmoNew.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(hComm, &ctmoNew);

// Seta taxa de transferncia, paridade, tamanho da word e bit de parada.
dcbCommPort.DCBlength = sizeof(DCB);
GetCommState(hComm, &dcbCommPort);
BuildCommDCB(ComParam.c_str(), &dcbCommPort);
SetCommState(hComm, &dcbCommPort);

// Ativa a Thread. O argumento setado como falso inicializa
// a Thread e a coloca em modo suspenso.
ReadThread = new TRead(false);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
// Termina a Thread.
ReadThread->Terminate();

// Aguarda a Thread Finalizar
// Remove o intervalo do buffer da porta com
// Restaura os antigos valores de tempo da porta
// Fecha a porta novamente
Sleep(250);
PurgeComm(hComm, PURGE_RXABORT);
SetCommTimeouts(hComm, &ctmoOld);
CloseHandle(hComm);
23
}
//---------------------------------------------------------------------------

void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
TransmitCommChar(hComm, 'h');
Giro->Caption = "Horrio";
}
//---------------------------------------------------------------------------


void __fastcall TForm1::BitBtn2Click(TObject *Sender)
{
TransmitCommChar(hComm, 'a');
Giro->Caption = "Anti-Horrio";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::BitBtn5Click(TObject *Sender)
{
TransmitCommChar(hComm, '+');
short vel = StrToInt(Velocidade->Caption.SubString(1, Velocidade->Caption.Length()-3).Trim());
try {
vel = 150000/vel;
vel -= 250;
vel = 150000/vel;
} catch(...) {
vel = 0;
}
Velocidade->Caption = IntToStr(vel) + " rpm";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::BitBtn4Click(TObject *Sender)
{
TransmitCommChar(hComm, '-');
short vel = StrToInt(Velocidade->Caption.SubString(1, Velocidade->Caption.Length()-3).Trim());
try {
vel = 150000/vel;
vel += 250;
vel = 150000/vel;
} catch(...) {
vel = 0;
}
Velocidade->Caption = IntToStr(vel) + " rpm";

}
//---------------------------------------------------------------------------

void __fastcall TForm1::BitBtn3Click(TObject *Sender)
{
TransmitCommChar(hComm, 'm');
Passo->Caption = "Meio Passo";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::BitBtn6Click(TObject *Sender)
{
TransmitCommChar(hComm, 'i');
Passo->Caption = "Passo Inteiro";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::BitBtn7Click(TObject *Sender)
{
TransmitCommChar(hComm, 'c');
Status->Caption = "Em funcionamento";
Velocidade->Caption = "30 rpm";
}
//---------------------------------------------------------------------------
24

void __fastcall TForm1::BitBtn8Click(TObject *Sender)
{
TransmitCommChar(hComm, 'p');
Status->Caption = "Parado";
Velocidade->Caption = "0 rpm";
}
//---------------------------------------------------------------------------

O arquivo a seguir, SerialCfg.cpp, configura os parmetros da porta serial no pc. O
cdigo apresentado a seguir.
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "SerialCfg.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
extern AnsiString ComName;
extern AnsiString ComParam;
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{

}
//---------------------------------------------------------------------------

void __fastcall TForm2::BtAplicarClick(TObject *Sender)
{
ComName = ComboBox1->Items->Strings[ComboBox1->ItemIndex];
// Agrupa os parmetros separados por ponto e vrgula
ComParam = ComboBox2->Items->Strings[ComboBox2->ItemIndex];
ComParam += ",";
if (ComboBox4->ItemIndex == 2) {
ComParam += "N,";
}
ComParam += ComboBox3->Items->Strings[ComboBox3->ItemIndex];
ComParam += ",";
ComParam += ComboBox5->Items->Strings[ComboBox5->ItemIndex];
BtAplicar->Enabled = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::BtOkClick(TObject *Sender)
{
if (BtAplicar->Enabled) {
BtAplicarClick(Sender);
}
}
//---------------------------------------------------------------------------

E por fim apresentado o arquivo ReadThread.cpp responsvel por ficar escutando
os pacotes que chegam na porta serial e atualizar os parmetros do motor na tela da
interface.
//---------------------------------------------------------------------------

#pragma hdrstop

#include "Main.h"
#include "ReadThread.h"
25

//---------------------------------------------------------------------------

#pragma package(smart_init)

// Variveis Globais
extern HANDLE hComm;
char InBuff[3];
short step;

//---------------------------------------------------------------------------
__fastcall TRead::TRead(bool CreateSuspended)
: TThread(CreateSuspended)
{
}

//---------------------------------------------------------------------------
void __fastcall TRead::DisplayIt()
{
// Atualiza os parametros do motor para visualizao
if (InBuff[0] == 's') {
if (InBuff[1] & 0x01) {
Form1->Status->Caption = "Em funcionamento";
Form1->Velocidade->Caption = "30 rpm";
}
else {
Form1->Status->Caption = "Parado";
Form1->Velocidade->Caption = "0 rpm";
}
}
else if (InBuff[0] == 'p') {
if (InBuff[1] == 0x00) {
Form1->Giro->Caption = "Horrio";
Form1->Passo->Caption = "Meio Passo";
step = 1;
}
else if (InBuff[1] == 0x01) {
Form1->Giro->Caption = "Anti-Horrio";
Form1->Passo->Caption = "Meio Passo";
step = 1;
}
else if (InBuff[1] == 0x02) {
Form1->Giro->Caption = "Horrio";
Form1->Passo->Caption = "Passo Inteiro";
step = 2;
}
else if (InBuff[1] == 0x03) {
Form1->Giro->Caption = "Anti-Horrio";
Form1->Passo->Caption = "Passo Inteiro";
step = 2;
}
}
else if (InBuff[0] == 'v') {
unsigned short vel = 0;
unsigned short tmp = 0;
vel = InBuff[2];
vel = vel << 8;
tmp = InBuff[1] & 0x00FF;
vel ^= tmp;
vel = step*15000/(vel/10);
Form1->Velocidade->Caption = IntToStr(vel) + " rpm";
}
}

//---------------------------------------------------------------------------
void __fastcall TRead::Execute()
{
//---- Coloque o cdigo da Thread aqui ----
DWORD dwBytesRead;
step = 1;
26

// O objeto da Thread automaticmanete destrudo quando terminado
FreeOnTerminate = true;

while(1) {
// Tenta ler caracteres da porta serial.
// Se no existe nada, espera o timeout e tenta novamente.
// Se existe, captura o caracter.
ReadFile(hComm, InBuff, 3, &dwBytesRead, NULL);

if(dwBytesRead) {
//InBuff[dwBytesRead] = 0; // String terminada com null
Synchronize(DisplayIt); // Componentes VCL devem ser usados com Synchronize
}
}
}
//---------------------------------------------------------------------------
27
6. Concluso
Todos os requisitos do projeto descritos na proposta foram alcanados. Foi possvel
controlar de forma adequada o sentido de giro do motor, o tipo de passo e a
velocidade do mesmo dentro uma faixa tolervel antes que o mesmo travasse,
deixando de operar.

A comunicao serial tambm foi alcanada com xito e foi possvel comunicar a
placa do kit com o aplicativo do PC sem maiores problemas, alcanando-se um
controle total do motor tanto pela interface do PC quanto pelo teclado do kit.

O projeto foi importante para aprender as peculiaridades e programao do
microcontrolador MSP430F169. A utilizao dos Timers A e B ficou bem conceituada
e aplicada, assim como o tratamento da comunicao serial utilizando a UART.

Como sugestes futuras a implementao do cdigo poderia ser passada para a
linguagem C, para fazer uma posterior comparao com o cdigo assembler com
relao ao tamanho e tambm poderia ser usado um contador do timer A para
acionar o motor livrando o timer B para outra funo. Por fim poderia ser colocado
tambm um sensor de temperatura nas entradas analgicas do microcontrolador e
atravs da medio da temperatura alterar a velocidade do motor.