Você está na página 1de 75

Agradecimentos

Gostaria de agradecer a todos que me ajudaram neste projeto, dando novas idias,
ajudando a montar os circuitos ou simplesmente tentando aprender tudo o que eu fiz para que
futuramente esse projeto ainda seja melhorado. Entre essas pessoas posso citar especialmente Felipe
Scofano, Cludio Duvivier, Jlio Guedes, Rafael Caram, Felipe Garschagen, Filipe Sacchi, Bruno
Favoreto, Leonardo Salvini, Rodger Moulin, Gustavo Lima, Ilana Nigri, Mariana Bystronski e
Marcio Barros, todos eles integrantes da equipe RioBotz a qual orgulhosamente fiz parte. Gostaria
de agradecer tambm ao grande Prof. Marco Antonio Meggiolaro, coordenador da equipe e meu
orientador, aos professores Prof. Mauro Schwanke, Prof. Mauro Speranza, Prof. Luiz Antonio
Gusmo, Prof. Francisco Rubens, Prof. Moiss Szwarcman, por tudo que me ensinaram. Outros
agradecimentos vo para meus pais, Zeev Lucyan Maimon e Maria Ines Brito W. Maimon, meus
grandes amigos, Felipe Belo, Ricardo Moreno, Rubens, Luiz, Daniel Camerini e Thiago Salcedo. E
no poderia esquecer da prpria PUC-Rio por possibilitar tal projeto, alm de prover toda a ajuda,
suporte e infra-estrutura necessrios, com o CETUC e ITUC, alm do Laboratrio de Controle e
Automao.
I
Resumo
Este projeto apresenta a concepo de um conjunto de circuitos eletrnicos de controle e de
potncia para promover uma soluo completa para controle de velocidade de motores de corrente
contnua (CC) de alta potncia, atravs de um controle remoto comum de aeromodelos.
O circuito de potncia formado por uma Ponte H, capaz de conduzir at 160A
continuamente, podendo suportar picos de mais de 400A, sem dissipadores, sendo refrigerados
apenas por um ventilador, tornando o circuito leve. Este circuito recebe sinais de velocidade e
direo de acionamento de uma placa de controle e aciona a Ponte H apropriadamente, incorporando
medidas de segurana para evitar condies que poderiam danificar o circuito no caso de problemas
no circuito de controle. O circuito de potncia tambm possui um regulador de tenso para alimentar
a si prprio e o circuito de controle.
O circuito de controle recebe os sinais do receptor de rdio, os interpreta e os converte em
sinais para o acionamento de dois motores (sada para duas eletrnicas de potncia). O controle de
velocidade do motor feito atravs de PWM (Pulse Width Modulation), que funciona modificando a
tenso mdia sobre o motor e, portanto, sua velocidade, j que esta depende diretamente da tenso
aplicada. O sinal de PWM utilizado possui freqncia de aproximadamente 4 kHz, ou seja, a cada
250s, o circuito de sinais envia um pulso, juntamente com o sinal de direo, para o circuito de
potncia.
O conjunto testado em um sistema robtico com motores de alta potncia, apresentando
resultados satisfatrios no controle de velocidade, sem aquecimento significativo das placas mesmo
sob condies de correntes mdias de at 100A.
II

Abstract
This work presents the development of control and power electronics to provide velocity
control of high power direct current (DC) motors, using a standard radio control system as an input.
The control circuit receives signals from a radio control receiver, generating proper signals
to drive two DC motors through outputs to two power circuits. The speed control is achieved
through PWM (Pulse Width Modulation), which works by changing the average voltage applied to
the motor and, therefore, its speed, since they are directly proportional. The PWM signal has an
approximate frequency of 4 kHz, meaning that the control circuit sends a pulse to the power circuit
every 250 microseconds, along with the direction signal.
The power circuit is built around an H bridge, able to handle up to 160A continuously, and
withstanding current peaks higher than 400A. It only uses a cooling fan to dissipate the heat, without
the need of heat sinks, resulting in a very light and portable system. The power circuit receives
velocity and direction signals from the control board, acting on the H bridge accordingly. It also
incorporates safety measures to prevent damage to the circuit caused by unexpected problems in the
signals from the control board. The power circuit also includes a voltage regulator to provide low
voltage power to both itself and the control board.
The circuits are tested in a robotic system with high power DC motors, presenting
satisfactory speed control performance, without any significant heating of the boards for average
currents up to at least 100A.

III
Sumrio
AGRADECIMENTOS I
RESUMO II
ABSTRACT III
1 INTRODUO 1
2 MOTORES CC 2
2 2.1. Funcionamento de motores CC
4 2.2. Acionamento dos motores
5 2.3. Modulao por Largura de Pulso (PWM)
6 2.4. Ponte H
3 CIRCUITO DE POTNCIA 9
10 3.1. Transistor Bipolar de Juno (BJT)
13 3.2. Transistor de Efeito de Campo tipo Metal - xido - Semicondutor (MOSFET)
15 3.3. Circuito de Acionamento da Ponte H
17 3.4. Circuito de Completo de Potncia
4 CIRCUITO DE CONTROLE 21
22 4.1. Sinais de Entrada e Sada
24 4.2. Descrio do Hardware
4.3. Software do Circuito de Controle 27
4.3.1. Configurao do PIC 28
4.3.2. Rotina de Interrupo 30
4.3.3. Normalizao e validao do pulso do receptor 33
4.3.4. Inverso do PWM 35
IV
4.3.5. Inicializao da Placa de Potncia 37
4.3.6. Limitao da taxa de variao da sada 38
4.3.7. rea morta (Dead Band) 40
4.3.8. Modos de controle 40
4.3.9. Rotina de Calibragem 42
4.3.10. Acionamento do rel 43
4.3.11. Rotina principal (main) 44
5 CONCLUSES E SUGESTES DE TRABALHOS FUTUROS 48
6 BIBLIOGRAFIA 52
ANEXO A - ESQUEMTICOS 53
ANEXO B CDIGO COMPLETO 55


V
ndice de Figuras

Fig. 2.1 Rotor, explicitando o comutador e os enrolamentos do motor. 2
Fig. 2.2 - Modelagem eltrica de um motor DC 3
Fig. 2.3 (a) PWM com D prximo de 100%; (b) D = 50%; (c) D prximo de 0%. 5
Fig. 2.4 Ponte H bsica 6
Fig. 2.5 Ponte H e seus modos de funcionamento. 7
Fig. 3.1 Modos de operao para chaveamento de um transistor bipolar. 10
Fig. 3.2 Formas de onda no transistor. a) melhor caso; b) pior caso. 12
Fig. 3.3 Modos de operao para um MOSFET. 13
Fig. 3.4 Circuito de acionamento dos FETs. 15
Fig. 3.5 Diagrama de blocos do HIP4081A 17
Fig. 3.6 Diagrama funcional de metade do HIP4081A 18
Fig. 4.1 Sinal do Receptor 22
Fig. 4.2 Pinagem do PIC16F876A. 24
Fig. 4.3 Circuito de sada da placa de controle. 25
Fig. 4.4 Circuito do rel e LED de status. 26
Fig. 4.5 Diagrama de blocos do software 27
Fig. 4.6 Exemplo da operao XOR em dois bytes 31
Fig. 4.7 Operao de deslocamento esquerda 34
Fig. 4.8 Operao de complemento a 2 36
Fig. A.1 Esquemtico do circuito de controle 53
Fig. A.2 Esquemtico da placa de potncia. 54

VI
ndice de Tabelas



Tabela 4.1 Sinais sugeridos para a placa de potncia 22
Tabela 4.2 Sinais sugeridos modificados para a placa de potncia 23
Tabela 4.3 Configurao do micro-controlador 28
Tabela 4.4 Campos de dados das variveis servo1 a servo4 33
Tabela 4.5 Nmeros positivos e negativos de 4 bits 36

VII
1 Introduo
Em vrias aplicaes da robtica moderna, existe a necessidade de motores eltricos
potentes, muitas vezes com potncia eltrica especificada maior do que 1 kW. Devido a isso,
necessria a utilizao de circuitos com maior complexidade para o controle desses motores. Uma
simples ponte H feita de chaves ou rels no conseguiria suportar toda a corrente gerada no motor
em situaes em que o mesmo estivesse em alta velocidade em uma direo sendo revertido
completamente na direo oposta. Nesse caso, uma alta corrente eltrica seria gerada e, com isso,
uma dissipao de potncia que poderia danificar o circuito.
Para essas aplicaes de alta potncia, foram desenvolvidos, neste projeto, um conjunto de
circuitos modulares circuito de controle e de potncia que, juntos, provm uma soluo completa
para controle destes motores, atravs de um controle remoto comum de aeromodelos.
Esta dissertao est organizada em cinco captulos. No Captulo 2 feita uma introduo
teoria de motores CC, alm de mostrar as formas de controlar estes tipos de motores. O Captulo 3
descreve a parte de potncia do circuito de acionamento dos motores. No Captulo 4 temos toda a
descrio do hardware e software do circuito de controle dos. E, finalmente, no Captulo 5, as
concluses do trabalho.
1
2 Motores CC
2.1. Funcionamento de motores CC
Para entender os modos acionamento de motores CC (Corrente Contnua) necessrio
entender seus fundamentos. Os motores so normalmente formados por um im permanente fixo,
que forma o estator, e um rotor que possui vrios enrolamentos. Esse enrolamento gera um campo
magntico que, em conjunto com o campo do im, gera um torque no rotor. Para que se tenha uma
sada com torque constante, os enrolamentos devem ser comutados continuamente, tarefa feita pelo
comutador presente no rotor e pelas escovas, presa na carcaa do motor.


Fig. 2.1 Rotor, explicitando o comutador e os enrolamentos do motor (motor NPC-T74).

Eletricamente, o motor CC pode ser modelado por uma resistncia, uma indutncia e uma
fonte de tenso, cujo valor diretamente proporcional velocidade do motor, todos em srie.
2

Fig. 2.2 - Modelagem eltrica de um motor DC
Como se pode perceber pela Figura 2.2, a corrente no motor expressa pela equao (1):
+ + = K I R
dt
dI
L V
a
a
a
(1)
onde,
- V
a
a tenso aplicada nos terminais do motor;
- I
a
a corrente passando atravs do motor;
- K uma constante que, multiplicada pela velocidade do eixo, gera a tenso induzida
quando o rotor est girando (efeito gerador);
- a velocidade angular do eixo.

3
2.2. Acionamento dos motores
Ao analisar a modelagem dos motores CC, fica claro que variando a tenso nos terminais
do motor, varia-se sua velocidade e caso seja necessrio mudar a direo do motor, necessrio
inverter os terminais do motor ou gerar uma tenso negativa entre seus terminais. Portanto, um
controle simples em que um rel fica encarregado de inverter os terminais do motor e um regulador
de tenso linear gera a tenso necessria para o acionamento do motor pode ser facilmente
implementado.
Apesar de ser bem simples, essa abordagem tem problemas srios, sendo o principal deles a
baixa eficincia do circuito, especialmente em baixas tenses de acionamento, j que toda a energia
que no utilizada pelo motor dissipada no regulador linear. Por exemplo, caso esse mtodo fosse
utilizado para controlar o motor NPC-T64 [1], que possui uma resistncia interna de
aproximadamente 0.22 e acionado por uma tenso de 24 V, fazendo-o girar metade de sua
velocidade mxima, tendo 12 V nos seus terminais, teramos uma corrente de 55 A passando
tambm pelo regulador de tenso, que dissiparia os 12 V restantes. Isso geraria no total uma
dissipao de potncia de 660 W, o que seria invivel, j que essa potncia seria desperdiada em
forma de calor que provavelmente queimaria o regulador de tenso caso ele no fosse grande o
suficiente para dissipar eficientemente o calor para suportar tamanha potncia.
Esse mtodo ainda possui outro problema, este devido indutncia do motor. Ao utilizar o
rel para inverter os terminais do motor, a corrente estar sendo desligada quase instantaneamente e,
devido a isso, uma tenso muito grande ser gerada pela indutncia, gerando arcos nos terminais do
rel, o que diminui sua vida til.
4
2.3. Modulao por Largura de Pulso (PWM)
Para conseguir uma eficincia maior e circuitos menores, necessrio utilizar um mtodo
diferente para variar a velocidade do motor, conhecido pela sigla em ingls de PWM (Pulse Width
Modulation, Modulao por Largura de Pulso). Esse mtodo consiste em ligar e desligar o motor,
numa freqncia fixa, atravs de uma chave, normalmente algum tipo de transistor (Bipolar ou
MOSFET), fazendo com que o motor gire numa velocidade proporcional relao entre o tempo
ligado (T
on
) e perodo (T). Essa relao chamada de Duty Cycle (D) e, se multiplicada pela tenso
de pico (tenso de alimentao do motor), temos uma tenso mdia que equivale tenso DC que
teria que ser aplicada para fazer o motor girar mesma velocidade.


Fig. 2.3 (a) PWM com D prximo de 100%; (b) D = 50%; (c) D prximo de 0%.
Na Figura 2.3, temos trs formas de ondas geradas com PWM, numa freqncia fixa. A
Figura 2.3(a) mostra o PWM com um D de quase 100%, ou seja, o motor se comporta como se
estivesse recebendo quase toda a sua tenso nominal. J na Figura 2.3(b) o motor estaria girando
aproximadamente a metade de sua velocidade mxima e na 2.3(c) estaria em uma velocidade muito
baixa.
A eficincia do circuito , idealmente, 100%, j que a chave que acionaria o motor no tem
perdas. Na prtica, isto no ocorre devido s perdas, tanto esttica quanto dinmicas, nos transistores
utilizados. Apesar disso, a eficincia de um controlador bem projetado est normalmente acima dos
90%.

5
2.4. Ponte H
A reverso do motor ainda um problema utilizando os mtodos citados anteriormente. As
duas formas apresentadas para implementar a reverso so inverter os terminais do motor ou gerar
uma tenso negativa para acion-lo. Inverter os terminais muito complexo, envolvendo a utilizao
de chaves ou rels, o que impraticvel, devido dificuldade de encontr-los. H tambm o
problema do alto preo de componentes qualificados para suportar altas correntes, alm do fato de
ser necessrio desconectar os fios momentaneamente para que os terminais sejam trocados. J a
opo de gerar tenso negativa tambm invivel devido complexidade do circuito necessrio
para isto, tendo uma bateria como alimentao principal do circuito.
Uma terceira opo a utilizao de uma ponte H. Ela possui este nome devido forma em
que as chaves e a carga esto dispostas no circuito. Ela a melhor escolha por no ser necessrio
criar tenses negativas e nem desconectar os terminais para que eles sejam trocados.

Fig. 2.4 Ponte H bsica
A Figura 2.4 mostra uma ponte H bsica. Fechando as chaves S1 a S4 numa ordem fixa,
pode-se fazer o motor girar para frente, para trs, assim como frear o motor. Outra vantagem o fato
de as chaves poderem ser transistores que podem ser chaveados rapidamente, suportam facilmente
altas correntes, e so baratos e acessveis.
6

Fig. 2.5 Ponte H e seus modos de funcionamento.
Na Figura 2.5 as chaves j foram substitudas por transistores tipo MOSFET, mostrando um
circuito bsico da ponte H. Para fazer o motor girar para frente, a corrente sai da bateria, passa pelo
MOSFET Hi1, passa pelo motor e por Lo2, como mostrado na curva A. Para girar para trs, os
MOSFETs Hi1 e Lo2 devem ser desativados, ativando-se o Hi2 e Lo1, fazendo a corrente percorrer
o caminho B.
Para frear o motor h duas opes, ou usar os MOSFETs Lo1 e Lo2 (curva C), ou usar Hi1
e Hi2 (curva D). Em ambas as opes os terminais do motor so curtados. Esse efeito de frenagem
ao curtar os terminais chamado de freio motor e acontece devido ao fato de toda a energia do
motor estar sendo dissipada somente na resistncia interna deste, que , normalmente, muito
pequena, fazendo com que a energia se dissipe rapidamente, parando efetivamente o motor.
Um grande problema de pontes H um efeito chamado shoot-through, que acontece ao
acionar as duas chaves de um mesmo lado da ponte. Quando isso acontece, a bateria sofre um curto,
gerando uma descarga muito grande de corrente que, em geral, faz com que as chaves sejam
destrudas completamente. Na Seo 3.3 sero discutidas tcnicas para evitar esse efeito.
Adicionar PWM ponte H bastante simples. Ao girar para frente, basta manter Hi1
permanentemente ligado e Lo2 ligado durante o T
on
, no se esquecendo de manter Hi2 e Lo1
7
desligados, e, durante o resto do perodo, desligar Lo2. Contudo, devido indutncia existente no
motor, a corrente tenta se manter fluindo e constante enquanto Lo2 estiver desligado e, para isso,
Hi2 deve ser acionado neste intervalo de tempo (caminho D na Figura 2.5), que, apesar de estar
ligando os dois terminais do motor juntos, mantm um caminho de baixa impedncia para a corrente
do motor, com perdas mnimas de energia. Apesar de isso frear o motor, esse efeito de ligar e
desligar o motor que gera a tenso mdia vista por ele e, com isso, a velocidade varivel. Algo
similar deve ser feito para que o motor gire para trs, acionando Hi2 e Lo1 durante o T
on
, e durante o
resto do perodo desligando Lo1 e ligando Hi1.
8
3 Circuito de potncia
As chaves que acionam a ponte-H, discutida no captulo anterior, foram inicialmente
consideradas ideais, ou seja, no possuem perda alguma. Como as chaves no so ideais na prtica,
devem-se analisar as perdas existentes nas chaves reais.
Existem trs tipos perdas em chaves reais. So elas:
Perdas na conduo perdas relativas ao comportamento da chave quando fechada
(ligada), devido a algum efeito que gere uma queda de tenso sobre a chave;
Perdas na comutao perdas relativas fase de comutao da chave, ou seja,
durante a fase de ligar ou deslig-la;
Perdas no acionamento perdas existentes nos circuitos de acionamento das chaves.
As perdas de conduo e comutao consomem parte da potncia que seria disponvel para
a carga, que transformada em calor, diminuindo a eficincia do circuito, alm de diminuir a
capacidade de acionamento dos circuitos j que todas as chaves reais possuem um limite de
temperatura de trabalho. Esse efeito da temperatura normalmente atenuado com tcnicas de
refrigerao, mas sempre existir nos sistemas disponveis.
Nos tpicos abaixo, os tipos de chaves eletrnicas (transistores) mais comumente utilizadas
transistores bipolares de juno e Mosfets sero analisadas, descrevendo suas vantagens,
desvantagens e as perdas existentes em cada um.
9
3.1. Transistor Bipolar de Juno (BJT)
O BJT foi o primeiro tipo de transistor a ser desenvolvido e, devido a isso, o de
construo mais simples e barato. O funcionamento dele baseado na amplificao de correntes, ou
seja, ao injetar uma corrente na sua entrada (Base), permitida a passagem de uma corrente,
proporcional corrente de base, entre os terminais de sada (Coletor e Emissor). A constante de
proporcionalidade chamada de ganho de corrente ( ou h
fe
). Caso a corrente de base seja nula, o
BJT estar em corte, ou seja, chave aberta (desligada) e, caso a corrente de base seja maior ou igual
que a necessria para acionar a carga, ele estar na saturao, que a situao equivalente a uma
chave fechada (ligada).


Fig. 3.1 Modos de operao para chaveamento de um transistor bipolar.

Quando um BJT est na saturao, a tenso entre o coletor e o emissor fica, na maioria dos
dispositivos de potncia, entre 0,5 V e 1 V. Essa tenso, multiplicada pela corrente que passa pelo
circuito, a potncia dissipada durante a conduo sendo, portanto, a perda de conduo do
transistor. No caso de motores de alta corrente, pode-se facilmente demonstrar a impossibilidade do
uso de BJTs, j que a corrente a qual o circuito deve suportar continuamente pode chegar a 160 A,
10
fazendo com que a perda de potncia em cada um dos dois dispositivos conduzindo ao mesmo
tempo seja de pelo menos 80 W, o que exigiria dissipadores de calor muito grandes e pesados. A
melhor forma de contornar esse problema seria utilizar vrios transistores em paralelo. Caso fossem
utilizados quatro transistores idnticos em paralelo, a corrente seria distribuda igualmente entre
todos 40 A em cada fazendo com que a potncia em cada transistor fosse de pelo menos 20 W,
um valor ainda muito grande para o uso sem dissipadores. Alm disso, o BJT possui um valor
mximo de corrente que no deve ser ultrapassado, podendo ocasionar queima instantnea do
transistor caso ocorra.
Outro grande problema do BJT seu acionamento. Como ele feito atravs de corrente,
necessria uma grande corrente em sua base para que ele permita a passagem de altas correntes entre
seus terminais, j que os BJTs de potncia normalmente possuem relativamente pequeno, entre 20
e 50. Com isso, a corrente necessria na base para a conduo de, e.g., 40 A em cada transistor de
no mnimo 2 A, alm de ser necessrio que as formas de ondas dessa corrente sejam complexas na
transio, fazendo com que o circuito de acionamento se torne extremamente complexo.
Quanto potncia dissipada no transistor durante o acionamento, ela devido tenso
existente entre a base e o emissor do transistor, aproximadamente 0,7 V, fazendo com que a potncia
dissipada fique em, pelo menos, 1,4 W seguindo o valor de 2 A do exemplo acima. Apesar de ser
muito menor que as perdas na conduo, esse valor ainda est muito prximo dos valores mximos
permitidos em encapsulamentos comuns de transistores, o que se torna mais um motivo que
inviabiliza o seu uso.
Por ltimo, h tambm a perda na comutao. Ela acontece devido ao transistor no
conseguir mudar instantaneamente do estado de corte (sem corrente e toda tenso no transistor) para
a saturao (tenso no transistor zero, idealmente, e a corrente fluindo) e vice versa. Nesse intervalo
11
de tempo haver uma maior dissipao de calor. As formas de onda vistas no transistor no melhor
caso, ou seja, quando o circuito totalmente resistivo, podem ser vistas na Figura 3.2(a). O pior caso
pode ser visto na Figura 3.2(b), caso a impedncia complexa (indutores ou capacitores) do circuito
seja muito grande.
Pela Figura 3.2, pode-se ver claramente que a perda na comutao depende dos tempos de
transio t
on
e t
off
, que dependem somente do transistor. A perda tambm depende da freqncia de
operao, que funo somente da aplicao considerada. Num BJT de potncia, em geral, os
tempos t
on
e t
off
ficam numa faixa de 0,5 s a 2 s.

tenso
corrente
t
on
t
off
a)
tenso
corrente
t
on
t
off
b)

Fig. 3.2 Formas de onda no transistor. a) melhor caso; b) pior caso.

12
3.2. Transistor de Efeito de Campo tipo Metal - xido - Semicondutor (MOSFET)
O MOSFET, ou abreviadamente FET, um dispositivo mais complexo que o BJT e,
portanto, mais caro. Apesar disso, suas vantagens so muitas. A primeira delas o fato de ele ser
acionado por tenso, facilitando muito o seu acionamento. Basta que a tenso na sua entrada (Gate)
seja maior que a tenso de limiar (V
th
) do dispositivo, para que seja permitida a passagem de
corrente entre seus terminais (Drain e Source).


Fig. 3.3 Modos de operao para um MOSFET.

Quando o FET est conduzindo, ele se comporta como um resistor (r
on
). Os melhores FETs
disponveis possuem r
on
perto de 5 m. Assim, como no caso do uso de BJT, um nico FET no
consegue suportar sozinho todos os 160 A contnuos do exemplo considerado, portanto sero
utilizados nesse caso quatro dispositivos, resultando numa potncia P igual a:
W m
A
r I P
on
8 5
4
160
2
2
=

= = (2)
Como se pode ver, a potncia dissipada no FET menos da metade da potncia de um BJT
similar e, com isso, dentro de uma faixa aceitvel para o uso de pequenos dissipadores, juntamente
13
com ventilao ativa proporcionada por uma ventoinha (fan). Caso no se utilize dissipadores, a
corrente mxima contnua aceitvel num sistema de 4 FETs fica em aproximadamente 100 A. Outra
grande vantagem do FET que ele no possui limitao de corrente, desde que a temperatura do
silcio fique dentro da mxima permitida, ou seja, que a corrente no seja grande demais por muito
tempo (tolerando assim grandes picos de corrente, uma segurana a mais para o circuito).
Como o FET acionado por tenso, a corrente consumida no gate, durante a conduo,
zero. Apesar disso, na comutao, existe uma corrente entrando ou saindo do gate, devido ao fato de
que existe uma capacitncia parastica entre o gate e a fonte. Como no existem elementos
dissipativos (resistores) dentro do FET no circuito de acionamento, a energia que armazenada
nessa capacitncia no ser dissipada no FET, e sim no circuito de acionamento.
Apesar disso, essa capacitncia parastica deve ser carregada para que a tenso no gate, que
a prpria tenso no capacitor, chegue acima de V
th
. Esse tempo que a tenso leva para chegar ao
V
th
depende somente do circuito de acionamento e da capacitncia parastica, mas normalmente da
ordem de algumas dezenas de nano segundos e exatamente o t
on
da comutao. Assim como a
tenso tem que subir acima de V
th
para ligar o transistor, ela tem que baixar desse valor para
deslig-lo, sendo esse tempo que o transistor leva para entrar em corte, o t
off
, tambm da ordem de
dezenas de nano segundos. Devido aos pequenos tempos de comutao t
on
e t
off
, em relao ao BJT,
pode-se afirmar que as perdas de comutao nos FETs so muito menores.
Em suma, as vantagens vistas acima justificam o uso de FETs no acionamento do circuito
proposto, apesar de seu custo relativamente alto.
14
3.3. Circuito de Acionamento da Ponte H
O fato de FETs serem acionados por tenso facilita muito o desenvolvimento de um
circuito para seu acionamento, mas uma caracterstica no ideal existente gera alguns problemas.
Para o FET entrar em conduo, uma carga eltrica deve ser injetada no gate do FET para que a
tenso entre o gate e o source chegue a um valor de aproximadamente 10 V, que , em geral, a
tenso em que eles entram em conduo mxima, ou seja, menores valores de r
on
. Essa necessidade
de injetar cargas no FET pode ser modelada como um capacitor em paralelo com o gate do FET (a
capacitncia parastica mencionada anteriormente), vide a Figura 3.4.

Fig. 3.4 Circuito de acionamento dos FETs.
Para carregar essa grande capacitncia, foi utilizado o chip HIP4081A [2], capaz de
fornecer at 2 A para os quatro FETs que se encontram em cada sada, em paralelo. Mas como os
FETs se comportam como uma capacitncia, a corrente inicial em cada ciclo seria muito grande,
caso no houvesse alguma limitao, podendo danificar o chip. Para evitar isso, foi colocado um
resistor em srie com o gate de cada FET, o que limita a corrente total, apesar de fazer com que os
FETs demorem mais para conduzirem. Um outro beneficio do resistor o fato de ajudar a balancear
15
o tempo de T
on
e T
off
de todos os FETs em paralelo, ao fazer com que as constantes RC do conjunto
resistor - capacitncia sejam semelhantes.
Apesar dessas vantagens, a incluso deste resistor aumenta a chance de ocorrer um
shoot-through, pelo fato de que o T
off
maior do que o T
on
, ou seja, um FET pode entrar em
conduo enquanto o outro no mesmo lado da ponte H ainda estiver conduzindo. Duas protees
existem para evitar essa condio. A primeira um tempo programvel no HIP4081A que faz com
que ambos os FETs fiquem em estado de corte e a segunda a adio de diodos extremamente
rpidos em paralelo com os resistores, de forma que durante o T
off
toda a corrente seja descarregada
por eles, fazendo com que o T
off
seja muito mais rpido, eliminando qualquer chance de ocorrer
shoot-through no circuito.
Uma ltima preocupao o fato de o gate dos FETs serem muito sensveis a tenses
muito altas, que podem destruir o FET, mesmo caso ocorram muito rapidamente. Para proteger os
FETs, dois diodos zener so colocados para cortar qualquer rudo que ultrapasse o valor da tenso
do zener (15 V, vide Figura 3.4).

16
3.4. Circuito de Completo de Potncia
O componente principal do circuito de potncia projetado o chip HIP4081A, discutido na
seo anterior. Ele tem a funo de acionar os FETs, tanto os FETs inferiores quanto os superiores,
j incluindo um circuito que aumenta a tenso para acionar estes ltimos. Ele aceita tenses de
bateria de 12 V at 80 V, gerando todos os sinais e tenses necessrios para acionar os FETs. Para
funcionar corretamente, o HIP4081A precisa de uma tenso de alimentao nominal de 12 V,
podendo variar de 9,5 V at 15 V. Caso a tenso de alimentao seja menor que o valor mnimo,
uma proteo interna desliga as sadas para os FETs superiores, desligando efetivamente o circuito.
Deve ser lembrado que caso a tenso de alimentao exceda 16 V, o chip pode ser danificado. Na
figura 3.5, o chip est sendo alimentado por uma tenso de 12 V e uma tenso de bateria de 80 V
est sendo aplicada carga.

Fig. 3.5 Diagrama de blocos do HIP4081A
O HIP4081A tem quatro entradas digitais, AHI, ALI, BHI e BLI, cada uma correspondendo
s sadas que acionam cada conjunto de FETs, AHO, ALO, BHO e BLO, respectivamente, ou seja,
quando uma entrada for ativada, a sua sada correspondente faz com que os FETs entrem em
conduo. Uma eletrnica externa deve enviar os sinais de PWM e direo para o HIP4081A de
17
forma a acionar a ponte H. Esses sinais digitais so compatveis com a lgica TTL, mas qualquer
tenso na entrada acima de 3 V reconhecida como sinal de nvel alto. Alm disso, o HIP4081A
possui uma proteo na lgica interna contra shoot-through, que desliga os FETs superiores quando
os FETs inferiores do mesmo lado da ponte forem acionados, independentemente do estado da
entrada superior. Essa proteo feita com portas lgicas AND em todas as entradas do HIP4081A,
conforme mostrado na figura 3.6. As portas tm como entrada os valores de entrada de AHI, ALI,
BHI e BLI, o complemento do pino DIS (Disable, ou desabilitar), fazendo com que ao ter um nvel
baixo, desliga todos os FETs. Alm dessas, as portas superiores, de AHI e BHI, tem outras duas
entradas, uma para a proteo contra tenses de alimentaes baixas, j citada e outra sendo o
complemento das entradas inferiores, o que faz com que as sadas superiores, AHO e BHO, sejam
desligadas, caso as entradas inferiores respectivas estiverem ativadas.

Fig. 3.6 Diagrama funcional de metade do HIP4081A

18
Resistores tambm so colocados no HIP4081A, entre os pinos de entrada e o terra,
forando o chip a um estado padro, de forma que, caso no exista nada conectado placa de
potncia, todos os FETs estejam desligados, formando uma proteo adicional contra o acionamento
no desejado dos motores.
Devido natureza dos FETs utilizados, a tenso no gate deve ser aproximadamente 10 V
maior do que a tenso de bateria para acionar os FETs superiores. Para gerar essa tenso maior, o
HIP4081A possui um sistema de charge-pump que, com a ajuda de um diodo e um capacitor
externo, D
BS
e C
BS
na figura 3.6, gera a tenso necessria nas sadas AHO e BHO, possibilitando o
acionamento dos respectivos FETs. Devido existncia desse sistema, no necessrio mais nada
para acionar os FETs.
Para proteger o circuito de picos de tenses causados pelas escovas e comutadores de
motores DC, utilizado um componente chamado Supressor de Transientes de Tenso (TVS
Transient Voltage Supressor, em ingls). Eles funcionam exatamente como um diodo zener, ou seja,
quando a tenso entre o dispositivo ultrapassa um valor especificado ele entra em conduo,
absorvendo toda a tenso excedente. Alm disso, o TVS otimizado para agentar picos de tenso
com altas correntes. O TVS colocado no circuito de forma a absorver os picos de tenso entre os
terminais da bateria e proteger os FETs de tenses que possam vir a superar o limite da tenso entre
os terminais drain e source. Alm dos TVS, uma rede RC entre os terminais do motor prov uma
proteo adicional contra picos de alta freqncia gerados pelas escovas do motor e, finalmente,
grandes capacitores eletrolticos so colocados o mais prximo possvel da ponte H para reduzir os
efeitos causados pelas impedncias dos fios da bateria at o circuito.

19
A ltima parte do circuito composta pela fonte de alimentao chaveada, que converte a
tenso da bateria para 12 V, atravs de um regulador chaveado de alta eficincia, fazendo com que
no seja necessrio o uso de um dissipador para o regulador. Esses 12 V tambm alimentam o
circuito externo placa de potncia, o que elimina a necessidade de uma alimentao externa para o
circuito de sinais.
O circuito completo se encontra no anexo A.
20
4 Circuito de controle
O circuito de potncia visto no Captulo 3 no capaz de receber diretamente os sinais de
um receptor de rdio-controle sem que estes sejam primeiramente tratados. Esse tratamento de sinais
feito pelo circuito de controle, formado principalmente por um micro-controlador PIC [3] capaz de
executar 1 milho de instrues por segundo, caso esteja funcionando com um cristal de 4 MHz.
O circuito da placa de sinais proposta nesse trabalho ser capaz de decodificar at quatro
sinais do receptor do controle remoto e, de acordo com estes, acionar duas eletrnicas de potncia
um sinal de entrada para cada com controle de velocidade e direo, alm de poder acionar um
rel auxiliar utilizando uma lgica com um ou os dois sinais restantes.

21
4.1. Sinais de Entrada e Sada
Antes de analisar o projeto do circuito de controle, deve-se entender quais sinais devem
entrar e sair deste circuito.
O nico sinal de entrada do circuito o que se origina no receptor do rdio-controle. Esse
sinal digital possui um perodo que pode variar entre 18 ms e 25 ms, com o sinal variando entre 1 ms
(low) e 2 ms (high).




1-2ms

18-25ms
Fig. 4.1 Sinal do Receptor
Quanto aos sinais de sada, h cinco sinais que devem ser enviados placa de potncia, o
AHI, ALI, BHI, BLI e o sinal de Disable. Esses sinais correspondem a cada um dos sinais de
entrada do HIP4081A da placa de potncia. Devido proteo contra shoot-through do HIP4081A,
pode-se fazer uma simplificao, mantendo tanto o sinal AHI quanto o BHI em nvel lgico alto. J
o Disable s usado caso se queira desligar a ponte H. Com isso, a Tabela 4.1 mostra os sinais
sugeridos para o correto funcionamento do circuito de potncia.

Tabela 4.1 Sinais sugeridos para a placa de potncia
AHI BHI ALI BLI Disable Funo
1 1 0 PWM 0 Para frente
1 1 PWM 0 0 Para trs
1 1 0 0 0 Freio
1 1 1 1 0 Freio
X X X X 1 Desligado
X: no importa; 1: 5 V; 0: 0 V;

22
Apesar de j ser necessrio utilizar somente dois sinais, j que o AHI e o BHI so fixos em
nvel lgico 1, ainda no h no circuito um sinal somente para o PWM e outro independente
somente para a direo, o que seria necessrio j que o sinal gerado pelo PIC estaria fixo num pino
especfico. A melhor soluo modificar a tabela para que os sinais fiquem fixos numa nica
posio. Essa modificao mostrada na Tabela 4.2.

Tabela 4.2 Sinais sugeridos modificados para a placa de potncia
AHI BHI ALI BLI Disable Funo
1 1 0 PWM 0 Para frente
1 1 1
PWM
0 Para trs
1 1 0 0 0 Freio
1 1 1 1 0 Freio
X X X X 1 Desligado
X: no importa; 1: 5 V; 0: 0 V;

Com essa nova tabela, fica claro que o sinal BLI ser o sinal de PWM, apesar de ser
necessrio alguma medida (seja por software ou por hardware) para inverter o sinal caso o motor
esteja girando para trs. Nesse caso o sinal ALI ser o sinal de direo, sendo de nvel baixo (0)
quando se deseja ir para frente e de nvel alto (1) quando se deseja ir para trs. Com isso,
considerando o PWM em 100%, ou seja, em 1 sempre, no caso para frente a corrente passa pelos
FETs conectados em AHO e BLO e, como no caso para trs o PWM est invertido (em 0) no caso
para trs, a corrente passa pelos FETs em BHO e ALO.

23
4.2. Descrio do Hardware
O hardware do circuito de controle extremamente simples. composto de um micro-
controlador PIC16F876A, de um buffer para isolar os sinais gerados pelo PIC em relao aos sinais
da placa de potncia, protegendo-o de quaisquer problemas que possam ocorrer. H tambm um
circuito (opcional) de acionamento de rel de alta potncia, tambm isolado, mas dessa vez por um
optoacoplador, que prov um isolamento completo entre o rel e o circuito de controle em si. Alm
disso, ainda existe um circuito regulador de tenso que utiliza os 12 V disponveis atravs da placa
de potncia e os transforma em 5 V atravs de um regulador linear. Esses 5 V so utilizados para
alimentar todo o circuito de controle, incluindo o receptor de rdio controle. O circuito ainda inclui
dois botes, um para reset do PIC e outro para o acionamento do modo de calibragem.
O micro-controlador PIC possui opo de gravao in-circuit, ou seja, no necessrio
retirar o chip para gravar o software de controle. Para isso, basta conectar o gravador no conector
disponvel no circuito.

Fig. 4.2 Pinagem do PIC16F876A.
As entradas dos sinais do receptor do rdio-controle so conectadas atravs de resistores
para os pinos RB4 at o RB7 do PIC. Esses pinos geram uma interrupo (desvio de programa)
quando a entrada muda de estado, sendo assim perfeitos para a leitura do sinal do receptor.
O buffer utilizado em ambas as sadas o chip 74HCT244, composto por dois conjuntos de
quatro buffers. possvel tambm utilizar outros chips equivalentes ao 74HCT244, como o
24
74HC244, mas deve-se atentar aos valores de tenso de sada que estes apresentam, caso se utilize
algum outro alm desses dois apresentados, j que existem valores mnimos a serem aplicados s
entradas do HIP4081A da placa de potncia. Por exemplo, o chip da srie LS (74LS244), possui
uma sada em nvel lgico alto com a tenso mnima especificada de 2 V, enquanto a tenso mnima
de entrada do HIP4081A para reconhecimento de nvel lgico alto de 2,5 V. Apesar disso o
74LS244 pode ser utilizado, mas no recomendado, j que a tenso mnima de sada s
alcanada com altas correntes de sada, que no ocorrem no circuito.

Fig. 4.3 Circuito de sada da placa de controle.
Na figura 4.3 esto mostrados dois conectores chamados OSMC1 e OSMC2. Eles so os
conectores para as placas de potncia, chamadas assim devido ao circuito base utilizado no projeto
chamado Open Source Motor Controllers ou, abreviadamente, OSMC [4].
Os sinais de sada AHI e BHI dos conectores das placas de potncia, pinos 5 e 7
respectivamente, j esto conectados na linha de 12 V da placa de potncia, pinos 1 e 2, ou seja,
25
sero reconhecidos pelo HIP4081A como sendo nvel lgico 1, exatamente como descrito na Tabela
4.2.
Outro detalhe que pode ser visto na Figura 4.2 o fato de termos diodos entre a linha de 12
V que vem dos conectores e a linha de 12 V da placa de controle. Isso feito para se utilizar a
alimentao das duas eletrnicas de potncia e, com isso, ganhar confiabilidade, j que existir
alimentao no circuito de controle mesmo caso uma das eletrnicas de potncia queime.

Fig. 4.4 Circuito do rel e LED de status.
J na Figura 4.3, pode-se ver o circuito que aciona o rel auxiliar (opcional). Ele formado
por um optoacoplador que, ao ser ativado, faz com que o transistor T1 entre em conduo,
acionando o rel. Para isso, os terminais do rel devem ser posicionados nos terminais X1-1 e X1-2
e uma alimentao de 24 V deve ser colocada nos terminais X2-1 e X2-2. Isso, claro, assume que
o rel seja de 24 V. O transistor T1 pode conduzir at 1 A, caso no se utilize um dissipador de
calor, ou at 3,5 A caso contrrio. Os transistores TIP120, TIP121 e TIP122 podem ser utilizados
nesse circuito [5].
Na Figura 4.3 tambm mostrado o LED de status, que serve para mostrar o estado do
programa que est sendo executado pelo PIC. Nesse projeto ele s foi utilizado para indicar se o
circuito est no modo de calibragem ou no modo normal.
26
4.3. Software do Circuito de Controle
Todo o software foi escrito na linguagem de programao C, que facilita muito a
programao, pois o programa utiliza vrias equaes matemticas que seriam complicadas de
serem implementadas em linguagem de mquina (assembly). O programa segue o diagrama de
blocos mostrado na Figura 4.4.
Inicio
Configurar
PIC
Manipulao dos
sinais recebidos
Clculo dos sinais
PWM e Direo
Validao dos sinais
recebidos
Acionamento do
circuito de potncia

Fig. 4.5 Diagrama de blocos do software
Como pode ser observado na figura acima, o programa principal no aquisita os valores dos
sinais do receptor. Isso feito pela rotina de interrupo, que executada sempre que uma
interrupo ocorre, independentemente do que est sendo processado no momento da interrupo.
No caso, ocorre uma interrupo em todas as transies dos quatro sinais do receptor. Isso permite
que os tempos lidos sejam os mais precisos possveis.
Um outro detalhe no mostrado na Figura 4.4 o fato de o programa rodar a cada 10 ms,
para facilitar as temporizaes existentes no software.
27
4.3.1. Configurao do PIC
Antes de poder executar qualquer programa, deve-se rodar alguma rotina que configure
todos os perifricos do micro-controlador que sero utilizados no sistema. Tambm necessrio
configurar as portas (pinos) do PIC para entrada ou sada, alm de colocar os seus respectivos
valores iniciais, e de inicializar as variveis. Todas essas operaes so feitas escrevendo valores
especficos em registradores de configurao do PIC. A Tabela 4.3 mostra todos os registradores
que devem ser configurados, suas funes no sistema, alm da configurao necessria e o valor, em
hexadecimal, a ser escrito. A ordem em que esses valores so escritos importante, ento devem ser
colocados na ordem mostrada na tabela.
Tabela 4.3 Configurao do micro-controlador
Registrador Funo Configurao Valor
TRISA
Define se os pinos da PORTA sero
entradas ou sadas
Todos os pinos so sada 0x00
TRISB
Define se os pinos da PORTB sero
entradas ou sadas
Pinos RB0 e RB4 a 7 so entrada 0xF1
TRISC
Define se os pinos da PORTC sero
entradas ou sadas
Somente o pino RC7 entrada 0x80
PORTA Define a sada nos pinos da PORTA 0x00
PORTB Define a sada nos pinos da PORTB 0x00
PORTC Define a sada nos pinos da PORTC 0x00
ADCON1
Configura parte do conversor AD e
pinos da PORTA
Configura os pinos da PORTA como digital
(padro analgico)
0x07
OPTION Configurao do Timer 0
Clock interno, dividido por 4.
A configurao feita pelo macro
0xC1
T1CON Configurao do Timer 1
Clock interno, dividido por 8 e j habilitado.
A configurao feita por macro
Set up_Count er s( ) ;
0x31
PR2 Configura freqncia do PWM F
pwm
= 3,906 kHz 4 kHz 0xFF
CCPR1L Configura o duty cycle do PWM1
Deve ser inicialmente zero, para no acionar
inadvertidamente os motores.
Configurado pelo macro set _ccp1( ) ;
0x00
CCPR2L Configura o duty cycle do PWM2
Deve ser inicialmente zero, para no acionar
inadvertidamente os motores.
Configurado por macro set _ccp2( ) ;
0x00
CCP1CON Configura o modo do modulo CCP1
Deve ser configurado como PWM
Configurado pelo macro set up_ccp1( ) ;
0x0C
CCP2CON Configura o modo do modulo CCP2
Deve ser configurado como PWM
Configurado pelo macro set up_ccp2( ) ;
0x0C
28
T2CON Configurao do Timer 2
Prescaler e postscaler do timer 2 desabilitados e
timer 2 ligado
Configurado pelo macro set up_t i mer _2( ) ;
0x04
RBPU
Bit de ativao dos resistores de
pull-up da PORTB
Resistores devem ser ativados, para que o PIC leia
nvel lgico alto, caso algum canal do receptor no
esteja ligado.
0
INTCON Configurao das interrupes
Interrupo on-change (mudana de estado) da
PORTB e de overflow do timer 0 devem ser
ativadas.
Configurada pelo macro
enabl e_i nt er r upt s( ) ;
0x28
GIE Habilita todas as interrupes 1

Alm desses registradores, as variveis tambm devem ser inicializadas. A rotina de
inicializao completa mostrada abaixo. Todas as macros so definidas no arquivo commdefs.h.
/ ********************************************************************************************/
/ * Rot i na de I ni ci al i zao do pr ocessador */
/ ********************************************************************************************/
voi d i ni t _pr oc ( voi d)
{
TRI SA = 0x00; / / PORTA t oda sa da
TRI SB = 0xF1; / / RB<4: 7> so ent r adas ( 4 canai s) e
/ / RB0 ent r ada do bot o de cal i br agem
TRI SC = 0x80; / / PORTC t oda sa da, excet o RC7 ( RX)

PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;

St at us_Led_Of f ( ) ;

st s. t mr _1ms =
st s. t mr _10ms =
st s. i nval i d_r c1 =
st s. i nval i d_r c1 =
st s. i nval i d_r c1 =
st s. i nval i d_r c1 = t r ue;
st s. Di sabl e_Al l = t r ue;
st s. Mi xMode = EEPROM_READ( eeaddMi xMode) ;
st s. AuxMode = EEPROM_READ( eeaddAuxMode) ;

Sl ew = SR_100ms;

t i cks = 0;

ADCON1 = 0x07; / / Conf i gur a t oda a PORTA como di gi t al

Set up_Count er s( RTCC_I NTERNAL, RTCC_DI V_4 ) ; / / Conf i gur a TMR0 ( RTCC) par a cl ock
/ / i nt er no compr e- scal er em1: 4 par a
/ / t er umTi me- out de 1, 024 ms ~ 1 ms

set up_t i mer _1( T1_DI V_BY_8 | T1_ENABLED ) ; / / Ti mer 1 i ncr ement a a cada 8 us
/ / e j est r odando

PR2 = 0xFF; / / Fpwm= 3, 906 kHz
set _ccp1( 0) ; / / Dut y Cycl e = 0 ( sempot nci a nos
set _ccp2( 0) ; / / Mot or es)
set up_ccp1( CCP_PWM ) ; / / CCP1 emmodo PWM
29
set up_ccp2( CCP_PWM ) ; / / CCP2 emmodo PWM
set up_t i mer _2( T2_DI V_BY_1, 1) ; / / Set a o Pr escal er e o Post scal er do
/ / Ti mer 2 em1: 1 e l i ga o Ti mer 2

RBPU = 0; / / At i va os Pul l - ups na PORTB par a o caso de no haver si nal

enabl e_i nt er r upt s( RB_CHANGE | I NT_TI MER0 ) ; / / Habi l i t a as i nt er r upes:
/ / RB on- change - > si nal r di o
/ / TMR0 - > i nt a cada 1ms

GI E = 1; / / Habi l i t a t odas as i nt er r upes
}


4.3.2. Rotina de Interrupo
Ao ocorrer uma interrupo, desde que o bit GIE (que habilita todas as interrupes) e o bit
que habilita a interrupo de um perifrico especfico estiverem em 1, a rotina de interrupo ser
executada. Como na configurao os bits relativos interrupo da RB on-change e de overflow do
timer 0 esto habilitados, assim como o GIE, sempre que ocorrer o evento relativo a essas
interrupes a rotina de interrupo ser executada.
Como todas as interrupes que ocorrem executam a mesma rotina, deve-se testar os flags
de interrupo para descobrir quem a gerou. Caso o flag de um mdulo esteja em 1, a interrupo
ocorreu nele e, ento, executado algum cdigo especfico. No se deve esquecer de zerar o flag da
interrupo que ocorreu, caso contrrio a rotina de interrupo ser executada num loop infinito, j
que o fato de o flag de alguma interrupo habilitada estar em 1 que gera a interrupo. O fato de
ter que testar os flags por software permite que se tenham prioridades entre as interrupes,
bastando testar a interrupo com maior prioridade primeiro e ir testando as prximas com
prioridade decrescente. Nesse sistema, a medio do tempo dos pulsos do receptor deve ser feita
com a menor latncia possvel, portanto a interrupo do RB on-change ter a maior prioridade,
sendo testada primeiro, seguido pela interrupo de temporizao, gerada pelo timer 0 que, por ter
freqncia baixa, pode ter prioridade menor.
30
A medio de tempo feita atravs da interrupo RB on-change. Como ela gerada
sempre que h uma mudana na entrada dos pinos RB4 at o RB7, necessrio identificar qual
entrada mudou e qual seu novo valor. Isso feito guardando o ltimo valor da PORTB e
comparando com o valor atual, atravs de uma operao lgica chamada OU exclusivo ou,
abreviadamente, XOR, vide Figura 4.5. Ao fazer essa operao em dois bytes obtm-se na sada
outro byte, com bits igual a 1 somente nas posies em que existam diferenas entre os dois bytes.
11000011
10101010
01101001
=
3 xC 0
xAA 0
69 x 0

Fig. 4.6 Exemplo da operao XOR em dois bytes
Aps a operao de XOR, ainda necessrio saber se o bit do pino que se deseja testar 1.
Para isso, basta zerar todos os outros bits e comparar com o valor que a PORTB teria caso s aquele
bit estivesse em 1.
Com isso, sabe-se se foi esse pino que mudou de estado, ento basta ler o pino em si para
saber se ele mudou para 1 ou para 0. Caso seja 1, o tempo lido do timer 1 (mltiplos de 8 s), logo
no incio da rotina de interrupo, o tempo inicial do pulso e, caso contrrio, o tempo final.
Como recomendado manter a rotina de interrupo com o menor tamanho possvel, a subtrao
dos tempos lidos feita em outra rotina, fora da interrupo. A rotina que implementa essa operao
para o pino RB4 mostrada no quadro abaixo:
t i me = TMR1L; / / L o val or do t i mer
r b_val ue = ( ol d_por t b ^ PORTB) ; / / Compar a o val or da PORTB ant i go como at ual
ol d_por t b = PORTB; / / Sal va o novo val or ( pr oxi mo ant i go)

i f ( ( r b_val ue & 0x10) == 0x10) { / / Se RB4 mudou

i f ( RB4 == 1) { / / Subi da de Pul so
ser vo1. st ar t = t i me; / / val or i ni ci al do pul so t i me
}
el se { / / Desci da do pul so
ser vo1. end = t i me; / / val or f i nal do pul so t i me
ser vo1. done = TRUE; / / Ter mi nou o pul so
}
}
31
Aps ler o tempo de quando o pulso vai para zero, a rotina avisa que possui os ltimos
valores de incio e fim do pulso do receptor atravs do campo done da varivel servo1. Aps ler os
valores novos, o programa principal zera este campo. Todos os outros pinos possuem cdigo
semelhante a esse, mudando apenas os valores de comparao no primeiro condicional if.
Alm da leitura dos pulsos do receptor, a rotina de interrupo tambm aciona o campo
tmr_10ms da varivel de status sts, que ser utilizado para a temporizao do programa, a cada 10
ms, durante a interrupo do timer 0. Como o timer 0 foi programado para ter overflow a cada 1,024
ms e o tempo de 10 ms no crtico, a varivel pode ser acionada a cada dez contagens da
interrupo. Alm disso, os 1,024 ms tambm so utilizados para incrementar um contador ticks ,
que conta quanto tempo passou desde o ltimo reset. Essa rotina mostrada abaixo:
i f ( T0I F)
{
T0I F = 0;
i f ( ++count > 9) {
st s. t mr _10ms = 1;
count = 0;
}
t i cks++;
}


32
4.3.3. Normalizao e validao do pulso do receptor
Os valores de tempo dos quatro pulsos do receptor lidos pela rotina de interrupo ficam
armazenados nas variveis servo1, servo2, servo3 e servo4. Essas variveis possuem uma estrutura
com vrios campos, listados na Tabela 4.4, cada um com uma funo especfica dentro do programa.
Tabela 4.4 Campos de dados das variveis servo1 a servo4
Campo Descrio Funo
start Tempo de inicio do pulso Tempo de incio de pulso lido na interrupo
end Tempo de fim do pulso Tempo de fim de pulso lido na interrupo
low Menor valor de pulso
Fator de escala para normalizar pulso pode ser
modificado na calibragem
high Maior valor de pulso
Fator de escala para normalizar pulso pode ser
modificado na calibragem
rcpulse Largura do pulso a subtrao de end por start.
width Largura do pulso normalizado o valor de rcpulse, normalizado entre 0 e 1023.
drive Valor a ser aplicado no motor
done Flag de fim de pulso Indica que o pulso acabou de ser lido na interrupo.
valid Flag de validao Indica se o ltimo pulso vlido ou no.

Alm desses campos, valores definidos no arquivo motor.h so utilizados no processo de
validao do pulso, sendo os principais deles os valores que delimitam os tamanhos mximo e
mnimo do pulso sem que programa o considere invlido. So eles MINVALIDWIDTH e
MAXVALIDWIDTH.
O primeiro passo da rotina simples, basta conferir que o pulso terminou de ser lido,
atravs do campo done e, caso tenha terminado, subtrair end de start e colocar o valor em rcpulse. O
valor de rcpulse ainda subtrado por 15 e o resultado armazenado numa varivel local tWidth
deslocando os valores lidos e, com isso, permitindo que valores muito perto do limite superior, que
est perto do maior valor possvel que pode ser armazenado em um byte, ainda possam ser lidos.
Aps isso, deve-se verificar que tWidth esteja entre os valores vlidos e, caso estejam, deve-se ainda
verificar se o pulso est entre os valores de low e high, j que esses so os maiores valores que o
33
pulso pode ter para ser normalizado corretamente. Caso seja menor ou maior que estes valores, basta
igualar a low ou high, respectivamente. Essa operao mostrada no cdigo abaixo:
i f ( MI NVALI DWI DTH < t Wi dt h && t Wi dt h < MAXVALI DWI DTH)
{

i f ( t Wi dt h > p- >hi gh) / / val or es l i mi t es do pul so
t Wi dt h = p- >hi gh;
el se i f ( t Wi dt h < p- >l ow)
t Wi dt h = p- >l ow;

Aps ter os valores corretos do pulso, deve ser feita uma normalizao para transformar o
valor de tWidth para algum valor entre 0 e 1023.
( )
low high
low tWidth
tWidth


=
1023
(3)
Como a normalizao envolve multiplicaes e divises, o cdigo gerado muito grande e
lento, ento necessrio otimiz-lo. Quanto diviso, no existe nada que possa ser feito para
diminuir o cdigo, j que os valores de high e low so valores que podem ser modificados durante a
calibragem. Porm a multiplicao pode ser otimizada, j que o multiplicador constante, alm de
ser um nmero muito prximo de 1024, que mltiplo de 2. Pode-se demonstrar que a operao
lgica de deslocar um nmero binrio para a esquerda o equivalente a multiplicar por 2 e, portanto,
deslocar o nmero 10 vezes para a esquerda o mesmo que multiplicar por 1024. Essa operao
extremamente rpida, j que o PIC possui uma instruo que a executa.
30 00011110 1
15 00001111
= = <<
= =
x
x

Fig. 4.7 Operao de deslocamento esquerda
Portanto, para multiplicar por 1023, basta deslocar o nmero para a esquerda e, depois,
subtrair o multiplicando do resultado obtido. Deve-se lembrar que a varivel tWidth deve ser de
16 bits para suportar o valor de 1023, j que com 8 bits o valor mximo 255. Alm disso, a funo
deve utilizar uma varivel temporria de 32 bits, j que o maior valor que pode surgir durante a
34
multiplicao ou 253952, que maior do que o valor mximo de um nmero de 16 bits.
Esse fato faria com que a multiplicao, caso no fosse otimizada, fosse lenta demais, inviabilizando
o funcionamento do circuito.
1024 248
Apesar de essa otimizao j ter diminudo muito o tempo de processamento gasto na
multiplicao, outra tcnica simples ainda pode ser empregada. Como o PIC um processador de
8 bits, um nmero de 16 bits formado por 2 bytes. Deslocar o nmero 8 vezes para a esquerda o
mesmo que colocar o byte menos significativo no mais significativo, o que mais rpido do que
deslocar o nmero para a esquerda vrias vezes. Ento a funo final deve deslocar o nmero 8
vezes para a esquerda, depois mais dois deslocamentos e, aps isso, subtrair o multiplicando do
resultado. A operao completa mostrada no quadro abaixo:
t emp = t Wi dt h - p- >l ow;
t emp = ( ( t emp << 8) << 2) - t emp;
p- >wi dt h = t emp / ( unsi gned) ( p- >hi gh - p- >l ow) ;

Essa rotina ainda deve retornar se o pulso foi considerado vlido ou no.

4.3.4. Inverso do PWM
Como visto na Seo 4.1, necessrio inverter o sinal do PWM quando o motor estiver
girando para trs. Como no se deseja fazer uma soluo por hardware, necessrio encontrar um
mtodo simples para fazer a inverso. A forma mais simples de cumprir esta tarefa utilizar
nmeros inteiros com sinais, ou seja, podem ser positivos ou negativos. Na prtica, essa inverso do
PWM faz com que a corrente que v da bateria para o motor (curvas A ou B da figura 2.5) durante o
T
off
, em vez de acontecer durante o T
on
, como o caso do motor estar indo para frente. Os nmeros
negativos so tratados com uma operao chamada complemento a 2, vide Figura 4.7.
35
5 1011 1 1010
1010 0101
5 0101
5
= = +
=
=

Fig. 4.8 Operao de complemento a 2
essa operao que permite com que o sinal de PWM seja invertido quando o motor gira
para trs. Ela funciona fazendo o complemento do nmero positivo e somando 1 ao resultado.
Utilizando esse mtodo, o bit mais significativo do nmero se torna o sinal do nmero e os outros
bits o nmero em si. A Tabela 4.5 mostra todos os valores possveis de nmeros com sinal para uma
palavra de 4 bits.
Tabela 4.5 Nmeros positivos e negativos de 4 bits
Nmero Binrio Nmero Binrio
0 0000
2
-1 1111
2
1 0001
2
-2 1110
2
2 0010
2
-3 1101
2
3 0011
2
-4 1100
2
4 0100
2
-5 1011
2
5 0101
2
-6 1010
2
6 0110
2
-7 1001
2
7 0111
2
-8 1000
2

Usando o exemplo dado na Tabela 4.5, se o nmero for 7, desconsiderando o bit de sinal,
temos o nmero 111
2
, que corresponderia com a sada de PWM sempre em nvel alto. Isso
combinado com a sada de direo em 0 (para frente), teramos a maior velocidade para frente, com
a corrente passando pelo motor atravs de AHI e BLI.
Caso o nmero fosse 1, o valor do PWM ainda seria 111
2
e a sua sada ainda estaria
sempre em nvel alto, ou seja, BLI sempre fechado (ligado). Combinando isso com a sada de
direo em 1, o motor fica parado, pois todos os quatro AHI, BHI, ALI e BLI estariam fechados
(ligados), impedindo o fluxo da corrente da bateria para o motor devido proteo de shoot-through
do HIP4081A. Se o nmero fosse 8, o PWM teria 000
2
o que, juntamente com a direo em 1, far
36
com que o motor gire em toda sua velocidade para trs, pois BLI estaria aberto (desligado), com a
corrente passando pelo motor atravs de BHI e ALI. Nos casos intermedirios, o PWM negativo
em BLI funcionaria impedindo o fornecimento de corrente ao motor durante o seu tempo T
on
em que
estiver ligado, e fornecendo corrente atravs de BHI e ALI no tempo restante em que estiver
desligado.
Portanto, s o fato de se trabalhar tambm com nmeros negativos o suficiente para
resolver o problema, desde que se tenha um bit a mais do que originalmente necessrio para guardar
o sinal do nmero. Como o PWM de 10 bits, so necessrios 11 bits para a velocidade, ou seja, os
valores utilizados ficam entre 1023 e 1024, sendo que os positivos fazem o motor girar para a
frente e os negativos para trs.

4.3.5. Inicializao da Placa de Potncia
Antes de poder utilizar a placa de potncia, necessrio inicializar o chip HIP4081. O
procedimento bem simples, necessitando apenas manter as entradas ALI e BLI em nvel baixo por
algum tempo e depois aplicar um pulso de aproximadamente 200 s no pino de Disable. Como a
rotina de inicializao do PIC j mantm todas as sadas em zero, basta esperar aproximadamente
500 ms e aplicar o pulso. A rotina utiliza a varivel ticks, que marca quanto tempo passou (em
mltiplos de 1 ms) desde o ltimo reset, ou seja, ela espera o valor de ticks aumentar de 500 para
prosseguir com o programa.
Alm de inicializar o HIP4081, ainda necessrio ler da memria de dados no voltil
(EEPROM) os valores de high e low de cada canal do receptor.

37
O cdigo completo mostrado abaixo:
voi d i ni t _mot or ( voi d)
{
i nt t i me = t i cks + 500;

whi l e ( t i cks < t i me) ; / / esper a 1/ 2 segundo ant es de i ni ci al i zar t udo!

LEFT_ENABLE( ) ;
RI GHT_ENABLE( ) ;
Del ayUs( 200) ;
LEFT_DI SABLE( ) ;
RI GHT_DI SABLE( ) ;

ser vo1. l ow = EEPROM_READ( eeaddRC1l ow) ;
ser vo1. hi gh = EEPROM_READ( eeaddRC1hi gh) ;
ser vo2. l ow = EEPROM_READ( eeaddRC2l ow) ;
ser vo2. hi gh = EEPROM_READ( eeaddRC2hi gh) ;
ser vo3. l ow = EEPROM_READ( eeaddRC3l ow) ;
ser vo3. hi gh = EEPROM_READ( eeaddRC3hi gh) ;
ser vo4. l ow = EEPROM_READ( eeaddRC4l ow) ;
ser vo4. hi gh = EEPROM_READ( eeaddRC4hi gh) ;

DeadBand = EEPROM_READ( eeaddDeadBand) ;
}

4.3.6. Limitao da taxa de variao da sada
Motores eltricos no toleram variaes bruscas de velocidade, ou seja, grandes taxas de
variao da velocidade. Quando uma alta taxa ocorre, grandes correntes nos motores aparecem,
podendo danificar a eletrnica de potncia. Para evitar esse efeito, o programa inclui a opo de
limitar a taxa de variao, ou Slew Rate (SR), da sada. Um efeito negativo que o torque no motor
menor, somente enquanto durar a variao da sada, devido menor corrente no motor.
Essa limitao feita somando ou subtraindo uma constante ao valor atual da sada a cada
10 ms, at o valor atual ser maior ou igual do que o desejado, ou seja, quanto maior a constante,
mais rpido a sada muda, proporcionando uma maior taxa de variao e menor tempo para a
mudana completa da sada. Quando essa condio ocorrer e o valor atual for maior do que o
necessrio, basta igual-lo ao valor desejado.
38
A constante pode ser facilmente calculada atravs da seguinte frmula:
) (
10 1023
ms t
SlewRate

= (4)
onde t o tempo que a sada levar para sair de 0 para 1023 e SlewRate valor inteiro mais
prximo do calculado. Como o programa executado em ciclos de 10 ms, esse o menor tempo que
a sada pode demorar pra ir de 0 at seu valor mximo. No arquivo motor.h j est definido valores
para tempos do SR de 10 ms, 50 ms, 100 ms, 150 ms, 200 ms, 250 ms, 300 ms, 400 ms, 500 ms, 680
ms e 1000 ms. Outros valores podem ser facilmente adicionados.
O cdigo da rotina de Slew Rate mostrado abaixo:
i nt DoSl ew( i nt Request edDr i ve, pRCcont r ol Bl ock p, char Sl ewRat e)
{

i nt Cur r ent Dr i ve = p- >Dr i ve;

i f ( Request edDr i ve > Cur r ent Dr i ve)
{
Cur r ent Dr i ve += Sl ewRat e;
i f ( Cur r ent Dr i ve >= Request edDr i ve)
{
Cur r ent Dr i ve = Request edDr i ve;
}
}
el se
{
Cur r ent Dr i ve - = Sl ewRat e;
i f ( Cur r ent Dr i ve <= Request edDr i ve)
{
Cur r ent Dr i ve = Request edDr i ve;
}
}
p- >Dr i ve = Cur r ent Dr i ve;
r et ur n Cur r ent Dr i ve;
}

39
4.3.7. rea morta (Dead Band)
Quando o controle remoto est na sua posio central, ou seja, sada com valor zero, um
valor constante enviado para o circuito de controle. Apesar disso, o valor lido pelo PIC nesta
posio no constante devido principalmente ao fato de existirem latncias variveis para o incio
da execuo da rotina de interrupo. Isso faria com que o motor se movesse (lentamente) mesmo
quando o sinal enviado fosse zero. Para evitar isso e permitir que o motor fique parado, a sada
mantida em zero enquanto o valor a ser colocado for menor do que a varivel DeadBand. O cdigo
da rotina mostrado abaixo:
i nt DoDeadBand( i nt dr i ve)
{
i f ( ( ( 0 - DeadBand) < dr i ve) && ( dr i ve < DeadBand) )
{
dr i ve = 0;
}
r et ur n ( dr i ve) ;
}


4.3.8. Modos de controle
Dependendo de quais canais do receptor so utilizados, possvel utilizar dois modos
completamente diferentes para o controle das duas placas de potncia.
O primeiro o modo normal, em que cada canal do rdio controle controla uma placa de
potncia individualmente. Para esse modo, a nica operao que se deve fazer subtrair o pulso
normalizado por 512, e depois multiplic-lo por 2. Aps esses passos, o valor final comparado
com 1022 para que, caso seja igual, seja ento igualado a 1023, j que este ltimo nmero jamais
seria atingido numa multiplicao por 2 pelo fato de ser mpar. Com esse procedimento, valores de
pulso menores do que 512 sero considerados valores negativos, fazendo com que o motor gire para
trs, enquanto valores maiores do que esse fazem o motor girar para a frente. Ao multiplicar por 2
40
adicionamos um bit ao nmero, o que necessrio para o correto funcionamento do PWM, como
visto na Seo 4.3.4.
O cdigo que executa o controle em modo normal mostrado abaixo:
Ri ght _Dr i ve = Li mi t Dr i ve( ser vo1. wi dt h - 0x200) ;
Lef t _Dr i ve = Li mi t Dr i ve( ser vo2. wi dt h - 0x200) ;

Ri ght _Dr i ve = Ri ght _Dr i ve * 2;
Lef t _Dr i ve = Lef t _Dr i ve * 2;

i f ( Ri ght _Dr i ve == 0x03FE)
Ri ght _Dr i ve = 0x03FF;
i f ( Lef t _Dr i ve == 0x03FE)
Lef t _Dr i ve = 0x03FF;
br eak;

A funo LimitDrive() no cdigo acima limita os valores de Right_Drive e Left_Drive entre
512 e 512.
O segundo tipo de controle o chamado modo mixado. Ele muito til, e.g., quando os
dois motores controlados estiverem acionando independentemente duas rodas de um veculo de
movimentao diferencial. No modo mixado, os dois canais so misturados de forma a um deles
controlar a velocidade mdia dos motores e o outro controlar a diferena de velocidades entre os
motores. Para fazer isso, basta fazer os clculos mostrados abaixo:
1024 2 1 2
2 1 1
+ =
=
canal canal Motor
canal canal Motor

onde canal1 e canal2 so os valores de pulso normalizados (entre 0 e 1023). Nesse caso o
canal1 estaria relacionado velocidade mdia do veculo, e o canal 2 estaria relacionado a mudanas
de direo, ou seja, canal 2 igual a 512 faria o veculo se locomover em linha reta, e qualquer outro
valor geraria diferena de velocidades entre as rodas, gerando curvas.


41
O cdigo desse modo mostrado abaixo:

Ri ght _Dr i ve = Li mi t Dr i ve( ser vo1. wi dt h - ser vo2. wi dt h) ;

Lef t _Dr i ve = Li mi t Dr i ve( ser vo1. wi dt h + ser vo2. wi dt h - 1024) ;



4.3.9. Rotina de Calibragem
Devido a diferenas entre sistemas de rdio controle, o tamanho mnimo (low),
aproximadamente 1 ms, e mximo (high), aproximadamente 2 ms, do pulso do receptor, podem
variar, fazendo com que apaream pequenos erros de acionamento ao normalizar os pulsos com
valores errados. Para corrigir esse problema, foi criada uma rotina de calibragem que pode ser
ativada, atravs de um boto, durante os 0,5 s aps o circuito ser ligado ou resetado. Esse limite de
tempo para o acionamento dessa rotina para evitar que o programa entre em modo de calibragem
caso o boto seja pressionado acidentalmente durante o funcionamento normal do circuito.
A rotina de calibragem compara os pulsos lidos com os valores de low e high atuais e caso
algum pulso seja menor ou maior do que estes valores, ele ser o novo valor. Ainda assim, esses
novos valores de low e high ainda devem obedecer aos valores MINVALIDWIDTH e
MAXVALIDWIDTH, que valem 102 e 248, respectivamente. Para que a operao de calibragem
funcione corretamente, todos os canais do controle que esto conectados ao circuito devem ser
variados em toda a sua excurso para que os valores de mximo e mnimo reais sejam lidos
corretamente.
Para que esses novos valores lidos no se percam ao desligar o circuito, eles so gravados
na memria de dados no voltil (EEPROM) do PIC.

42
A rotina de calibragem para o servo1 mostrada no quadro abaixo. Cada canal de servo
tem um cdigo idntico a esse.
i f ( ser vo1. done) {
ser vo1. done = f al se;

ser vo1. r cpul se = ser vo1. end - ser vo1. st ar t - 15;

i f ( ( MI NVALI DWI DTH < ser vo1. r cpul se) && ( ser vo1. r cpul se < MAXVALI DWI DTH) )
{
i f ( ser vo1. r cpul se > Canal 1. hi gh) {
Canal 1. hi gh = ser vo1. r cpul se;
}
i f ( ser vo1. r cpul se < Canal 1. l ow) {
Canal 1. l ow = ser vo1. r cpul se;
}
}
}


4.3.10. Acionamento do rel
O circuito proposto permite a utilizao de um rel opcional, independente do controle de
velocidade dos motores, para acionar outros sistemas. Existem dois modos de acionamento do rel,
sendo eles o modo simples e o modo duplo. No modo simples apenas um canal utilizado para o
acionamento, enquanto no modo duplo dois canais so utilizados.
Para que a sada seja acionada no modo simples, necessrio que o canal tenha um pulso
maior do que o valor de disparo superior AUX_HIGH_TH. A sada s desligada caso o pulso
seja menor do que o valor de disparo inferior AUX_LOW_TH.
No modo duplo, a sada s ativada caso ambos os canais tenham pulsos maiores do que
AUX_HIGH_TH, dois teros do valor mximo ou 682, e desativada se pelo menos um for menor do
que AUX_LOW_TH, um tero do valor mximo ou 341.


43
O cdigo de acionamento do rel mostrado abaixo:
swi t ch ( st s. AuxMode)
{
case AUX_SI NGLE: {
i f ( ser vo3. val i d) {
i f ( ser vo3. wi dt h > AUX_HI GH_TH) {
Aux_On( ) ;
}
el se i f ( ser vo3. wi dt h < AUX_LOW_TH) {
Aux_Of f ( ) ;
}
}
br eak;
}

case AUX_DOUBLE: {
i f ( ( ser vo3. val i d) && ( ser vo4. val i d) ) {
i f ( ( ser vo3. wi dt h > AUX_HI GH_TH) && ( ser vo4. wi dt h > AUX_HI GH_TH) ) {
Aux_On( ) ;
}
el se i f ( ( ser vo3. wi dt h < AUX_LOW_TH) | | ( ser vo4. wi dt h < AUX_LOW_TH) ) {
Aux_Of f ( ) ;
}
}
br eak;
}
}


4.3.11. Rotina principal (main)
A rotina principal, ou main, a primeira rotina a ser executada aps um reset ou ligar o
micro-controlador e, por isso, ela controla todo o sistema.
Portanto a main deve chamar as rotinas de inicializao, tanto a do micro-controlador
quanto a do motor, e conferir se o boto de calibragem foi pressionado durante os 500 ms iniciais,
preparando todo o sistema para o correto funcionamento.
Aps toda a incializao, o programa entra num loop infinito, sendo executado todos os
passos necessrios para o acionamento dos motores e do rel, incluindo a interpretao dos sinais,
manipulao matemtica destes e limitao de taxa de variao da sada. Alm disso, antes do
acionamento dos motores, ainda verificado se os pulsos recebidos foram vlidos e, caso no
tenham sido, a sada correspondente ao pulso invlido desligada.
44
Abaixo encontra-se a parte de inicializao da rotina.
voi d mai n ( voi d)
{
i ni t _pr oc( ) ; / / I ni ci al i za o PI C

whi l e ( t i cks < 500) { / / Esper a 500 ms
i f ( RB0 == 0) { / / Se o bot o f oi pr essi onado
Cal i br at e( ) ; / / Cal i br a os canai s
br eak;
}
}

i ni t _mot or ( ) ; / / I ni ci al i za a pl aca de pot enci a

St at us_Led_On( ) ; / / Li ga LED de st at us t udo OK

RI GHT_ENABLE( ) ; / / Habi l i t a el et r oni cas de pot enci a
LEFT_ENABLE( ) ;

O loop infinito, juntamente com a normalizao e checagem dos pulsos pela rotina
CheckPulse(), mostrado abaixo.
whi l e ( t r ue) { / / l oop I nf i ni t o
i f ( st s. t mr _10ms) { / / S execut a t udo a cada 10 ms
st s. t mr _10ms = f al se; / / zer a o f l ag
st s. i nval i d_r c1 = CheckPul se( &ser vo1) ; / / Nor mal i za e checa se o pul so est a cor r et o
st s. i nval i d_r c2 = CheckPul se( &ser vo2) ; / / ATENCAO! ! ! A f uno CheckPul se r et or na
st s. i nval i d_r c3 = CheckPul se( &ser vo3) ; / / ver dadei r o se o pul so est i ver i nvl i do
st s. i nval i d_r c4 = CheckPul se( &ser vo4) ;

O modo de acionamento dos motores mostrado abaixo, juntamente com as manipulaes
efetuadas nos valores de acionamento dos motores.
swi t ch ( st s. Mi xMode)
{
case MI XED: {
Ri ght _Dr i ve = Li mi t Dr i ve( ser vo1. wi dt h - ser vo2. wi dt h) ;
Lef t _Dr i ve = Li mi t Dr i ve( ser vo1. wi dt h + ser vo2. wi dt h - 1024) ;
br eak;
}
case STRAI GHT: {
Ri ght _Dr i ve = Li mi t Dr i ve( ser vo1. wi dt h - 0x200) ;
Lef t _Dr i ve = Li mi t Dr i ve( ser vo2. wi dt h - 0x200) ;

Ri ght _Dr i ve = Ri ght _Dr i ve * 2;
Lef t _Dr i ve = Lef t _Dr i ve * 2;

i f ( Ri ght _Dr i ve == 0x03FE)
Ri ght _Dr i ve = 0x03FF;
i f ( Lef t _Dr i ve == 0x03FE)
Lef t _Dr i ve = 0x03FF;
br eak;
}
}

45
Ri ght _Dr i ve = DoDeadBand( Ri ght _Dr i ve) ;
Lef t _Dr i ve = DoDeadBand( Lef t _Dr i ve) ;

Ri ght _Dr i ve = DoSl ew( Ri ght _Dr i ve, &ser vo1, Sl ew) ;
Lef t _Dr i ve = DoSl ew( Lef t _Dr i ve, &ser vo2, Sl ew) ;

O acionamento dos motores mostrado abaixo.
i f ( st s. i nval i d_r c1) { / / Se f or i nvl i do
RI GHT_DI SABLE( ) ; / / Desl i ga mot or
Ri ght _Dr i ve = 0;
}
el se { / / se f or vl i do
RI GHT_ENABLE( ) ; / / Li ga mot or
}
i f ( st s. i nval i d_r c2) { / / Se f or i nvl i do
LEFT_DI SABLE( ) ; / / Desl i ga mot or
Lef t _Dr i ve = 0;
}
el se { / / se f or vl i do
LEFT_ENABLE( ) ; / / Li ga mot or
}

i f ( Ri ght _Dr i ve >= 0) { / / Mai or que zer o
RI GHT_FOWARD( ) ; / / Gi r a par a f r ent e
}
el se { / / Menor que zer o
RI GHT_REVERSE( ) ; / / Gi r a par a t r s
}

i f ( Lef t _Dr i ve >= 0) { / / Mai or que zer o
LEFT_FOWARD( ) ; / / Gi r a par a f r ent e
}
el se { / / Menor que zer o
LEFT_REVERSE( ) ; / / Gi r a par a t r s
}

set _pwm1( Ri ght _Dr i ve) ; / / Col oca novo val or de PWM
set _pwm2( Lef t _Dr i ve) ; / / Col oca novo val or de PWM

Por ltimo, foram implementados ambos os modos de acionamento dos rels. A
escolha entre eles feito pela varivel sts.AuxMode.
swi t ch ( st s. AuxMode)
{
case AUX_SI NGLE: {
i f ( ser vo3. val i d) {
i f ( ser vo3. wi dt h > AUX_HI GH_TH) {
Aux_On( ) ;
}
el se i f ( ser vo3. wi dt h < AUX_LOW_TH) {
Aux_Of f ( ) ;
}
}
br eak;
}
case AUX_DOUBLE: {
i f ( ( ser vo3. val i d) && ( ser vo4. val i d) ) {
i f ( ( ser vo3. wi dt h > AUX_HI GH_TH) && ( ser vo4. wi dt h > AUX_HI GH_TH) ) {
46
Aux_On( ) ;
}
el se i f ( ( ser vo3. wi dt h < AUX_LOW_TH) | | ( ser vo4. wi dt h < AUX_LOW_TH) ) {
Aux_Of f ( ) ;
}
}
br eak;
}
}

47
5 Concluses e Sugestes de Trabalhos Futuros
Nesse trabalho foi apresentado o resultado do desenvolvimento de um conjunto de circuitos
para o controle de motores de corrente contnua de alta potncia, consistindo de um circuito de
controle que recebe sinais de um receptor de rdio controle e os transforma em sinais que podem ser
interpretados por um circuito de potncia, o qual aciona os motores.
Os testes feitos em dois sistemas robticos diferentes, ambos com motores que apresentam
potncias eltricas superiores a 1,5 HP, chegando a mais de 3,5 HP, mostraram que o circuito de
potncia suporta as cargas sem problemas. Apesar disso, a segunda verso feita do circuito de
controle, modificada para acrescentar chaves de segurana, apresentou problemas na gravao do
software no micro-controlador, causada pela mudana na disposio das trilhas dos sinais de
gravao. Por isso, em prximas verses, recomendado que essas trilhas sejam mantidas no menor
comprimento possvel, ligando os pinos do conector com os do PIC por um caminho direto,
ininterrupto.
Outro detalhe em relao ao hardware do circuito de controle a utilizao de chips SMD
(montagem em superfcie), o que dificultou o trabalho de correo de erros nos circuitos que se
mostraram defeituosos. Recomenda-se, tambm, o uso de chips DIP comuns, com o uso de soquetes,
para facilitar a troca, caso o micro-controlador queime, apesar de fazer com que o circuito fique um
pouco maior.
Alm disso, na parte de proteo do software atual existe um bug (problema no programa)
na parte do cdigo que desativa os motores que deve ser corrigido. Ele se apresenta somente no
modo mixado, j que o software relaciona um canal do receptor com uma sada especfica. Como no
48
modo mixado dois canais so utilizados para criar os valores de sada de ambos os motores, os dois
devem ser desativados caso pelo menos um dos canais se mostre invlido.
O cdigo incorreto, juntamente com a correo mostrado abaixo:
Cdigo incorreto Novo cdigo
i f ( st s. i nval i d_r c1) {
RI GHT_DI SABLE( ) ;
Ri ght _Dr i ve = 0;
}
el se {
RI GHT_ENABLE( ) ;
}
i f ( st s. i nval i d_r c2) {
LEFT_DI SABLE( ) ;
Lef t _Dr i ve = 0;
}
el se {
LEFT_ENABLE( ) ;
}
i f ( ( st s. i nval i d_r c1) | | ( st s. i nval i d_r c2) ) {
RI GHT_DI SABLE( ) ;
LEFT_DI SABLE( ) ;
Ri ght _Dr i ve = 0;
Lef t _Dr i ve = 0;
}
el se {
RI GHT_ENABLE( ) ;
LEFT_ENABLE( ) ;
}

Apesar do sucesso do conjunto, ainda existem vrias caractersticas que podem ser
adicionadas ao circuito de controle. A principal delas em relao ao reconhecimento de pulsos
invlidos. Atualmente somente a largura do nvel alto do pulso medida e comparada com valores
limtrofes para verificar se est dentro da faixa de aceitao. O circuito de controle poderia verificar
o perodo desses pulsos, que deve estar entre 18 ms e 25 ms, alm de s considerar um pulso vlido
aps receber um nmero mnimo de pulsos corretos. Essas duas mudanas aumentariam muito a
segurana do circuito.
O circuito ainda tem problemas na leitura dos pulsos, com os valores lidos variando um
pouco, principalmente devido latncia varivel para o incio da execuo da rotina de interrupo,
j que os pulsos so lidos em passos de 8 s e a latncia, com o PIC rodando a 4 MHz, pode variar
de 3 s a 4 s. Aumentando a freqncia do micro-controlador, o efeito da latncia diminudo.
Aumentando a freqncia para 16 MHz, por exemplo, faria com que a latncia diminusse para 0,75
s a 1 s, apesar de algumas mudanas no programa terem que ser feitas para manter os timers
49
funcionando nas freqncias certas. Provavelmente, em 16 MHz, os timers 0 e 1 devero trocar de
funo para que se consiga isso.
Caso os circuitos sejam utilizados para controlar a velocidade de motores com avano de
fase para a locomoo de robs, pode ser necessrio que exista uma limitao da sada, podendo ser
s numa direo do motor ou em ambas, para que motores opostos girem mesma velocidade. Para
incluir essa opo, logo antes de atualizar o valor do PWM dos motores deve ser feita uma nova
normalizao dos valores. Por exemplo, caso o motor deva ser limitado at 50%, ou seja, seu valor
mximo 512, quando girando para frente, nada deve ser feito enquanto o motor gira para trs e ao
comear a girar para frente, deve ser feito a seguinte conta:
1023
_ 512 atual valor
sada

=
Antes de implementar essa opo, deve ser feito um estudo para saber se o PIC consegue
terminar todas as contas adicionais (duas multiplicaes e duas divises para cada motor) entre o
recebimento de dois pulsos do receptor de rdio controle. Caso no seja possvel, pode ser feita uma
diminuio na resoluo do PWM, utilizando somente 8 bits para os valores dos sinais lidos, ou seja,
128 a 127, completando os bits do PWM com 0s ou 1s, dependendo do caso, j que so
necessrios 10 bits para o PWM.
Outras melhorias podem ser feitas para facilitar a utilizao dos vrios modos de execuo
existentes. Atualmente necessrio regravar o micro-controlador com os novos parmetros de
utilizao. Uma interface poderia ser feita para permitir a programao desses parmetros pela porta
serial disponvel no PIC, utilizando o computador para enviar os novos parmetros. O software atual
foi feito pensando nessas futuras atualizaes, j que todos os parmetros (modo do rel, modo de
acionamento dos motores, slew rate, banda morta e calibragem) so gravados na memria EEPROM
50
do PIC e lidos durante a inicializao do circuito. Uma outra opo criar uma interface no circuito
utilizando botes e um display de cristal lquido (LCD), fazendo o circuito ficar altamente porttil,
sem a necessidade de um computador para efetuar as mudanas necessrias nos parmetros.
51
6 Bibliografia
[1] NPC Robotics Inc., www.npcrobotics.com
[2] Intersil, www.intersil.com
[3] Microchip, www.microchip.com
[4] Grupo de discusso Open Source Motor Controllers, groups.yahoo.com/group/osmc
[5] Philips Semiconductors, www.semiconductors.philips.com
[6] Sedra, A.S.; Smith, K.C., Microeletrnica, Ed. Makron Books, 2000.
[7] Pressman, A.I., Switching Power Supply Design 2
nd
ed, Ed. McGraw-Hill, 1998.
[8] MicrochipC.com, www.microchipc.com
[9] Horovitz, P., Hill, W., The Art of Electronics, Cambridge University Press, 1989.
52
Anexo A - Esquemticos

Fig. A.1 Esquemtico do circuito de controle
53

Fig. A.2 Esquemtico da placa de potncia.
54
Anexo B Cdigo completo
3.1. main.c
/ *****************************************************************************************/
/ * Pr ogr ama : MAI N. C */
/ * Funo : Pr ogr ama de Cont r ol e do OSMC */
/ * Aut or : Fel i pe Mai mon */
/ * Li nguagem : Hi Tech C 8. 02 PL1 ( ANSI C) */
/ * Pl at af or ma : PI C16F876A @4MHz */
/ * Har dwar e : Ri oBot z 1. 0 */
/ * */
/ * Ver si on : 0. 1 */
/ *****************************************************************************************/

#def i ne _MAI N_C

/ / #def i ne VERBOSE

#i ncl ude <pi c. h>
#i ncl ude " commdef s. h"
#i ncl ude " mot or . h"
#i ncl ude " ser i al . h"
#i ncl ude " eepr om. h"
#i ncl ude " mai n. h"

__CONFI G( 0x3F71 ) ; / / XT | PWRTEN | BOREN | LVPDI S


char Sl ew;
i nt Lef t _Dr i ve, Ri ght _Dr i ve;

/ ********************************************************************************************/
/ * Mai n Pr ogr am */
/ ********************************************************************************************/
voi d mai n ( voi d)
{
i ni t _pr oc( ) ;

put st ( " Cont r ol ador OSMC\ n" ) ;

whi l e ( t i cks < 500) {
i f ( RB0 == 0) {
Cal i br at e( ) ;
br eak;
}
}

i ni t _mot or ( ) ;

St at us_Led_On( ) ;

RI GHT_ENABLE( ) ;
LEFT_ENABLE( ) ;

whi l e ( t r ue) {

i f ( st s. t mr _10ms) {

st s. t mr _10ms = f al se;

st s. i nval i d_r c1 = CheckPul se( &ser vo1) ;
st s. i nval i d_r c2 = CheckPul se( &ser vo2) ;
st s. i nval i d_r c3 = CheckPul se( &ser vo3) ;
st s. i nval i d_r c4 = CheckPul se( &ser vo4) ;

swi t ch ( st s. Mi xMode)
{
case MI XED: {
Ri ght _Dr i ve = Li mi t Dr i ve( ser vo1. wi dt h - ser vo2. wi dt h) ;
Lef t _Dr i ve = Li mi t Dr i ve( ser vo1. wi dt h + ser vo2. wi dt h - 1024) ;
br eak;
}
case STRAI GHT: {
Ri ght _Dr i ve = Li mi t Dr i ve( ser vo1. wi dt h - 0x200) ;
Lef t _Dr i ve = Li mi t Dr i ve( ser vo2. wi dt h - 0x200) ;

Ri ght _Dr i ve = Ri ght _Dr i ve * 2;
Lef t _Dr i ve = Lef t _Dr i ve * 2;

i f ( Ri ght _Dr i ve == 0x03FE)
Ri ght _Dr i ve = 0x03FF;
i f ( Lef t _Dr i ve == 0x03FE)
Lef t _Dr i ve = 0x03FF;
br eak;
}
55
}

Ri ght _Dr i ve = DoDeadBand( Ri ght _Dr i ve) ;
Lef t _Dr i ve = DoDeadBand( Lef t _Dr i ve) ;

Ri ght _Dr i ve = DoSl ew( Ri ght _Dr i ve, &ser vo1, Sl ew) ;
Lef t _Dr i ve = DoSl ew( Lef t _Dr i ve, &ser vo2, Sl ew) ;

i f ( st s. i nval i d_r c1) {
RI GHT_DI SABLE( ) ;
Ri ght _Dr i ve = 0;
}
el se {
RI GHT_ENABLE( ) ;
}
i f ( st s. i nval i d_r c2) {
LEFT_DI SABLE( ) ;
Lef t _Dr i ve = 0;
}
el se {
LEFT_ENABLE( ) ;
}

i f ( Ri ght _Dr i ve >= 0) {
RI GHT_FOWARD( ) ;
}
el se {
RI GHT_REVERSE( ) ;
}

i f ( Lef t _Dr i ve >= 0) {
LEFT_FOWARD( ) ;
}
el se {
LEFT_REVERSE( ) ;
}

set _pwm1( Ri ght _Dr i ve) ;
set _pwm2( Lef t _Dr i ve) ;

swi t ch ( st s. AuxMode)
{
case AUX_SI NGLE: {
i f ( ser vo3. val i d) {
i f ( ser vo3. wi dt h > AUX_HI GH_TH) {
Aux_On( ) ;
}
el se {
Aux_Of f ( ) ;
}
}
br eak;
}

case AUX_DOUBLE: {
i f ( ( ser vo3. val i d) && ( ser vo4. val i d) ) {
i f ( ( ser vo3. wi dt h > AUX_HI GH_TH) && ( ser vo4. wi dt h > AUX_HI GH_TH) ) {
Aux_On( ) ;
}
el se {
Aux_Of f ( ) ;
}
}
br eak;
}
}

#i f def VERBOSE1
Pr i nt Val ues( ) ;
#endi f
}
}
}
/ ********************************************************************************************/

/ ********************************************************************************************/
/ * Rot i na de I ni ci al i zao do pr ocessador */
/ ********************************************************************************************/
voi d i ni t _pr oc ( voi d)
{
TRI SA = 0x00; / / PORTA t oda sa da
TRI SB = 0xF1; / / RB<4: 7> so ent r adas ( 4 canai s) e
/ / RB0 ent r ada do bot o de cal i br ao
TRI SC = 0x80; / / PORTC t oda sa da, excet o RC7 ( RX)

PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;

St at us_Led_Of f ( ) ;

56
st s. t mr _1ms =
st s. t mr _10ms =
st s. i nval i d_r c1 =
st s. i nval i d_r c1 =
st s. i nval i d_r c1 =
st s. i nval i d_r c1 = t r ue;
st s. Di sabl e_Al l = t r ue;
st s. Mi xMode = EEPROM_READ( eeaddMi xMode) ;
st s. AuxMode = EEPROM_READ( eeaddAuxMode) ;

/ / 0 - t empo 0
/ / 1 - t empo ~ 50 ms
/ / 2 - t empo ~ 100 ms
/ / 3 - t empo ~ 150 ms
/ / 4 - t empo ~ 200 ms
/ / 5 - t empo ~ 250 ms
/ / 6 - t empo ~ 300 ms
/ / 7 - t empo ~ 400 ms
/ / 8 - t empo ~ 500 ms
/ / 9 - t empo ~ 750 ms
/ / 10 - t empo ~ 1000 ms
Sl ew = SR_100ms;

t i cks = 0;

ADCON1 = 0x07; / / Conf i gur a t oda a PORTA como di gi t al

Set up_Count er s( RTCC_I NTERNAL, RTCC_DI V_4 ) ; / / Conf i gur a TMR0 ( RTCC) par a cl ock
/ / i nt er no compr e- scal er em1: 4 par a
/ / t er umTi me- out de 1, 024 ms ~ 1 ms

set up_t i mer _1( T1_DI V_BY_8 | T1_ENABLED ) ; / / Ti mer 1 i ncr ement a a cada 8 us
/ / e j est r odando

PR2 = 0xFF; / / Fpwm= 3, 906 kHz
set _ccp1( 0) ; / / Dut y Cycl e = 0 ( sempot nci a nos
set _ccp2( 0) ; / / Mot or es)
set up_ccp1( CCP_PWM ) ; / / CCP1 emmodo PWM
set up_ccp2( CCP_PWM ) ; / / CCP2 emmodo PWM
set up_t i mer _2( T2_DI V_BY_1, 1) ; / / Set a o Pr escal er e o Post scal er do
/ / Ti mer 2 em1: 1 e l i ga o Ti mer 2
RBPU = 0; / / At i va os Pul l - ups na PORTB par a o caso de no haver si nal

ser i al _set up( ) ;

enabl e_i nt er r upt s( RB_CHANGE | I NT_TI MER0 ) ; / / Habi l i t a as i nt er r upes:
/ / RB on- change - > si nal r di o
/ / TMR0 - > i nt a cada 1ms

GI E = 1; / / Habi l i t a t odas as i nt er r upes
}


3.2. main.h
/ *****************************************************************************************/
/ * Pr ogr ama : MAI N. H */
/ * Funo : Header do MAI N */
/ * Aut or : Fel i pe Mai mon */
/ * */
/ *****************************************************************************************/

#i f ndef _MAI N_H
#def i ne _MAI N_H

/ *****************************************************************************************/
/ * Pr ocessor speed def i nes */
/ *****************************************************************************************/
#def i ne _CLOCK_ 4000000 / / Cr i st al de 4MHz
#def i ne St at us_Led_On( ) RA4 = 0;
#def i ne St at us_Led_Of f ( ) RA4 = 1;
#def i ne Aux_On( ) RA5 = 1;
#def i ne Aux_Of f ( ) RA5 = 0;

/ *****************************************************************************************/
/ * St r uct def i nes */
/ *****************************************************************************************/

st r uct ct r _st at us
{
unsi gned t mr _1ms : 1; / / f l ag set ada a cada 1 ms
unsi gned t mr _10ms : 1; / / f l ag set ada a cada 10 ms
unsi gned Mi xMode : 1; / / f l ag do modo de cont r ol e ( Mi xado ou Separ ado)
unsi gned AuxMode : 1; / / f l ag do aci onament o do mot or auxi l i ar
unsi gned i nval i d_r c1 : 1; / / f l ag de er r o do ser vo1
57
unsi gned i nval i d_r c2 : 1; / / f l ag de er r o do ser vo2
unsi gned i nval i d_r c3 : 1; / / f l ag de er r o do ser vo3
unsi gned i nval i d_r c4 : 1; / / f l ag de er r o do ser vo4
unsi gned Di sabl e_Al l : 1; / / f l ag par a par ar o Robo
}

t ypedef st r uct
{
unsi gned char st ar t ; / / St ar t t i me
unsi gned char end; / / end t i me
unsi gned char l ow; / / Scal i ng f act or
unsi gned char hi gh; / / scal i ng f act or
unsi gned char r cpul se; / / l ast cal cul at ed R/ C pul se wi dt h
/ / unsi gned char pul se; / / number s of val i d pul ses
unsi gned i nt wi dt h; / / Nor mal i zed pul se wi dt h
unsi gned i nt Dr i ve;
unsi gned done : 1; / / pul se f l ags
unsi gned val i d : 1; / / Mar ks dat a as val i d or not .
}
RCcont r ol Bl ock, *pRCcont r ol Bl ock;

/ *****************************************************************************************/
/ * Var i abl e and const ant decl ar at i ons */
/ *****************************************************************************************/
ext er n vol at i l e st r uct ct r _st at us st s;
ext er n vol at i l e RCcont r ol Bl ock ser vo1, ser vo2, ser vo3, ser vo4;
ext er n vol at i l e unsi gned i nt t i cks;
/ *****************************************************************************************/
/ * Funct i on pr ot ot ypes */
/ *****************************************************************************************/

voi d i ni t _pr oc( voi d) ;

#endi f / / _MAI N_H

/ / ***** EOF MAI N. H *****



3.3. motor.c
#def i ne _MOTOR_C

#i ncl ude <pi c. h>
#i ncl ude " commdef s. h"
#i ncl ude " del ay. h"
#i ncl ude " mai n. h"
#i ncl ude " ser i al . h"
#i ncl ude " eepr om. h"
#i ncl ude " mot or . h"

char DeadBand;

voi d i ni t _mot or ( voi d)
{
i nt t i me = t i cks + 500;

whi l e ( t i cks < t i me) ; / / esper a 1/ 2 segundo ant es de i ni ci al i zar t udo!

LEFT_ENABLE( ) ;
RI GHT_ENABLE( ) ;
Del ayUs( 200) ;
LEFT_DI SABLE( ) ;
RI GHT_DI SABLE( ) ;

ser vo1. l ow = EEPROM_READ( eeaddRC1l ow) ;
ser vo1. hi gh = EEPROM_READ( eeaddRC1hi gh) ;
ser vo2. l ow = EEPROM_READ( eeaddRC2l ow) ;
ser vo2. hi gh = EEPROM_READ( eeaddRC2hi gh) ;
ser vo3. l ow = EEPROM_READ( eeaddRC3l ow) ;
ser vo3. hi gh = EEPROM_READ( eeaddRC3hi gh) ;
ser vo4. l ow = EEPROM_READ( eeaddRC4l ow) ;
ser vo4. hi gh = EEPROM_READ( eeaddRC4hi gh) ;

DeadBand = EEPROM_READ( eeaddDeadBand) ;
}

bi t CheckPul se( pRCcont r ol Bl ock p)
{
unsi gned char t Wi dt h;
unsi gned l ong t emp;

i f ( p- >done)
{
p- >r cpul se = t Wi dt h = p- >end - p- >st ar t - 15; / / Subt r ai 15 par a desl ocar
/ / o t empo par a a esquer da e
/ / consegui r l er at 2. 17 ms
58
p- >done = FALSE; / / Reset Pul se Tr ap

i f ( MI NVALI DWI DTH < t Wi dt h && t Wi dt h < MAXVALI DWI DTH)
{
i f ( t Wi dt h > p- >hi gh) / / l i mi t measur ed r ange.
t Wi dt h = p- >hi gh;
el se i f ( t Wi dt h < p- >l ow)
t Wi dt h = p- >l ow;

t emp = t Wi dt h - p- >l ow;
t emp = ( ( t emp << 8) << 2) - t emp;
p- >wi dt h = t emp / ( unsi gned) ( p- >hi gh - p- >l ow) ;

p- >val i d = t r ue;
}
el se
{
p- >val i d = f al se;
}
}
r et ur n ( ! p- >val i d) ; / / Ret ur n Tr ue i f not val i d
}

i nt DoDeadBand( i nt dr i ve)
{
i f ( ( ( 0 - DeadBand) < dr i ve) && ( dr i ve < DeadBand) )
{
dr i ve = 0;
}
r et ur n ( dr i ve) ;
}


/ *************************************************************************
Sl ewRat e umi nt ei r o ent r e 0 e 10. Os val or es do SR cor r espondent e est o
na t abel a abai xo, emor demcr escent e
*/
i nt DoSl ew( i nt Request edDr i ve, pRCcont r ol Bl ock p, char Sl ewRat e)
{

const i nt Sl ewTabl e[ ] = { 1023, / / 0 - t empo ent r e mxi mo e par ado 0
204, / / 1 - t empo ~ 50 ms
102, / / 2 - t empo ~ 100 ms
68, / / 3 - t empo ~ 150 ms
51, / / 4 - t empo ~ 200 ms
41, / / 5 - t empo ~ 250 ms
34, / / 6 - t empo ~ 300 ms
26, / / 7 - t empo ~ 400 ms
20, / / 8 - t empo ~ 500 ms
14, / / 9 - t empo ~ 730 ms
10 / / 10 - t empo ~ 1000 ms
};

i nt Cur r ent Dr i ve = p- >Dr i ve;

Sl ewRat e = Sl ewTabl e[ Sl ewRat e] ;

i f ( Request edDr i ve > Cur r ent Dr i ve)
{
Cur r ent Dr i ve += Sl ewRat e;
i f ( Cur r ent Dr i ve > Request edDr i ve)
{
Cur r ent Dr i ve = Request edDr i ve;
}
}
el se
{
Cur r ent Dr i ve - = Sl ewRat e;
i f ( Cur r ent Dr i ve < Request edDr i ve)
{
Cur r ent Dr i ve = Request edDr i ve;
}
}
p- >Dr i ve = Cur r ent Dr i ve;
r et ur n Cur r ent Dr i ve;
}

i nt Li mi t Dr i ve( i nt Dr i ve)
{
i f ( Dr i ve > 511)
Dr i ve = 511;
i f ( Dr i ve < - 512)
Dr i ve = - 512;
r et ur n Dr i ve;
}

voi d Cal i br at e( voi d)
{
st r uct
{
char hi gh;
59
char l ow;
}
Canal 1, Canal 2, Canal 3, Canal 4;
i nt t i me = 0;

Canal 1. hi gh =
Canal 2. hi gh =
Canal 3. hi gh =
Canal 4. hi gh = 0;
Canal 1. l ow =
Canal 2. l ow =
Canal 3. l ow =
Canal 4. l ow = 255;

t i me = t i cks + 10000;

St at us_Led_Of f ( ) ;

whi l e ( t i cks < t i me)
{
i f ( ser vo1. done) {
ser vo1. done = f al se;

ser vo1. r cpul se = ser vo1. end - ser vo1. st ar t - 15;

i f ( ( MI NVALI DWI DTH < ser vo1. r cpul se) && ( ser vo1. r cpul se < MAXVALI DWI DTH) )
{
i f ( ser vo1. r cpul se > Canal 1. hi gh) {
Canal 1. hi gh = ser vo1. r cpul se;
}
i f ( ser vo1. r cpul se < Canal 1. l ow) {
Canal 1. l ow = ser vo1. r cpul se;
}
}
}
i f ( ser vo2. done) {
ser vo2. done = f al se;

ser vo2. r cpul se = ser vo2. end - ser vo2. st ar t - 15;

i f ( ( MI NVALI DWI DTH < ser vo2. r cpul se) && ( ser vo2. r cpul se < MAXVALI DWI DTH) )
{
i f ( ser vo2. r cpul se > Canal 2. hi gh) {
Canal 2. hi gh = ser vo2. r cpul se;
}
i f ( ser vo2. r cpul se < Canal 2. l ow) {
Canal 2. l ow = ser vo2. r cpul se;
}
}
}
i f ( ser vo3. done) {
ser vo3. done = f al se;

ser vo3. r cpul se = ser vo3. end - ser vo3. st ar t - 15;

i f ( ( MI NVALI DWI DTH < ser vo3. r cpul se) && ( ser vo3. r cpul se < MAXVALI DWI DTH) )
{
i f ( ser vo3. r cpul se > Canal 3. hi gh) {
Canal 3. hi gh = ser vo3. r cpul se;
}
i f ( ser vo3. r cpul se < Canal 3. l ow) {
Canal 3. l ow = ser vo3. r cpul se;
}
}
}
i f ( ser vo4. done) {
ser vo4. done = f al se;

ser vo4. r cpul se = ser vo4. end - ser vo4. st ar t - 15;

i f ( ( MI NVALI DWI DTH < ser vo4. r cpul se) && ( ser vo4. r cpul se < MAXVALI DWI DTH) )
{
i f ( ser vo4. r cpul se > Canal 4. hi gh) {
Canal 4. hi gh = ser vo4. r cpul se;
}
i f ( ser vo4. r cpul se < Canal 4. l ow) {
Canal 4. l ow = ser vo4. r cpul se;
}
}
}
}

EEPROM_WRI TE( eeaddRC1l ow, Canal 1. l ow) ;
EEPROM_WRI TE( eeaddRC1hi gh, Canal 1. hi gh) ;
EEPROM_WRI TE( eeaddRC2l ow, Canal 2. l ow) ;
EEPROM_WRI TE( eeaddRC2hi gh, Canal 2. hi gh) ;
EEPROM_WRI TE( eeaddRC3l ow, Canal 3. l ow) ;
EEPROM_WRI TE( eeaddRC3hi gh, Canal 3. hi gh) ;
EEPROM_WRI TE( eeaddRC4l ow, Canal 4. l ow) ;
EEPROM_WRI TE( eeaddRC4hi gh, Canal 4. hi gh) ;
}
60
3.4. motor.h
#i f ndef _MOTOR_H
#def i ne _MOTOR_H

#i ncl ude <pi c. h>
#i ncl ude " mai n. h"

/ / Di sabl e Bi t s
st at i c vol at i l e bi t DI S1 @( unsi gned) &PORTC*8+4;
st at i c vol at i l e bi t DI S2 @( unsi gned) &PORTC*8+5;
/ / Di r ect i on Bi t s
st at i c vol at i l e bi t DI R1 @( unsi gned) &PORTC*8+3;
st at i c vol at i l e bi t DI R2 @( unsi gned) &PORTC*8+0;

#def i ne RI GHT_FOWARD( ) DI R1 = 0
#def i ne RI GHT_REVERSE( ) DI R1 = 1
#def i ne RI GHT_DI SABLE( ) DI S1 = 1
#def i ne RI GHT_ENABLE( ) DI S1 = 0

#def i ne LEFT_FOWARD( ) DI R2 = 0
#def i ne LEFT_REVERSE( ) DI R2 = 1
#def i ne LEFT_DI SABLE( ) DI S2 = 1
#def i ne LEFT_ENABLE( ) DI S2 = 0

#def i ne MI NVALI DWI DTH 102
#def i ne MAXVALI DWI DTH 248
#def i ne RC_MI N 135
#def i ne RC_MAX 210
#def i ne AUX_LOW_TH ( 1023 * 1 / 3)
#def i ne AUX_HI GH_TH ( 1023 * 2 / 3)

#def i ne SR_0ms 0
#def i ne SR_50ms 1
#def i ne SR_100ms 2
#def i ne SR_150ms 3
#def i ne SR_200ms 4
#def i ne SR_250ms 5
#def i ne SR_300ms 6
#def i ne SR_400ms 7
#def i ne SR_500ms 8
#def i ne SR_750ms 9
#def i ne SR_1000ms 10

#def i ne MI XED 0
#def i ne STRAI GHT 1

#def i ne AUX_SI NGLE 0 / / Aci onament o comumcanal
#def i ne AUX_DOUBLE 1 / / Aci onament o com2 canai s

#def i ne DEADBAND 130

voi d i ni t _mot or ( voi d) ;
bi t CheckPul se( pRCcont r ol Bl ock p) ;
i nt DoDeadBand( i nt dr i ve) ;
i nt DoSl ew( i nt Request edDr i ve, pRCcont r ol Bl ock p, char Sl ewRat e) ;
i nt Li mi t Dr i ve( i nt Dr i ve) ;
voi d Cal i br at e( voi d) ;

#endi f _MOTOR_H




3.5. int.c
/ *****************************************************************************************/
/ * Pr ogr ama : I NT. C */
/ * Funo : Rot i nas de I nt er r upo */
/ * Aut or : Fel i pe Mai mon */
/ * Li nguagem : Hi Tech C 8. 02 PL1 ( ANSI C) */
/ * Pl at af or ma : PI C16F876A @4MHz */
/ * Har dwar e : Ri oBot z 1. 0 */
/ * */
/ * Ver si on : 0. 1 */
/ *****************************************************************************************/

#def i ne _I NT_C
#i ncl ude " commdef s. h"
#i ncl ude " mot or . h"
#i ncl ude " mai n. h"

/ / #def i ne RB_ADJ


/ ********************************************************************************************/
61
/ * Vr i avei s ext er nas
*/
/ ********************************************************************************************/
vol at i l e RCcont r ol Bl ock ser vo1, ser vo2, ser vo3, ser vo4;
vol at i l e st r uct ct r _st at us st s;
vol at i l e unsi gned i nt t i cks;
/ ********************************************************************************************/

unsi gned char ol d_por t b;
unsi gned char count ;

voi d i nt er r upt i sr ( voi d)
{
unsi gned char t i me,
r b_val ue;

i f ( RBI F) {
RBI F = 0;

t i me = TMR1L; / / L sempr e o val or do t i mer e da PORTB
r b_val ue = ( ol d_por t b ^ PORTB) ; / / par a di mi nui r a l at nci a da l ei t ur a
ol d_por t b = PORTB;

i f ( ( r b_val ue & 0x10) == 0x10) { / / Se RB4 mudou

i f ( RB4 == 1) { / / Subi da de Pul so
ser vo1. st ar t = t i me; / / val or i ni ci al do pul so t i me
}
el se { / / Desci da do pul so
ser vo1. end = t i me; / / val or f i nal do pul so t i me
ser vo1. done = TRUE; / / Ter mi nou o pul so
}
}
i f ( ( r b_val ue & 0x20) == 0x20) { / / Se RB5 mudou

i f ( RB5 == 1) { / / Subi da de Pul so
ser vo2. st ar t = t i me; / / val or i ni ci al do pul so t i me
}
el se { / / Desci da do pul so
ser vo2. end = t i me; / / val or f i nal do pul so t i me
ser vo2. done = TRUE; / / Ter mi nou o pul so
}
}
i f ( ( r b_val ue & 0x40) == 0x40) { / / Se RB6 mudou

i f ( RB6 == 1) { / / Subi da de Pul so
ser vo3. st ar t = t i me; / / val or i ni ci al do pul so t i me
}
el se { / / Desci da do pul so
ser vo3. end = t i me; / / val or f i nal do pul so t i me
ser vo3. done = TRUE; / / Ter mi nou o pul so
}
}
i f ( ( r b_val ue & 0x80) == 0x80) { / / Se RB7 mudou

i f ( RB7 == 1) { / / Subi da de Pul so
ser vo4. st ar t = t i me; / / val or i ni ci al do pul so t i me
}
el se { / / Desci da do pul so
ser vo4. end = t i me; / / val or f i nal do pul so t i me
ser vo4. done = TRUE; / / Ter mi nou o pul so
}
}
}

i f ( T0I F)
{
T0I F = 0;
st s. t mr _1ms = 1;
i f ( ++count > 9) {
st s. t mr _10ms = 1;
count = 0;
}
t i cks++;
}
}

62
3.6. commdefs.h
/ *****************************************************************************************/
/ * Pr ogr ama : COMMDEFS. H */
/ * Funo : Common macr os and def i nes f or PI C app s not def i ned i n pi c. h */
/ * Aut or : J ohn F. Fi t t er B. E. */
/ * Modi f i caes : */
/ * */
/ * - Ret i r ado o #def i ne TMR1 */
/ * - Modi f i cado os #def i nes de i nt er r upo ser i al de I NT_RDA e I NT_TBE par a */
/ * I NT_RX e I NT_TX, r espect i vament e */
/ * - Adi ci onado #def i nes par a i nt er r upes exi st ent es no PI C16F87X */
/ * */
/ *****************************************************************************************/

#i f ndef _COMMDEFS_H
#def i ne _COMMDEFS_H

#i ncl ude <pi c. h>

/ / Gener al PI C macr os ( addi t i onal t o pi c. h)
#def i ne cl r wdt ( ) CLRWDT( )

/ / Macr o t o def i ne t he I D byt es
#def i ne __I D( a, b, c, d) asm( " \ t psect absdat a, abs ovr l d, del t a=2" ) ; \
asm( " \ t gl obal i d_byt es" ) ; \
asm( " \ t or g 0x2000" ) ; \
asm( " i d_byt es" ) ; \
asm( " \ t db " ___mkst r ( a) ) ; \
asm( " \ t db " ___mkst r ( b) ) ; \
asm( " \ t db " ___mkst r ( c) ) ; \
asm( " \ t db " ___mkst r ( d) )

/ / Gener al macr os
#def i ne HI BYTE( i nt Val ue) ( ( i nt Val ue) >>8)
#def i ne LOBYTE( i nt Val ue) ( ( i nt Val ue) &0xf f )
#def i ne HI NI BBLE( char Val ue) ( ( char Val ue) >>4)
#def i ne LONI BBLE( char Val ue) ( ( char Val ue) &0xf )
#def i ne hi byt e( i nt Val ue) ( ( i nt Val ue) >>8)
#def i ne l owbyt e( i nt Val ue) ( ( i nt Val ue) &0xf f )
#def i ne hi ni bbl e( char Val ue) ( ( char Val ue) >>4)
#def i ne l oni bbl e( char Val ue) ( ( char Val ue) &0xf )

/ / Common bi t def i nes
#def i ne B_I N 1
#def i ne B_OUT 0
#def i ne B_HI GH 1
#def i ne B_LOW 0

/ / Common byt e def i nes
#def i ne W_I N 0xf f
#def i ne W_OUT 0
#def i ne W_HI GH 0xf f
#def i ne W_LOW 0

/ / Common per i pher al cont r ol def i nes
#def i ne P_ON 1
#def i ne P_OFF 0

/ / Common user i nt er f ace def i nes
#def i ne I _UP 1
#def i ne I _DOWN 0

/ / Logi cal def i nes
#def i ne TRUE 1
#def i ne FALSE 0
#def i ne t r ue TRUE
#def i ne f al se FALSE

/ / Har dwar e pul l up def i nes
#def i ne por t _b_pul l ups( f l ag) RBPU=f l ag==0

/ / ASCI I cont r ol char act er def i nes ( usef ul l f or comms)
#def i ne A_NUL 0
#def i ne A_SOH 1
#def i ne A_STX 2
#def i ne A_ETX 3
#def i ne A_EOT 4
#def i ne A_ENQ 5
#def i ne A_ACK 6
#def i ne A_BEL 7
#def i ne A_BS 8
#def i ne A_HT 9
#def i ne A_LF 0xa
#def i ne A_VT 0xb
#def i ne A_FF 0xc
#def i ne A_CR 0xd
#def i ne A_SO 0xe
#def i ne A_SI 0xf
63
#def i ne A_DLE 0x10
#def i ne A_DC1 0x11
#def i ne A_DC2 0x12
#def i ne A_DC3 0x13
#def i ne A_DC4 0x14
#def i ne A_NAK 0x15
#def i ne A_SYN 0x16
#def i ne A_ETB 0x17
#def i ne A_CAN 0x18
#def i ne A_EM 0x19
#def i ne A_SUB 0x1a
#def i ne A_ESC 0x1b
#def i ne A_FS 0x1c
#def i ne A_GS 0x1d
#def i ne A_RS 0x1e
#def i ne A_US 0x1f

/ / Ti mer 0 def i nes
#def i ne RTCC_I NTERNAL 0 / / r t cc_st at e val ues ( OR t oget her )
#def i ne RTCC_EXT_L_TO_H 0x20
#def i ne RTCC_EXT_H_TO_L 0x30

#def i ne RTCC_DI V_2 0 / / ps_st at e val ues ( OR t oget her )
#def i ne RTCC_DI V_4 1
#def i ne RTCC_DI V_8 2
#def i ne RTCC_DI V_16 3
#def i ne RTCC_DI V_32 4
#def i ne RTCC_DI V_64 5
#def i ne RTCC_DI V_128 6
#def i ne RTCC_DI V_256 7
#def i ne WDT_18MS 8
#def i ne WDT_36MS 9
#def i ne WDT_72MS 0xa
#def i ne WDT_144MS 0xb
#def i ne WDT_288MS 0xc
#def i ne WDT_576MS 0xd
#def i ne WDT_1152MS 0xe
#def i ne WDT_2304MS 0xf

#def i ne Set up_Count er s( r t cc_st at e, ps_st at e) OPTI ON=( OPTI ON&0xc0) | r t cc_st at e| ps_st at e
#def i ne get _r t cc( ) TMR0
#def i ne set _r t cc( t val ue) TMR0=t val ue
#def i ne get _t i mer 0( ) get _r t cc( )
#def i ne set _t i mer 0( t val ue) set _r t cc( t val ue)

/ / Ti mer 1 def i nes
#def i ne T1_ENABLED 1 / / t i mer 1 modes ( OR t oget her )
#def i ne T1_I NTERNAL 1
#def i ne T1_EXTERNAL 7
#def i ne T1_EXTERNAL_SYNC 3
#def i ne T1_CLK_OUT 8
#def i ne T1_DI V_BY_1 0
#def i ne T1_DI V_BY_2 0x10
#def i ne T1_DI V_BY_4 0x20
#def i ne T1_DI V_BY_8 0x30

#def i ne set up_t i mer _1( mode) T1CON=mode
#def i ne enabl e_t i mer _1( st at e) TMR1ON=st at e
#def i ne get _t i mer 1( ) TMR1L
#def i ne set _t i mer 1( t val ue) TMR1L=t val ue

/ / Ti mer 2 def i nes
#def i ne T2_DI SABLED 0 / / t i mer 2 modes ( OR t oget her )
#def i ne T2_DI V_BY_1 4 / / T2_DI SABLED must be on i t s own
#def i ne T2_DI V_BY_4 5 / / post scal e i s 1 t o 16
#def i ne T2_DI V_BY_16 7

#def i ne set up_t i mer _2( mode, post scal e) T2CON=mode| ( ( post scal e- 1) <<3)
#def i ne get _t i mer 2( ) TMR2
#def i ne set _t i mer 2( t val ue) TMR2=t val ue

/ / CCP def i nes
st at i c vol at i l e bi t CCP1 @( unsi gned) &PORTC*8+2; ; / / CCP1 por t pi n
st at i c vol at i l e bi t CCP2 @( unsi gned) &PORTC*8+1; ; / / CCP2 por t pi n

#def i ne CCP_OFF 0
#def i ne CCP_CAPTURE_FE 4
#def i ne CCP_CAPTURE_RE 5
#def i ne CCP_CAPTURE_DI V_4 6
#def i ne CCP_CAPTURE_DI V_16 7
#def i ne CCP_COMPARE_SET_ON_MATCH 8
#def i ne CCP_COMPARE_CLR_ON_MATCH 9
#def i ne CCP_COMPARE_I NT 0xa
#def i ne CCP_COMPARE_RESET_TI MER 0xb
#def i ne CCP_PWM 0xc
#def i ne CCP_PWM_PLUS_1 0x1c
#def i ne CCP_PWM_PLUS_2 0x2c
#def i ne CCP_PWM_PLUS_3 0x3c

#def i ne set up_ccp1( mode) CCP1CON=mode
#def i ne set up_ccp2( mode) CCP2CON=mode
64
/ / #def i ne set _ccp1( cval ue) CCPR1L=cval ue
/ / #def i ne set _ccp2( cval ue) CCPR2L=cval ue
#def i ne set _ccp1( cval ue) \
CCPR1L=( ( cval ue) >>2) &0x00FF; \
CCP1CON&=0xCF; \
CCP1CON| =( ( cval ue) &0x03) <<4

#def i ne set _ccp2( cval ue) \
CCPR2L=( ( cval ue) >>2) &0x00FF; \
CCP2CON&=0xCF; \
CCP2CON| =( ( cval ue) &0x03) <<4

#def i ne set _pwm1( cval ue) set _ccp1( cval ue)
#def i ne set _pwm2( cval ue) set _ccp2( cval ue)

#def i ne get _ccp1( ) CCPR1
#def i ne get _ccp2( ) CCPR2

/ / I nt er r upt def i nes

#def i ne GLOBAL 0x80
#def i ne RTCC_ZERO 0x20
#def i ne RB_CHANGE 0x08
#def i ne EXT_I NT 0x10
#def i ne I NT_TI MER0 0x20
#def i ne I NT_TI MER1 0x0100
#def i ne I NT_TI MER2 0x0200
#def i ne I NT_CCP1 0x0400
#def i ne I NT_CCP2 0x10000
#def i ne I NT_SSP 0x0800
#def i ne I NT_PSP 0x8000
#def i ne I NT_RX 0x2000
#def i ne I NT_TX 0x1000
#def i ne I NT_CMP 0x400000
#def i ne ADC_DONE 0x4000
#def i ne EE_DONE 0x100000
#def i ne SER_BCL 0x40000

#def i ne enabl e_per i pher al _i nt er r upt s( ) PEI E=1
#def i ne enabl e_gl obal _i nt er r upt s( ) GI E=1
#def i ne enabl e_i nt er r upt s( l evel ) \
I NTCON| =( l evel ) &0xf f ; \
PI E1| =( ( l evel ) >>8) &0xf f ; \
PI E2| =( l evel ) >>16
#def i ne enabl e_r t cc_i nt er r upt ( ) T0I E=1

#def i ne di sabl e_per i pher al _i nt er r upt s( ) PEI E=0
#def i ne di sabl e_gl obal _i nt er r upt s( ) do GI E=0; whi l e( GI E)
#def i ne di sabl e_i nt er r upt s( l evel ) \
I NTCON&=~( ( l evel ) &0xf f ) ; \
PI E1&=~( ( ( l evel ) >>8) &0xf f ) ; \
PI E2&=~( ( l evel ) >>16)
#def i ne di sabl e_r t cc_i nt er r upt ( ) T0I E=0

/ / USART def i nes

#def i ne SER_MASTER 0x80
#def i ne SER_9BI T 0x40
#def i ne SER_TX_ENABLE 0x20
#def i ne SER_SYNCHRONOUS 0x10
#def i ne SER_HI GH_BAUD 4
#def i ne SER_TSR_EMPTY 2
#def i ne SER_ENABLE 0x80
#def i ne SER_RX_SGL 0x20
#def i ne SER_RX_CON 0x10

#def i ne kbhi t ( ) RCI F

#def i ne set _l o_baud( baud) SPBRG=( unsi gned char ) ( ( 2*( l ong) _CLOCK_/ 64+( l ong) baud) / 2/ \
( l ong) baud- 1) ; TXSTA &= ~SER_HI GH_BAUD
#def i ne set _hi _baud( baud) SPBRG=( unsi gned char ) ( ( 2*( l ong) _CLOCK_/ 16+( l ong) baud) / 2/ \
( l ong) baud- 1) ; TXSTA | = SER_HI GH_BAUD

#def i ne set up_usar t _async8_l o( baud) \
TRI SC | = 0xc0; \
TXSTA=SER_MASTER| SER_TX_ENABLE| SER_TSR_EMPTY; \
RCSTA=SER_ENABLE| SER_RX_CON; \
set _l o_baud( baud)

#def i ne set up_usar t _async9_l o( baud) \
TRI SC | = 0xc0; \
TXSTA=SER_MASTER| SER_TX_ENABLE| SER_TSR_EMPTY| SER_9BI T; \
RCSTA=SER_ENABLE| SER_RX_CON| SER_9BI T; \
set _l o_baud( baud)

#def i ne set up_usar t _async8_hi ( baud) \
TRI SC | = 0xc0; \
TXSTA=SER_MASTER| SER_TX_ENABLE| SER_TSR_EMPTY; \
RCSTA=SER_ENABLE| SER_RX_CON; \
set _hi _baud( baud)

65
#def i ne set up_usar t _async9_hi ( baud) \
TRI SC | = 0xc0; \
TXSTA=SER_MASTER| SER_TX_ENABLE| SER_TSR_EMPTY| SER_9BI T; \
RCSTA=SER_ENABLE| SER_RX_CON| SER_9BI T; \
set _hi _baud( baud)

st at i c vol at i l e bi t t xd @( unsi gned) &PORTC*8+6; ; / / USART ser i al dat a out pi n
st at i c vol at i l e bi t r xd @( unsi gned) &PORTC*8+7; ; / / USART ser i al dat a i n pi n

/ / SPI def i nes
#def i ne SPI _MASTER 0x20
#def i ne SPI _SLAVE 0x24
#def i ne SPI _SS_DI SABLED 0x25
#def i ne SPI _L_TO_H 0
#def i ne SPI _H_TO_L 0x10
#def i ne SPI _CLK_DI V_4 0
#def i ne SPI _CLK_DI V_16 1
#def i ne SPI _CLK_DI V_64 2
#def i ne SPI _CLK_T2 3
#def i ne spi _enabl e( en) SSPEN=! ! en / / enabl es t he spi
#def i ne spi _dat a_i s_i n( ) BF / / t est s t he buf f er f ul l bi t

st at i c vol at i l e bi t sdo @( unsi gned) &PORTC*8+5; / / ser i al dat a out pi n
st at i c vol at i l e bi t sdo_di r @( unsi gned) &TRI SC*8+5; / / ser i al dat a out di r ect i on bi t
st at i c vol at i l e bi t sdi @( unsi gned) &PORTC*8+4; / / ser i al dat a i n pi n
st at i c vol at i l e bi t sdi _di r @( unsi gned) &TRI SC*8+4; / / ser i al dat a i n di r ect i on bi t
st at i c vol at i l e bi t sck @( unsi gned) &PORTC*8+3; / / ser i al cl ock pi n
st at i c vol at i l e bi t sck_di r @( unsi gned) &TRI SC*8+3; / / ser i al cl ock di r ect i on bi t
st at i c vol at i l e bi t ss_di r @( unsi gned) &TRI SA*8+5; / / synchr onous sl ave mode enabl e bi t
st at i c vol at i l e bi t BF @( unsi gned) &SSPSTAT*8+0; / / spi buf f er f ul l bi t

#endi f / / COMMDEFS_H

3.7. eeprom.c
/ *

I ncl udi ng t hi s f i l e i ni t i al i ses t he 256 EEPROM 8- bi t byt es t o t he cor r ect val ues.
Wor ks on 16F876, see Hi - Tech C FAQ.

Cr eat ed f or PI CuWEB - PI C mi cr os and C
ht t p: / / www. wor ki ngt ex. com/ ht pi c
( c) 2001 Shane Tol mi e

Thi s f i l e i s i n use f or a commer ci al pr oduct , wi t h appr ox. 7000 l i nes of C, and
copi es of t hi s code ar e cur r ent l y r unni ng on 1100+ 16F876- based uni t s wor l dwi de.

*/

#i ncl ude " mot or . h"

/ / [ user change]
#def i ne PROFI LE 0 / / 0 f or nor mal set up
/ / 1 f or EEPROM f i l l ed wi t h zer os

/ / [ do not al t er ]
#i f ( PROFI LE! =0) && ( PROFI LE! =1)
#er r or eep_i ni t 13
#endi f

#asm
psect eedat a, del t a=2, abs, ovr l d
or g 2100h
#endasm

#i f ( PROFI LE==0)
#asm
db STRAI GHT, AUX_DOUBLE, 130, SR_50ms, RC_MI N, RC_MAX, RC_MI N, RC_MAX
db RC_MI N, RC_MAX, RC_MI N, RC_MAX, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
66
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
#endasm
#endi f

#i f ( PROFI LE==1) / / not hi ng i n EEPROM
#asm
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
#endasm
#endi f


3.8. eeprom.h
#i f ndef _EEPROM_H
#def i ne _EEPROM_H

#def i ne eeaddMi xMode 0x00
#def i ne eeaddAuxMode 0x01
#def i ne eeaddDeadBand 0x02
#def i ne eeaddSl ewRat e 0x03
#def i ne eeaddRC1l ow 0x04
#def i ne eeaddRC1hi gh 0x05
#def i ne eeaddRC2l ow 0x06
#def i ne eeaddRC2hi gh 0x07
#def i ne eeaddRC3l ow 0x08
#def i ne eeaddRC3hi gh 0x09
#def i ne eeaddRC4l ow 0x0A
#def i ne eeaddRC4hi gh 0x0B

#endi f / / _EEPROM_H
67

Você também pode gostar