Você está na página 1de 64

Universidade Estadual de Campinas

nica
Faculdade de Engenharia Meca

ES670 - Projeto de Sistemas


Embarcados
Relat
orio 7/7

Nome:
Lucas Neves Egidio
Tiago Noboru Ukei

30 de junho de 2015

RA
103167
104224

Sum
ario
1 Objetivos

2 Modelagem

3 Diagramas esquem
aticos do target utilizados

10

4 Matriz de rastreabilidade de requisitos vs implementaco


es

14

5 C
alculos utilizados
15
5.1 Perodo do PWM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
5.2 Controlador PID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
6 Notas

16

7 Refer
encias

17

A C
odigo
A.1 adc.h . . .
A.2 adc.c . . .
A.3 buzlib.h .
A.4 buzlib.c .
A.5 cooler.h .
A.6 cooler.c .
A.7 dsplib.h .
A.8 dsplib.c .
A.9 es670 pp.h
A.10 es670 pp.c
A.11 fsmlib.h .
A.12 fsmlib.c .
A.13 intlib.h . .
A.14 intlib.c . .
A.15 lcd.h . . .
A.16 lcd.c . . .
A.17 ledswi.h .
A.18 ledswi.c .
A.19 mclab2.h .
A.20 pidlib.h .
A.21 pidlib.c . .
A.22 pwm.h . .
A.23 pwm.c . .
A.24 rs232lib.h
A.25 rs232lib.c
A.26 tachlib.h .
A.27 tachlib.c .
A.28 timerlib.h
A.29 timerlib.c

18
18
19
20
21
21
22
23
24
25
26
31
31
34
35
36
37
40
41
44
47
48
50
50
52
53
55
55
56
57

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

A.30 util.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
A.31 util.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

Objetivos

Com a conclusao do projeto, foram implementados todos os requisitos do plano


inicial. Na primeira fase, implementamos os requisitos de projeto relativos ao monitoramento das 4 chaves tipo push button e ao acionamento dos 4 LEDs e dos 4
displays de 7 segmentos presentes na placa de circuito impresso.
Na segunda parte do projeto, tivemos como objetivo implementar os requisitos
relativos a` comunicacao serial do target com um PC atraves de um cabo RS232.
Na terceira parte, foi implementada a comunicacao com o display LCD. A implementacao foi feita em C e utilizamos o PIC18F4550 para o controle.
Durante a quarta parte, a leitura da velocidade do ventilador presente no kit foi
implementada atraves de um contador.
Durante a quinta parte, foi implementado o controle do sinal PWM que aciona
o ventilador, permitindo controlar a corrente media enviada ao seu motor.
Na sexta parte as funcoes referentes a` conversao analogico-digital do sensor de
temperatura foram implementadas.
Ja nesta u
ltima parte, foi implementado um controle PID para a temperatura
aquisitada pelo sensor.
Os seguintes itens foram exercitados durante a execucao desse projeto:
Familiarizacao com a parte de codigos ja desenvolvidos;
Familiarizacao com a parte de modelos ja desenvolvidos;
Exercitar desenvolvimento iterativo e incremental;
Implementacao de protocolo de comunicacao serial;
Realizacao de maquina de estados;
Tratamento de interrupcoes;
Testar;
Apresentar (durante a aula) modelos, codigos e testes no target.

Modelagem

Nesta secao, apresentamos os diagramas utilizados para a modelagem do sistema,


para atender aos requisitos do projeto.
A Figura 1 mostra o diagrama de requisitos do sistema, especificado na SysML,
que contem todos os requisitos de projeto implementados, sem se importar com os
detalhes de implementacao.

a5aas55aa555555

sssssssssssssssssssssssssssssssssssssss
5555555555555555555555555555555555
a5aa5a5a5a55a5aa5555555a55a55555a

a5aa555555

a5aa555555

a5aa555555

a5aa555555OOOOOaO

a5aa555555OOa

a5aa555555aAa5OOG7aOG

Aa5A5aOA5O

Aa5A5aOA5B

Aa5A5aOA5O

O5555555a5a5 55 5555555555
555555a55555a55 55 a 555
55 55. a5 5.a555..

O5555555a5a5 5555555a ae5a5


a555a55 5OOa5.

O5555555a5a5 5555555a ae5a5


a555a55 5a55 a 55a5575
55a55555.

a5aa555555

a5aa555555

a5aa555555

a5aa5555555aOOOOOOO

a5aa555555OOa

a5aa555555EOOOOAaOaO

Aa5A5aOA5

Aa5A5aOA3

O5555555a5a5 55 555a555a55
555555 55a55555a55a 55
5555a 55a ae5a555555.555
555aa5555555555a5555a5a55
a555 555..555555a55555555a.

O5555555a5a5 5555555a ae5a5


5 5.555555aa555
a .aa5.555a55a55OOa.

Aa5A5aOA
O5555555a5a5 5555555a ae5a5
55a 5ea5555a5 555a55
5 555aaa55a55555a 5.

a5aa555555

a5aa555555

a5aa555555

a5aa5555555MM

a5aa555555OaO

a5aa555555OOEOaOOO

Aa5A5aOA5

Aa5A5aOA6

Aa5A5aOA7

O5555555a5a5 5555555a ae5a5


a55a55a5555a 5a555MM.

O5555555a5a5 5555555a ae5a5


55a 5ea55a5 555a5a5a5555a 5
aa a5555555a5..55a5
55 555 55O5a5a5555555a .

O5555555a5a5 5555555a ae5a5


55a 5ea55a5.a555a 5aaa55a55
55555 aa555a5a55a .

Figura 1: Diagrama de requisitos.

A Figura 2 mostra o diagrama de pacotes, de acordo com a linguagem UML,


utilizado para implementacao do programa, que especifica a estrutura na qual o
sistema esta organizado.

a5aas a55555
sssssssssssssssssssssssssssssssssssssss
5555555555555555555555555555555555
a5aa5a5a5a555a55555

s5555555s55a5555

sa5aa555555

Ma5

M5Oa.5

l55

A5O5.

a5535O5.

BaeO5.

055O5.

a5 O5.

O5aad5

O5a

O55 55

Oa5 O5.

O5555O5.

5d5

Oa5

55aO5.

5aa55355.5

Figura 2: Diagrama de pacotes implementados.

A Figura 3 mostra o diagrama de definicao de blocos, tal como e definido na


SysML, o qual mostra a estrutura do sistema juntamente com suas propriedades,
operacoes e relacionamentos.
sssssssssssssssssssssssssssssssssssssss
5555555555555555555555555555555555
a5aa5a5a5a55a5.55

55a55B 5555

aa.5 5555

aa.5 5555

5d5pp d5

Oa5ppaa5

l5aa5

OaOsOOEEOaOAOEsaOEOp55A5
OaOsOOEEOaOAOEs5aOOOaaAEGp55A5
OaOsOOEEOaOAOEsGOp55A5

d5s5555d5ddp 55a
d5s555aa5 O 5 5da5aa5 O 5 5pa55a5a555dp 55a

aa.5 5555

O5555O5.pp55555 5.
aa.5 5555

Oa5 O5.pp5a5 5.
l5aa5

aa5s555Oa5ddp 55a
aa5s55Oa5a55ddpa55a5a555
aa5s55a55O5 55555ddp 55a
aa5sa55Ea a5ddpa55a5a555

l5aa5

5a5 5.s555ddp 55a


5a5 5.s55aaddp 55a
5a5 5.s555 a55O55 55E5 5555 ddpa55a5a555

l5aa5

aa.5 5555

55555 5.s555O55555O5O5a555ddp 55a


55555 5.s55555O55555O5a555ddp 55a
55555 5.s55a55O55555O5a555ddp 55a
55555 5.s555 O55555O5a555ddp 55a
55555 5.sa55O55555O5a555ddpa55a5a555
55555 5.s55.5aO 5 55O 55a55 5ddp 55a
55555 5.s55555O 5 55O 55a55 5ddp 55a

aa.5 5555

O5aad5pp 5a5d5

MO4sOOasaMAp55A5

O55 55pp555 55
5

OOOOOasBOOaOasElMp55A7

l5aa5

555 55s555O55 55ddp 55a


555 55s5a5OO..d5a5OO..pa55a5a55 a5dp 55a

05 5

l5aa5

55675s5aA555a 5ea555ddp 55a


5a5ddp 55a
55675s 55 a55ddp 55a
55675s555 55Oa5dddp 55a
55675sd5555O55 55E5 5555 ddp 55a
55675s555 a55O55 55a5a55Oa5dddp ...

5a 5.s555daa5ap5AasaOOO5ddaOpa5a. 5dp 55a


5a 5.s555 a55Oa5 a5daa5ap5AasaOOO5ddp55
5a 5.sa aa55A a5daa5ap5AasaOOO5dda5M5a5pa55a5a555dp 55a
5a 5.sa aa55a5..daa5ap5AasaOOO5ddaa5..pa5a. 5dp 55a
5a 5.sa aa55Ga5daa5ap5AasaOOO5ddad5pa5a. 5dadapa5a. 5dadApa5a. 5dp 55a

aa.5 5555

Ma5pp55675s

l5aa5

55aO5.pp 5a 5.

5a5d5s555O5aad555 d5O5aEa5p5 a5d5ad555 Ea5p5 a5dp 55a


5a5d5s555O5ad5O5aEa5p5 a5dp 55a
5a5d5s5 5a5O5ad5O5aEa5p5 a5dp 55a
5a5d5sa55ad555 a5a5a5d5ad555 Ea5p5 a5dp5d555 s55a5a5s5 5s5
5a5d5s55aaO5ad5O5aEa5p5 a5dp55
5a5d5s a M55 O5a5d5a5aa5p55dp 55a

l5aa5

aa.5 5555

BaeO5.pp.ae 5.

l5aa5

500 555

.ae 5.s555ddp 55a


.ae 5.s a Baed555555ap55d5aa5a555Map55dp 55a

l5aa5
l5aa5

l5aa5

l5aa5
aa.5 5555

05 5

5
l5aa5

5as555O5addp 55a
5asd5555aa5ada5aa5apa55a5a55 a5dp 55a
5as55aO555aada5O5apa55a5a55 a5dp 55a
5asM5555a555ad55Ba..55p5555555555 a5ddp 55a
5as555Oa5555d5O55pa55a5a55 a5d5O5 a5pa55a5a55 a5dp 55a
5asaa55 O5 5ddp 55a
5asd5555Ea55d5Ea55p5 a5dd5aap5 a5ddp 55a

l5aa5

5ds555ddp 55a
5a s555ddp 55a
55 5.s555ddp 55a

O5appO5a

M5Oa.5pp55 a.5
A5O5.pp55 5.

l5aa5
l5aa5

l5aa5

l5aa5

aa.5 5555

a5535O5.pp55535 5.

l5aa5

l5aa5
5

aA0OsO0sBl00Oap55A55
OAMOOlOp55A5555

aa.5 5555

l55 ppa55
aa.5 5555

a5 O5.ppa5 5.

55535 5.s555ddp 55a


55535 5.s55a a5aa ddp55
55535 5.s55555 5B 55ddp5 a5
55535 5.s55aB 55d5B 55p5 a5dp 55a
55535 5.s55555 5Ba..55d5Ba..p5 a5ddp 55a
55535 5.s55aBa..55d5Ba..p5 a5ddp 55a

lOAOs5asAOOaOOAOEsElMp55A55
OOM5sEOOs0aOAp55A55
OOM5sOOM5s0aOAp55A5

aa5p5 a5dA.5 30d55 56d55 5Bd55 0d55 66d55 6ad55 7ad5...


a5
a5
a5
a5

5.sa55 a A55ddp 55a


5.sa55 a M5555d5A a5p5 a5ddp 55a
5.s55a555a5 da5Ea5.55pa55a5a555d5Oa5p5 a5ddp 55a
5.s55d5 5a5 da5Ea5.55pa55a5a555d5Oa5p5 a5ddp 55a

l5aa5

5
aa.5 5555

055O5.pp.55 5.

l5aa5

a55 sa5a5 a 5Maddp 55a


a55 sa5a5 a 55Maddp 55a
a55 sa5a5 a 555Maddp 55a
a55 sa5a5 a 555Maddp 55a
a55 s55Ea5.55d5Ea a5p5 a5dp55
a55 s55 5550555l55O5555da5Ea pa55a5a555d5a55p5 a5ddp 55a
a55 s555 a55O 5O 55Eddp 55a

l5aa5

aMAOOdsO5OEp5 a5d
aMAOOdsOOOaOap5 a5d
OOasaOOp5 a5d
OOasOOOOaOap5 a5d
EOsOEap5 a5d
5a5555a5a55pa5a55

l5aa5
55a 5.

l5aa5

.55 5.s555ddp 55a


.55 5.s5555 555O5ad5Ba..a5ap5 a5dd5Ba..O5p5 a5ddp55

5555a
l5aa5

Figura 3: Diagrama de definicao de blocos.

O diagrama de estados utilizado para implementacao da maquina de estados que


realiza a interpretacao dos comandos (REQ2), e ilustrado a seguir.

5aa55555.5

ddddddddddsdddddd
sssssssssssssssssssssssssssssssssssssss
5dd5dddd5d5ddddd5d5dd5ddd5dddd5]55
sddddddddddds5dddd5

ddddddddddddddddddd
dddddd

ddddddeddd

dded

ddddddddddddddddd

]d]]]]]d]]]]d]]d]d]]

]d]]]]]d]]]]d]]d]]]]

ddddddddddddddddd

]d]]]]]d]]]]d]]d]]]]

]d]]]]]d]]]]d]]d]d]]

]d]]]]]d]]]]d]]d]]]]

ddddddddd

]]ddddddd

ddddddddddddddddd

]d]]ddd

ddddddddddddddddd

ddddddddddddddddd

Figura 4: Diagrama de estados da maquina de estados finitos (FSM) implementada.

Utilizamos tambem um diagrama de sequencia, que evidencia a sequencia de


mensagens comunicadas entre os elementos para o tratamento do protocolo de comunicacaa5aas55aa555
o do host com o target, para implementacao do REQ2.
p55675s

p55535 5.

p55 5.

p.55 5.

55535 5.s555dd
55 5.s555dd
.55 5.s555dd
5a s555dd

55535 5.s55555 5Ba..55d5Ba.d

.55 5.s5555 555O5ad5Ba..a5ad5Ba..O5d

55535 5.s55aBa..55d5Ba.d

5dddd5dd]d5

sssssssssssssssssssssssssssssssssssssss
5555555555555555555555555555555555
a5aa5a5a5a55a5aas55a555A555 555aa555a55O55aa55

Figura 5: Diagrama de sequencia para o interpretador de comandos.

A Figura 6 apresenta o diagrama de sequencia que mostra o funcionamento do


cclico executivo.

aa5
p55675s

p55555 5.

55675s5aA555a 5ea555dd

55675s 55 a55dd

55555 5.s55.5aO 5 55O 55a55 5dd

55

]d 5 5dOalOd]

55675s555 a55O55 55a5a55Oa5ddd

55675s555d5a555aa5 O 5 5Oa5ddd

55675s555 55Oa5ddd

55675sd5555O55 55E5 5555 dd

>d d55555>

Figura 6: Diagrama de sequencia para o funcionamento do cclico executivo.

A Figura 7 mostra o diagrama de atividades para o funcionamento do display


LCD.
Ea

mA

a
sssssssssssssssssssssssssssssssssssssss
55aa55
5
5 55.5
5 a 55
a
55555
A

a a E

a a

5 DDssDssDsssssDDsDDD

a a
a
SS
EEEEEE
AEAE

E
a

E A
a

D a

a a
a a
a

a
a

E A

a a

Figura 7: Diagrama de atividades do display LCD.

A Figura 8 apresenta o diagrama da maquina de estados da tarefa de computar


temperatura.

Controlador PID digital

Diagrama
de blocos
do controlador
do PID temperatura.
Figura 8: Diagrama
de estados
da tarefa de computar
A Figura 9 mostra o diagrama de blocos do controlador PID utilizado para o
controle da temperatura.

Figura 9: Diagrama de blocos do controlador PID.

Loubach, D. S. (UNICAMP)

ES670 - Projeto de Sistemas Embarcados

1o Semestre de 2015

34 / 35

Diagramas esquem
aticos do target utilizados

A figura a seguir mostra o diagrama de acionamento dos LEDs e monitoramento


das chaves, utilizada para implementacao do requisito REQ1A e REQ1B. Note que
ambos compartilham as mesmas portas do microcontrolador.

Figura 10: Diagrama de acionamento dos LEDs e monitoramento das chaves.

A Figura 11 mostra o diagrama de acendimento dos displays de 7 segmentos


(REQ1C).

Figura 11: Diagrama de acendimento dos displays.

10

A figura abaixo mostra o circuito esquematico que representa a ligacao entre o


conector DB9 e o microprocessador, atraves de um CI conversor de nvel MAX232,
utilizado para implementar o requisito REQ2.

Figura 12: Diagrama de comunicacao via RS232.

Na figura abaixo, e mostrado o esquema da ligacao entre o display LCD e o


microprocessador (REQ3).

Figura 13: Diagrama de conexoes entre o PIC e o display LCD.

Nas Figuras 14 e 15, podemos ver o esquema de ligacao do tacometro e do


ventilador com o PIC.

11

Figura 14: Diagrama de conexoes entre o PIC e tacometro.

Figura 15: Diagrama de conexoes entre o PIC e o ventilador.

12

Figura 16: Diagrama de conex


oes o diodo medidor de temperatura, seu circuito condicionador de sinais e o PIC.

Figura 17: Diagrama de conexoes entre o PIC e o resistor aquecedor.

13

Matriz de rastreabilidade de requisitos vs implementaco


es
A Tabela 1 mostra a matriz de rastreabilidade de requisitos vs implementacoes.

ID do requisito
REQ1A

REQ1B

REQ1C

REQ2

REQ3

REQ4

REQ5

REQ6

REQ7

Implementa
c
ao
ledswi.c
- void ledswi initLedSwitch(char cLedNum, char cSwitchNum)
- switch status type e ledswi getSwitchStatus(char cSwitchNum)
ledswi.c
- void ledswi initLedSwitch(char cLedNum, char cSwitchNum)
- void ledswi setLed(char cLedNum)
- void ledswi clearLed(char cLedNum)
dsplib.c
- void dsplib displayInit(void)
- void dsplib displayWrite(char cInput[4])
rs232lib.c
- void rs232lib init(void)
- void rs232lib receiveBuffer(char* cBuf)
- void rs232lib sendBuffer(char* cBuf)
intlib.c
- void intlib init(void)
- void high isr(void)
fsmlib.c
- void fsmlib init(void)
- int fsmlib interpretCmd(char* cBuffReq, char* cBuffAns )
lcd.c
- void lcd initLcd(void)
- void lcd writeData(unsigned char ucData)
- void lcd sendCommand(unsigned char ucCmd)
- void lcd WriteString(const rom char *ccBuffer)
- void lcd setCursor(unsigned char cLine, unsigned char cColumn)
tachlib.c
- void tachlib init(void)
- unsigned int tachlib computeCoolerVelocity(void)
pwm.c
- void pwm initPwm(void)
- void pwm setDutyCycle(const unsigned int uiDutyCycle)
adc.c
- void adc initAdc(void)
- void adc startConvertion(void)
- unsigned int adc getValue(void)
- unsigned int adc isAdcDone(const unsigned int uiDutyCycle)
pidlib.c
- void pidlib init(PID DATA* data, double dT)
- int pidlib computeOutput(PID DATA* data)
- void pidlib updateInput(PID DATA* data, unsigned int uiMeas)
- void pidlib updateReff(PID DATA* data, double dReff)
- void pidlib updateGain(PID DATA* data, double dKP, double dKD, double dKI)

Tabela 1: Matriz de rastreabilidade de requisitos do projeto implementados.

14

C
alculos utilizados

5.1

Perodo do PWM

Foi especificada uma frequencia de PWM de fP W M = 46.875 Hz. Para isso,


utilizamos a formula da equacao (15-1) do Datasheet [2]
fP W M =

fOSC
.
4(PR2 + 1)[TMR2 Prescale Value]

(1)

Foi possvel entao encontrar, para fOSC = 48MHz um valor de PR2 = 255.

5.2

Controlador PID

A equacao do controlador PID analogico pode ser escrita da seguinte maneira:




Z
1 t
d
u(t) = K e(t) +
e( )d + td e(t)
(2)
Ti 0
dt
onde:
K e o ganho;
Ti e o tempo de integracao;
Td e o tempo de derivacao.
Utilizando a integracao trapezoidal e equacoes a` diferencas, obtemos a seguinte
equacao para o controlador PID digital:
u(k) = u(k 1) + q0 e(k) + q1 e(k 1) + q2 e(k 2)
onde:

Td
T0
+
q0 = K 1 +
2Ti T0


Td
T0
q1 = K 1 + 2
T0 2Ti
 
Td
q2 = K
T0


T0 e o perodo de amostragem do controlador

15

(3)

Notas

Durante a realizacao dos primeiros testes, apos a implementacao dos requisitos


REQ1A, REQ1B e REQ1C, encontramos dificuldades para testar o programa no target,
pois a fonte de alimentacao da placa de circuito impressa estava com problemas.
Apos substituda a fonte, foi possvel testar o programa, o qual atendeu bem aos
requisitos.
Na segunda fase do projeto, notamos que erros de Framming e Overrun ocorriam
frequentemente na transmissao de dados do PC para o target. Esse problema foi
resolvido por meio da implementacao de uma rotina de tratamento desses erros antes
da leitura do registrador. Alem disso, a implementacao por Polling se mostrou
ineficiente em alguns casos em que o target executava outras atividades alem do
tratamento dos comandos recebidos via RS232, o que ocasionalmente gerava perda
na transmissao de dados. Logo, optamos pela implementacao por interrupcao, que
apresentou um resultado bem mais satisfatorio.
Na implementacao do REQ3, notamos que deve-se respeitar o tempo de processamento de cada comando do LCD antes de enviar um novo. Para isso, foi alterado
o delay do codigo fornecido pelo professor, na funcao lcd write2Lcd().
Na implementacao do REQ4, foram feitas adaptacoes nos codigos fornecidos visando o melhor mapeamento dos registradores e pinos do PIC que formam o contexto
dos timers. Foi entao criada a biblioteca timerlib.c.
Para a implementacao do REQ5, foi encontrada uma dificuldade de vencer a
inercia inicial do ventilador parado quando o duty-cycle era menor ou igual que
75%. Para isso, sempre que o motor e acionado partindo do repouso, o duty-cycle e
colocado em 100% ate que o motor inicie o movimento e logo apos e regulado para
o valor desejado.
Durante a implementacao do REQ6, nao tivemos problemas.
Para a implementacao do REQ7, utilizamos a interface serial para enviar os
comandos para modificar os parametros do controlador PID e o valor da temperatura
de referencia. Os switches estao sendo utilizados para controlar o duty-cycle do
cooler. A velocidade do ventilador e o respectivo duty-cycle sao impressos no display
LCD, enquanto o valor medido da temperatura e enviado pela comunicacao serial.
Podemos afirmar que o projeto foi implementado com sucesso, atendendo perfeitamente a todos os requisitos especificados.

16

Refer
encias
[1] Roteiro de Laboratorio - Semanas 04 a 14. Disponvel em: http:
//www.ggte.unicamp.br/ea/
[2] Microchip, PIC18F2455/2550/4455/4550 Data Sheet. Microchip Technology Inc., 2009. Disponvel em: http://ww1.microchip.com/
downloads/en/DeviceDoc/39632e.pdf

17

C
odigo

Segue abaixo o codigo utilizado para implementar os requisitos apresentados na


Figura 1.

A.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

/*
/*
/*
/*
/*
/*
/*
/*

adc.h

*****************************************************************
File name:
adc.h
File description: Header file containing the functions/methods
interfaces for handling the ADC module from uC
Author name:
dloubach
Creation date:
21mai2015
Revision date:
22mai2015
*****************************************************************

#ifndef ADC_H
#define ADC_H
#define ADC_CONVERTION_DONE
#define ADC_CONVERTION_PROCESSING
#define ADC_CONVERTION_GO

1
0
1

/* ************************************************
/* Method name:
adc_initAdc
/* Method description: initialize the ADC configs
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void adc_initAdc(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
adc_isAdcDone
/* Method description: verify if the AD convertion
/*
is done
/* Input params:
n/a
/* Outpu params:
1 if done, 0 otherwise
/* ************************************************
unsigned int adc_isAdcDone(void);

*/
*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
adc_startConvertion
/* Method description: start the AD convertion
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void adc_startConvertion(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
adc_getValue
/* Method description: return the value after the
/*
AD convertion is done
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
unsigned int adc_getValue(void);

*/
*/
*/
*/
*/
*/
*/

#endif /* ADC_H */

18

*/
*/
*/
*/
*/
*/
*/
*/

A.2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

/*
/*
/*
/*
/*
/*
/*
/*

adc.c

*****************************************************************
File name:
adc.c
File description: File dedicated to the function implementation
related to ADC module from the uC target
Author name:
dloubach
Creation date:
21mai2015
Revision date:
22mai2015
*****************************************************************

#include "adc.h"
#include "mclab2.h"
/* ************************************************
/* Method name:
adc_initAdc
/* Method description: initialize the ADC configs
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void adc_initAdc(void)
{
/* let's select the CHANNEL 0 */
ADCON0bits.CHS = 0;

*/
*/
*/
*/
*/
*/

/* config the reference voltage */


ADCON1bits.VCFG1 = 0; //VSS
ADCON1bits.VCFG0 = 0; //VDD
/* AD port configuration, for AN0 going to ANALOG INPUT */
ADCON1bits.PCFG = 0b1110;
/* right justfied */
ADCON2bits.ADFM = 1;
/* acquistion time */
ADCON2bits.ACQT = 0b101; // 12 TAD
/* converstion clock */
ADCON2bits.ADCS = 0b110; // 64 TOSC
/* ADC module ON */
ADCON0bits.ADON = 1;
}

/* ************************************************
/* Method name:
adc_isAdcDone
/* Method description: verify if the AD convertion
/*
is done
/* Input params:
n/a
/* Outpu params:
1 if done, 0 otherwise
/* ************************************************
unsigned int adc_isAdcDone(void)
{
unsigned char ucAdcStatus;
int iReturn;
/* get the ADC convertion status */
ucAdcStatus = ADCON0bits.GO_DONE;
/* check it */
if(ucAdcStatus)
iReturn = ADC_CONVERTION_PROCESSING;
else
iReturn = ADC_CONVERTION_DONE;
/* return the result */
return (iReturn);

19

*/
*/
*/
*/
*/
*/
*/

*/
*/
*/
*/
*/
*/
*/
*/

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

/* ************************************************
/* Method name:
adc_startConvertion
/* Method description: start the AD convertion
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void adc_startConvertion(void)
{
ADCON0bits.GO_DONE = ADC_CONVERTION_GO;
}

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
adc_getValue
/* Method description: return the value after the
/*
AD convertion is done
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
unsigned int adc_getValue(void)
{
unsigned int uiAdcLowValue;
unsigned int uiAdcValue;

*/
*/
*/
*/
*/
*/
*/

/* return the MSB + LSB parts */


uiAdcLowValue = ADRESL;
uiAdcValue = (((unsigned int)ADRESH & 0x03) << 8) + uiAdcLowValue;
return(uiAdcValue);
}

A.3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

/*
/*
/*
/*
/*
/*
/*
/*

buzlib.h

*****************************************************************
File name:
buzlib.h
File description: Header file containing the functions/methods
prototypes of buzlib.c
Author name:
tukei & legidio
Creation date:
17abr2015
Revision date:
17abr2015
*****************************************************************

#ifndef BUZLIB_H
#define BUZLIB_H
/* Define period of oscillation for each note */
#define MN_DO
19
#define MN_RE
17
#define MN_MI
15
#define MN_FA
14
#define MN_SOL 13
/* ************************************************
/* Method name:
buzlib_init
/* Method description: Initialize buzzer
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void buzlib_init(void);

*/
*/
*/
*/
*/
*/

/* ************************************************ */

20

*/
*/
*/
*/
*/
*/
*/
*/

29
30
31
32
33
34
35
36
37
38

/* Method name:
buzlib_playBuz
/* Method description: Play buzzer
/* Input params:
iPeriod = half of the period
/*
of oscillation
/*
iDurationMS = duration in ms
/* Outpu params:
n/a
/* ************************************************
void buzlib_playBuz(int,int);
#endif /* BUZLIB_H */

A.4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

/*
/*
/*
/*
/*
/*
/*
/*

buzlib.c

*****************************************************************
File name:
buzlib.c
File description: This file has some functions that handle the
buzzer
Author name:
tukei & legidio
Creation date:
17abr2015
Revision date:
17abr2015
*****************************************************************

*/
*/
*/
*/
*/
*/
*/
*/

#include "mclab2.h"
#include "buzlib.h"
#include "util.h"
/* ************************************************
/* Method name:
buzlib_init
/* Method description: Initialize buzzer
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void buzlib_init(void) {
BUZZ_DIR = OUTPUT;
}

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
buzlib_playBuz
/* Method description: Play buzzer
/* Input params:
iPeriod = half of the period
/*
of oscillation
/*
iDurationMS = duration in ms
/* Outpu params:
n/a
/* ************************************************
void buzlib_playBuz(int iPeriod, int iDurationMS) {
int j,i;
for(i=0;i<iDurationMS/(iPeriod*2);i++){
BUZZER = _ON;
for(j=0;j<iPeriod;j++)
util_genDelay1MS();
BUZZER = _OFF;
for(j=0;j<(iPeriod);j++)
util_genDelay1MS();
}
}

*/
*/
*/
*/
*/
*/
*/
*/

A.5
1
2
3

*/
*/
*/
*/
*/
*/
*/

cooler.h

/* ***************************************************************** */
/* File name:
cooler.h
*/
/* File description: Header file containing the functions/methods
*/

21

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

/*
/*
/*
/*
/*
/*

interfaces for handling the COOLER hardware from*/


the target
*/
Author name:
dloubach
*/
Creation date:
04mai2015
*/
Revision date:
04mai2015
*/
***************************************************************** */

#ifndef COOLER_H
#define COOLER_H
#define COOLER_BLADES_NUM

/* ************************************************ */
/* Method name:
cooler_initCooler
*/
/* Method description: initialize the cooler configs*/
/* Input params:
n/a
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void cooler_initCooler(void);
/* ************************************************ */
/* Method name:
cooler_turnOnOff
*/
/* Method description: initialize the cooler configs*/
/* Input params:
cucOnOff => COOLER_ON
*/
/*
=> COOLER_OFF
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void cooler_turnOnOff(const unsigned char cucOnOff);
#endif /* COOLER_H */

A.6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

/*
/*
/*
/*
/*
/*
/*
/*

cooler.c

*****************************************************************
File name:
cooler.c
File description: File dedicated to the function implementation
related to the COOLER installed in the target
Author name:
dloubach
Creation date:
04mai2015
Revision date:
04mai2015
*****************************************************************

#include "cooler.h"
#include "mclab2.h"
/* ************************************************ */
/* Method name:
cooler_initCooler
*/
/* Method description: initialize the cooler configs*/
/* Input params:
n/a
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void cooler_initCooler(void)
{
COOLER = 0x0;
COOLER_DIR = OUTPUT;
}
/* ************************************************ */
/* Method name:
cooler_turnOnOff
*/
/* Method description: initialize the cooler configs*/
/* Input params:
cucOnOff => COOLER_ON
*/
/*
=> COOLER_OFF
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void cooler_turnOnOff(const unsigned char cucOnOff)
{

22

*/
*/
*/
*/
*/
*/
*/
*/

34
35
36
37
38
39
40
41
42

/* check input for turn on or turn off the cooler */


if(COOLER_ON == cucOnOff)
COOLER = COOLER_ON;
else
{
if(COOLER_OFF == cucOnOff)
COOLER = COOLER_OFF;
}
}

A.7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

/*
/*
/*
/*
/*
/*
/*
/*

dsplib.h

*****************************************************************
File name:
dsplib.h
File description: Header file containing the functions/methods
prototypes of dsplib.c
Author name:
tukei & legidio
Creation date:
20mar2015
Revision date:
27mar2015
*****************************************************************

#ifndef DSPLIB_H
#define DSPLIB_H
/* ************************************************
/* Method name:
dsplib_displayInit
/* Method description: Initialize 7 seg display
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void dsplib_displayInit(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
dsplib_displayWrite
/* Method description: Since the pins that output
/*
data to the four digit of
/*
the display are shared, this
/*
function multiplexes the
/*
output
/* Input params:
cInput[] = array of chars to
/*
be displayed
/* Outpu params:
n/a
/* ************************************************
void dsplib_displayWrite(char*);

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
dsplib_intDec2dsp
/* Method description: Converts an integer with up
/*
to 4 dec digit to disp array
/* Input params:
uiNumber = int to be convert
/*
cOut = array with 4 digits
/*
to be displayed
/* Outpu params:
n/a
/* Modify:
cOut
/* ************************************************
void dsplib_intDec2dsp(unsigned int, char*);

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

/*
/*
/*
/*
/*
/*
/*
/*
/*

*/
*/
*/
*/
*/
*/
*/
*/
*/

************************************************
Method name:
dsplib_intHex2dsp
Method description: Converts an integer with up
to 4 hex digit to disp array
Input params:
uiNumber = int to be convert
cOut = array with 4 digits
to be displayed
Outpu params:
n/a
Modify:
cOut

23

*/
*/
*/
*/
*/
*/
*/
*/

55
56
57
58

/* ************************************************ */
void dsplib_intHex2dsp(unsigned int, char*);
#endif /* DSPLIB_H */

A.8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

/*
/*
/*
/*
/*
/*
/*
/*

dsplib.c

*****************************************************************
File name:
dsplib.c
File description: This file has some functions that handle the
7 segment display
Author name:
tukei & legidio
Creation date:
20mar2015
Revision date:
27mar2015
*****************************************************************

*/
*/
*/
*/
*/
*/
*/
*/

#include "mclab2.h"
#include "dsplib.h"
#include "util.h"
/* Define which segments are to be lit for each character */
const char DSP[17] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x80};
/* ************************************************
/* Method name:
dsplib_displayInit
/* Method description: Initialize 7 seg display
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void dsplib_displayInit(void){
DSP_OUT_DIR = 0x00;
DSP_OUT = 0x00;
DSP1_EN_DIR = OUTPUT;
DSP2_EN_DIR = OUTPUT;
DSP3_EN_DIR = OUTPUT;
DSP4_EN_DIR = OUTPUT;
}

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
dsplib_displayWrite
/* Method description: Since the pins that output
/*
data to the four digit of
/*
the display are shared, this
/*
function multiplexes the
/*
output
/* Input params:
cInput[] = array of chars to
/*
be displayed
/* Outpu params:
n/a
/* ************************************************
void dsplib_displayWrite(char cInput[4]) {
int i;
for(i=0;i<4;i++){
switch(i){
case 3:
DSP1_EN = _ON;
DSP2_EN = _OFF;
DSP3_EN = _OFF;
DSP4_EN = _OFF;
break;
case 2:
DSP1_EN = _OFF;
DSP2_EN = _ON;
DSP3_EN = _OFF;
DSP4_EN = _OFF;
break;

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

24

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

case 1:
DSP1_EN
DSP2_EN
DSP3_EN
DSP4_EN
break;
case 0:
DSP1_EN
DSP2_EN
DSP3_EN
DSP4_EN
break;

_OFF;
_OFF;
_ON;
_OFF;

=
=
=
=

_OFF;
_OFF;
_OFF;
_ON;

}
DSP_OUT = cInput[i];
util_genDelay10MS();
}
}
/* ************************************************
/* Method name:
dsplib_intDec2dsp
/* Method description: Converts an integer with up
/*
to 4 dec digit to disp array
/* Input params:
uiNumber = int to be convert
/*
cOut = array with 4 digits
/*
to be displayed
/* Outpu params:
n/a
/* Modify:
cOut
/* ************************************************
void dsplib_intDec2dsp(unsigned int uiNumber, char*
int i;
for(i=0;i<4;i++,uiNumber/=10)
cOut[i] = DSP[uiNumber%10];
if(uiNumber > 0) // Overflow
cOut[0] |= DSP[16];
}

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
cOut) {

/* ************************************************
/* Method name:
dsplib_intHex2dsp
/* Method description: Converts an integer with up
/*
to 4 hex digit to disp array
/* Input params:
uiNumber = int to be convert
/*
cOut = array with 4 digits
/*
to be displayed
/* Outpu params:
n/a
/* Modify:
cOut
/* ************************************************
void dsplib_intHex2dsp(unsigned int uiNumber, char*
int i;
for(i=0;i<4;i++,uiNumber/=16)
cOut[i] = DSP[uiNumber%16];
if(uiNumber > 0) // Overflow
cOut[0] |= DSP[16];
}

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
cOut) {

A.9
1
2
3
4
5
6
7
8
9
10

=
=
=
=

/*
/*
/*
/*
/*
/*
/*
/*

es670 pp.h

*****************************************************************
File name:
es670.h
File description: Header file containing a couple of defintions
used for configuring the uC
Author name:
dloubach
Creation date:
09jan2015
Revision date:
29mai2015
*****************************************************************

#ifndef ES670_H

25

*/
*/
*/
*/
*/
*/
*/
*/

11
12
13
14
15
16
17
18
19
20
21

#define ES670_H
/* general constants */
#define TRUE
1
#define FALSE
0
#define ADC_TRANSF_EQ_PARAM_A
#define ADC_TRANSF_EQ_PARAM_B
#define CLEAN_DATA

0x00

#endif /* ES670_H */

A.10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

0.4073
-123.75

/*
/*
/*
/*
/*
/*
/*

es670 pp.c

*****************************************************************
File name:
es670_pp.c
File description: Main file for the ES670 Practical Project
Author name:
tukei e legidio
Creation date:
20jan2015
Revision date:
26jun2015
*****************************************************************

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

*/
*/
*/
*/
*/
*/
*/

"es670_pp.h"
"mclab2.h"
"ledswi.h"
"util.h"
"lcd.h"
"cooler.h"
"intlib.h"
"timerlib.h"
"tachlib.h"
"dsplib.h"
"rs232lib.h"
"fsmlib.h"
"buzlib.h"
"pwm.h"
"adc.h"
"pidlib.h"

/* uC init configurations */
/* uC @
#pragma
#pragma
#pragma

48 MHz
config
config
config

*/
PLLDIV = 1
CPUDIV = OSC1_PLL2
FOSC
= XTPLL_XT

//Divide by 1 (04 MHz oscillator input)


//96 MHz PLL Src: /2
//XT oscillator, PLL enabled

#pragma
#pragma
#pragma
#pragma
#pragma
#pragma

config
config
config
config
config
config

IESO
PWRT
BOR
BORV
WDT
LVP

//Oscillator Switchover mode disabled


//Power-up Timer enabled
//Brown-out Reset enabled
//Brown-out Reset to maximum setting
//Watchdog timer disabled
//Single-Supply ICSP disabled

=
=
=
=
=
=

OFF
ON
ON
0
OFF
OFF

/* global variables */
volatile unsigned int uiFlagNextPeriod = 0; // cyclic executive flag
unsigned int uiAdcTaskState;
unsigned int uiTemperature;
unsigned int uiTempCelsius;
unsigned int uiCycExecN = 0;
unsigned int uiPwmDc = 0;
PID_DATA PID1data;
/* state machine related to ADC task */
#define ADC_TASK_STATE_INIT
0
#define ADC_TASK_STATE_CONVERTING
1
#define ADC_TASK_STATE_DONE
2

26

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

/* transfer equation for AD to Temperature


* f(y) = ax + b
* the parameters apply only in the range
* 28oC to 89oC
* ADC_TRANSF_EQ_LOW_LIM to ADC_TRANSF_EQ_HIG_LIM
* which could be obtained when heater is in 50% duty cycle PWM
*/
#define ADC_TRANSF_EQ_LOW_LIM
350
#define ADC_TRANSF_EQ_HIG_LIM
500
/* ************************************************
/* Method name:
es670_runInitialization
/* Method description: takes care of uC intial
/*
configurations
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void es670_runInitialization(void)
{
/* clean all ports */
PORTA = CLEAN_DATA;
PORTB = CLEAN_DATA;
PORTC = CLEAN_DATA;
PORTD = CLEAN_DATA;
PORTE = CLEAN_DATA;
/* init ADC */
adc_initAdc();
/* init leds and switches */
ledswi_initLedSwitch(04, 00);
/* initialize display */
dsplib_displayInit();
/* initialize RS232 */
rs232lib_init();
/* initialize finite state machine */
fsmlib_init();
/* initialize buzzer */
buzlib_init();
/* initialize interruption */
intlib_init();
/* init LCD */
lcd_initLcd();
/* init cooler */
cooler_initCooler();
/* init PWM module for cooler */
pwm_initPwm(PWM_COOLER);
/* init PWM module for heater */
pwm_initPwm(PWM_HEATER);
/* init TIMER1 as counter,
* used for counting the number of pulses
* originated from the cooler
*/
timerlib_initTimer1AsCounter();
/* init tachometer */
tachlib_init();
/* init PID */

27

*/
*/
*/
*/
*/
*/
*/

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

pidlib_init(&PID1data,1.0/UTIL_1S_ITERATION_NUM);
}
/* ************************************************ */
/* Method name:
es670_prepare
*/
/* Method description: prepare things before execute*/
/*
the main program loop
*/
/* Input params:
n/a
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void es670_prepare(void)
{
unsigned int i;
/* write something in the LCD and play with LEDs */
lcd_sendCommand(CMD_CLEAR);
lcd_setCursor(0,0);
lcd_dummyText();
for(i=0; i<25; i++) {
ledswi_setLed(i%4+1);
ledswi_clearLed((i-1)%4+1);
util_genDelay500MS();
util_genDelay500MS();
}
ledswi_clearLed((i-1)%4+1);
lcd_sendCommand(CMD_CLEAR);
/* play with leds */
ledswi_initLedSwitch(00, 04);
/* init TIMER1 counter */
timerlib_startTimer1Counter();
/* set DC for heater PWM in 50% */
uiAdcTaskState = ADC_TASK_STATE_INIT;
}
/* ************************************************ */
/* Method name:
es670_coolerTask
*/
/* Method description: this task (method) plays with*/
/*
the cooler installed on target*/
/* Input params:
n/a
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void es670_coolerTask(void)
{
int i;
if(SWITCH_ON == ledswi_getSwitchStatus(01)) {
i = tachlib_read();
pwm_setDutyCycle(1023,PWM_COOLER);
while(tachlib_read() == i);
while(tachlib_read() != i);
uiPwmDc = 1;
}
if(SWITCH_ON == ledswi_getSwitchStatus(02)){
i = tachlib_read();
pwm_setDutyCycle(1023,PWM_COOLER);
while(tachlib_read() == i);
while(tachlib_read() != i);
uiPwmDc = 2;
}
if(SWITCH_ON == ledswi_getSwitchStatus(03)){
i = tachlib_read();
pwm_setDutyCycle(1023,PWM_COOLER);
while(tachlib_read() == i);
while(tachlib_read() != i);
uiPwmDc = 3;
}

28

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

if(SWITCH_ON == ledswi_getSwitchStatus(04))
uiPwmDc = 4;
if(SWITCH_ON == ledswi_getSwitchStatus(01) &&
SWITCH_ON == ledswi_getSwitchStatus(04))
uiPwmDc = 0;
pwm_setDutyCycle(uiPwmDc*1023/4,PWM_COOLER);
}
/* ************************************************
/* Method name:
es670_writeCoolerVelocity
/* Method description: writes cooler speed and duty
/*
cycle on LCD
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void es670_writeCoolerVelocity(void)
{
char cBuffer1[]="0 ";
char cBuffer2[]="0 ";
char cDefaultTxt1[] = "Speed:
RPS";
char cDefaultTxt2[] = "DC:
%";

*/
*/
*/
*/
*/
*/
*/

if(uiCycExecN%COMP_VEL_FREQ != 0)
return;
lcd_setCursor(0,0);
lcd_WriteString(cDefaultTxt1);
lcd_setCursor(0,7);
util_convertFromUi2Ascii(tachlib_computeCoolerVelocity(),cBuffer1);
lcd_WriteString(cBuffer1);
lcd_setCursor(1,0);
lcd_WriteString(cDefaultTxt2);
lcd_setCursor(1,4);
util_convertFromUi2Ascii(uiPwmDc*25, cBuffer2);
lcd_WriteString(cBuffer2);
}
/* ************************************************ */
/* Method name:
es670_computeTemperatureTask */
/* Method description: compute the temperature based*/
/*
in the target sensor D1
*/
/*
*/
/*
Period = 500 ms
*/
/*
*/
/* Input params:
n/a
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void es670_computeTemperatureTask(void)
{
char cBuffer[10];
char cBuff1[7] = "Temp: ";
char cBuff2[7] = "Tref: ";
if(uiCycExecN%COMP_TMP_FREQ != 0)
return;
switch(uiAdcTaskState){
case ADC_TASK_STATE_INIT:
adc_startConvertion();
uiAdcTaskState = ADC_TASK_STATE_CONVERTING;
break;
case ADC_TASK_STATE_CONVERTING:
if(adc_isAdcDone() == ADC_CONVERTION_DONE){
uiTemperature = adc_getValue();
uiAdcTaskState = ADC_TASK_STATE_DONE;
}
break;
case ADC_TASK_STATE_DONE:
if (uiTemperature >= ADC_TRANSF_EQ_LOW_LIM &&
uiTemperature <= ADC_TRANSF_EQ_HIG_LIM)

29

uiTempCelsius = ADC_TRANSF_EQ_PARAM_A*uiTemperature + ADC_TRANSF_EQ_PARAM_B;


else
uiTempCelsius = uiTemperature;
pidlib_updateInput(&PID1data, uiTemperature);
rs232lib_sendBuffer(cBuff1);
util_convertFromUi2Ascii(uiTempCelsius, cBuffer);
rs232lib_sendBuffer(cBuffer);
rs232lib_sendNewLine();
rs232lib_sendBuffer(cBuff2);
util_convertFromUi2Ascii(ADC_TRANSF_EQ_PARAM_A*PID1data.dReff + ADC_TRANSF_EQ_PARAM_B, cBuffer);
rs232lib_sendBuffer(cBuffer);
rs232lib_sendNewLine();
rs232lib_sendNewLine();
uiAdcTaskState = ADC_TASK_STATE_INIT;
break;

263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

}
}
/* ************************************************
/* Method name:
es670_setHeaterDutyCycleTask
/* Method description: compute and set PWM DC of
/*
the heater
/*
/*
Period = 500 ms
/*
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void es670_setHeaterDutyCycleTask(void)
{
int iPwm;
if(uiCycExecN%COMP_PID_FREQ != 0)
return;
iPwm = pidlib_computeOutput(&PID1data);
if(iPwm<0)
iPwm=0;

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

pwm_setDutyCycle(iPwm, PWM_HEATER);
}

/* ************************************************
/* Method name:
main
/* Method description: main program function
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void main(void)
{
/* run uC init configs */
es670_runInitialization();

*/
*/
*/
*/
*/
*/

/* prepare something before entering the main loop */


es670_prepare();
/* config and start the cyclic executive */
timerlib_configCyclicExecutive();
/* main system loop, runs forever */
while(TRUE)
{
es670_computeTemperatureTask();
es670_setHeaterDutyCycleTask();
es670_coolerTask();
es670_writeCoolerVelocity();
/* WAIT FOR CYCLIC EXECUTIVE PERIOD */
while(!uiFlagNextPeriod);

30

331
332
333
334

uiFlagNextPeriod = 0;
} /* while(TRUE) */
}

A.11

fsmlib.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

/*
/*
/*
/*
/*
/*
/*
/*

*****************************************************************
File name:
fsmlib.h
File description: Header file containing the functions/methods
prototypes of fsmlib.c
Author name:
tukei & legidio
Creation date:
10abr2015
Revision date:
17abr2015
*****************************************************************

#ifndef FSMLIB_H
#define FSMLIB_H
/* ************************************************
/* Method name:
fsmlib_init
/* Method description: Initialize FSM
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void fsmlib_init(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
fsmlib_interpretCmd
/* Method description: Interprets the commands
/*
received by the target
/* Input params:
cBuffReq = buffer of request
/*
cBuffAns = buffer of answer
/* Outpu params:
1 if error, 0 otherwise
/* Modify:
cBuffAns
/* ************************************************
int fsmlib_interpretCmd(char*,char*);

*/
*/
*/
*/
*/
*/
*/
*/
*/

#endif /* FSMLIB_H */

A.12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

*/
*/
*/
*/
*/
*/
*/
*/

/*
/*
/*
/*
/*
/*
/*
/*

fsmlib.c

*****************************************************************
File name:
fsmlib.c
File description: This file has some functions that interpret the
commands, using a finite state machine
Author name:
tukei & legidio
Creation date:
10abr2015
Revision date:
26jun2015
*****************************************************************

#include
#include
#include
#include
#include
#include
#include

"fsmlib.h"
"ledswi.h"
"buzlib.h"
"util.h"
"pidlib.h"
<string.h>
<stdlib.h>

31

*/
*/
*/
*/
*/
*/
*/
*/

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

typedef enum {Idle, LedCmd, SwitchCmd, BuzzerCmd, ReffCmd, ControlCmd} State;


/* Variable that keeps the current state of the FSM */
State currentState;
/* Define strings of answers to the commands */
const char SWITCH_OPEN[] = "O\r\n";
const char SWITCH_CLOSED[] = "C\r\n";
const char LED_SET[] = "S\r\n";
const char LED_CLEARED[] = "C\r\n";
const char NO_ANS[] = "";
extern PID_DATA PID1data;
/* ************************************************
/* Method name:
fsmlib_init
/* Method description: Initialize FSM
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void fsmlib_init(void) {
currentState = Idle;
}

*/
*/
*/
*/
*/
*/

/* ************************************************ */
/* Method name:
fsmlib_interpretCmd
*/
/* Method description: Interprets the commands
*/
/*
received by the target
*/
/* Input params:
cBuffReq = buffer of request */
/*
cBuffAns = buffer of answer */
/* Outpu params:
1 if error, 0 otherwise
*/
/* Modify:
cBuffAns
*/
/* ************************************************ */
int fsmlib_interpretCmd(char* cBuffReq, char* cBuffAns) {
int iVarNum; /* Receives numerical parts of commands */
/* Answers nothing by default */
strcpy(cBuffAns, NO_ANS);
/* Finite state machine to interpret commands */
do {
switch(currentState) {
/* Initial state */
case Idle:
switch(cBuffReq[0]) {
case 'L':
currentState =
break;
case 'S':
currentState =
break;
case 'B':
currentState =
break;
case 'T':
currentState =
break;
case 'K':
currentState =
break;
default:
currentState =
return 1;
}
break;

LedCmd;

SwitchCmd;

BuzzerCmd;

ReffCmd;

ControlCmd;

Idle;

/* LED command */

32

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

case LedCmd:
iVarNum = cBuffReq[2]-48;
currentState = Idle;
if(iVarNum < 1 || iVarNum > MAX_LED_SWI)
return 1;
switch(cBuffReq[1]) {
case 'S':
ledswi_setLed(iVarNum);
break;
case 'C':
ledswi_clearLed(iVarNum);
break;
case 'R':
if(ledswi_readLed(iVarNum))
strcpy(cBuffAns,LED_SET);
else
strcpy(cBuffAns,LED_CLEARED);
break;
default:
return 1;
}
break;
/* Switch command */
case SwitchCmd:
iVarNum = cBuffReq[1]-48;
currentState = Idle;
if(iVarNum < 1 || iVarNum > MAX_LED_SWI)
return 1;
if(!ledswi_getSwitchStatus(iVarNum))
strcpy(cBuffAns,SWITCH_CLOSED);
else
strcpy(cBuffAns,SWITCH_OPEN);
break;
/* Buzzer command */
case BuzzerCmd:
currentState = Idle;
if(util_isNumber(cBuffReq[1]) && util_isNumber(cBuffReq[2])
&& util_isNumber(cBuffReq[3]) && (cBuffReq[4]=='\0' || cBuffReq[4]=='\r')) {
iVarNum = atoi(cBuffReq+1);
buzlib_playBuz(MN_DO,iVarNum);
}
else
return 1;
break;
/* Set reference temperature command */
case ReffCmd:
currentState = Idle;
if(util_isNumber(cBuffReq[1]) && util_isNumber(cBuffReq[2])
&& (cBuffReq[3]=='\0' || cBuffReq[3]=='\r')) {
iVarNum = atoi(cBuffReq+1);
pidlib_updateReff(&PID1data, iVarNum);
}
else
return 1;
break;
/* Define controller constants command */
case ControlCmd:
currentState = Idle;
switch(cBuffReq[1]) {

33

157
158
159
160
161

case 'P':
if(util_isNumber(cBuffReq[2]) && util_isNumber(cBuffReq[3])
&& (cBuffReq[4]=='\0' || cBuffReq[4]=='\r')) {
iVarNum = atoi(cBuffReq+2);
pidlib_updateGain(&PID1data, iVarNum, PID1data.dKD, PID1data.dKI);
}
else
return 1;
break;
case 'D':
if(util_isNumber(cBuffReq[2]) && util_isNumber(cBuffReq[3])
&& (cBuffReq[4]=='\0' || cBuffReq[4]=='\r')) {
iVarNum = atoi(cBuffReq+2);
pidlib_updateGain(&PID1data, PID1data.dKP, iVarNum, PID1data.dKI);
}
else
return 1;
break;
case 'I':
if(util_isNumber(cBuffReq[2]) && util_isNumber(cBuffReq[3])
&& (cBuffReq[4]=='\0' || cBuffReq[4]=='\r')) {
iVarNum = atoi(cBuffReq+2);
pidlib_updateGain(&PID1data, PID1data.dKP, PID1data.dKD, iVarNum);
}
else
return 1;
break;
default:
return 1;

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198

}
break;
default:
currentState = Idle;
return 1;
}
} while(currentState != Idle);
/* Command acknowledged */
return 0;
}

A.13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

/*
/*
/*
/*
/*
/*
/*
/*

intlib.h

*****************************************************************
File name:
intlib.h
File description: Header file containing the functions/methods
prototypes of intlib.c
Author name:
tukei & legidio
Creation date:
17abr2015
Revision date:
17abr2015
*****************************************************************

#ifndef INTLIB_H
#define INTLIB_H
/*
/*
/*
/*
/*
/*

************************************************
Method name:
low_isr
Method description: Handles low prior interrupts
Input params:
n/a
Outpu params:
n/a
************************************************

34

*/
*/
*/
*/
*/
*/

*/
*/
*/
*/
*/
*/
*/
*/

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

void low_isr(void);
/* ************************************************
/* Method name:
high_isr
/* Method description: Handles hi prior interrupts
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void high_isr(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
intlib_init
/* Method description: Initialize interruptions
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void intlib_init(void);

*/
*/
*/
*/
*/
*/

#endif /* INTLIB_H */

A.14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

/*
/*
/*
/*
/*
/*
/*
/*

intlib.c

*****************************************************************
File name:
intlib.c
File description: This file has functions that handle the
interruptions
Author name:
tukei & legidio
Creation date:
17abr2015
Revision date:
17abr2015
*****************************************************************

#include
#include
#include
#include
#include
#include

*/
*/
*/
*/
*/
*/
*/
*/

"mclab2.h"
"fsmlib.h"
"rs232lib.h"
"intlib.h"
"timerlib.h"
"util.h"

#pragma interruptlow low_isr


#pragma interrupt high_isr
/* High priority interruption */
#pragma code high_vector = 0x08
void interrupt_at_high_vector(void) {
_asm GOTO high_isr _endasm
}
#pragma code /* code high_vector = 0x08 */
/* Low priority interruption */
#pragma code low_vector = 0x18
void interrupt_at_low_vector(void) {
_asm GOTO low_isr _endasm
}
#pragma code /* code low_vector = 0x18 */
/* Global variables that help handling the commands received by the target */
char cBuffIn[SIZE_OF_BUFFER];
char cBuffOut[SIZE_OF_BUFFER];
const char ERR_MSG[] = "ERR\r\n";
const char ACK_MSG[] = "ACK\r\n";
extern volatile unsigned int uiFlagNextPeriod; // cyclic executive flag
/*
/*
/*
/*

************************************************
Method name:
low_isr
Method description: Handles low prior interrupts
Input params:
n/a

35

*/
*/
*/
*/

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

/* Outpu params:
n/a
*/
/* ************************************************ */
void low_isr(void) {
return;
}
/* ************************************************
/* Method name:
high_isr
/* Method description: Handles hi prior interrupts
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void high_isr(void) {
/* Timer0 interruption */
if(T0_IF){
/* set the cyclic executive flag */
uiFlagNextPeriod = 1;
/* reset the cyclic executive counting */
util_computeCycExecN();
timerlib_resetCyclicExecutive();
/* acknowledge the interrupt */
T0_IF = 0;
}
/* Serial interruption */
if(RX_READY) {
rs232lib_receiveBuffer(cBuffIn);
if(!fsmlib_interpretCmd(cBuffIn,cBuffOut)){
rs232lib_sendBuffer(ACK_MSG);
rs232lib_sendBuffer(cBuffOut);
}
else {
rs232lib_sendBuffer(ERR_MSG);
}
}
}
/* ************************************************
/* Method name:
intlib_init
/* Method description: Initialize interruptions
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void intlib_init(void) {
PRIO_EN = _ON; //Priority bit enabled
GIEH_EN = _ON; //Enables high priority
GIEL_EN = _ON; //Enables low priority
}

A.15
1
2
3
4
5
6
7
8
9
10
11

*/
*/
*/
*/
*/
*/

/*
/*
/*
/*
/*
/*
/*
/*
/*

*/
*/
*/
*/
*/
*/

lcd.h

*****************************************************************
File name:
es670_pp.h
File description: Header file containing the functions/methods
interfaces for handling the LCD hardware from
the target
Author name:
dloubach
Creation date:
16abr2015
Revision date:
16abr2015
*****************************************************************

#ifndef LCD_H

36

*/
*/
*/
*/
*/
*/
*/
*/
*/

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

#define LCD_H
/* commands list */
#define CMD_INIT_LCD
#define CMD_CLEAR
#define CMD_NO_CURSOR
#define CMD_CURSOR2R
#define CMD_NO_CUR_NO_BLINK

/* ************************************************
/* Method name:
lcd_initLcd
/* Method description: Initialize the LCD function
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void lcd_initLcd(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
lcd_writeData
/* Method description: Write data to be displayed
/* Input params:
ucData => char to be writen
/* Outpu params:
n/a
/* ************************************************
void lcd_writeData(unsigned char ucData);

*/
*/
*/
*/
*/
*/

/* ************************************************ */
/* Method name:
lcd_sendCommand
*/
/* Method description: Write command to LCD
*/
/* Input params:
ucCmd => command to be executed*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void lcd_sendCommand(unsigned char ucCmd);
/* ************************************************
/* Method name:
lcd_WriteString
/* Method description: Write string to be displayed
/* Input params:
ccBuffer => string to be
/*
writen in LCD
/* Outpu params:
n/a
/* ************************************************
void lcd_WriteString(const char *ccBuffer);

*/
*/
*/
*/
*/
*/
*/

/* ************************************************ */
/* Method name:
lcd_setCursor
*/
/* Method description: Set cursor line and column
*/
/* Input params:
cLine = LINE0..LINE1
*/
/*
cColumn = COLUMN0..MAX_COLUMN*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void lcd_setCursor(unsigned char cLine, unsigned char cColumn);
/* ************************************************ */
/* Method name:
lcd_dummyText
*/
/* Method description: Write a dummy hard coded text*/
/* Input params:
n/a
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void lcd_dummyText(void);
#endif /* LCD_H */

A.16
1
2
3

0x0F
0x01
0x0C
0x06 /* cursor to right */
0x38 /* no cursor, no blink */

lcd.c

/* ***************************************************************** */
/* File name:
lcd.c
*/
/* File description: File dedicated to the function implementation
*/

37

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

/*
/*
/*
/*
/*
/*

related to the LCD HARDWARE based on the KS006U


controller
Author name:
dloubach
Creation date:
16abr2015
Revision date:
16abr2015
*****************************************************************

#include "lcd.h"
#include "mclab2.h"
#include "util.h"
/* line and columns */
#define LINE0
0
#define COLUMN0
0
#define L0C0_BASE
#define L1C0_BASE
#define MAX_COLUMN

0x80 /* line 0, column 0 */


0xC0 /* line 1, column 0 */
15

/* ************************************************
/* Method name:
lcd_initLcd
/* Method description: Initialize the LCD function
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void lcd_initLcd(void)
{
/* ports configured as outputs */
LCD_RS_DIR
= OUTPUT;
LCD_ENABLE_DIR = OUTPUT;
LCD_DATA_DIR
= OUTPUT;

*/
*/
*/
*/
*/
*/

// turn-on LCD, with no cursor and no blink


lcd_sendCommand(CMD_NO_CUR_NO_BLINK);
// init LCD
lcd_sendCommand(CMD_INIT_LCD);
// clear LCD
lcd_sendCommand(CMD_CLEAR);
// LCD with no cursor
lcd_sendCommand(CMD_NO_CURSOR);
// cursor shift to right
lcd_sendCommand(CMD_CURSOR2R);
}
/* ************************************************ */
/* Method name:
lcd_write2Lcd
*/
/* Method description: Send command or data to LCD */
/* Input params:
ucBuffer => char to be send */
/*
cDataType => command LCD_RS_CMD*/
/*
or data LCD_RS_DATA
&/
/* Outpu params:
n/a
*/
/* ************************************************ */
void lcd_write2Lcd(unsigned char ucBuffer, unsigned char cDataType)
{
/* writing data or command */
if(LCD_RS_CMD == cDataType)
/* will send a command */
LCD_RS = LCD_RS_CMD;
else
/* will send data */
LCD_RS = LCD_RS_DATA;
/* write in the LCD bus */
LCD_DATA = ucBuffer;

38

*/
*/
*/
*/
*/
*/

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

/* enable, delay, disable LCD */


/* this generates a pulse in the enable pin */
LCD_ENABLE = LCD_ENABLED ;
util_genDelay10MS();
LCD_ENABLE = LCD_DISABLED;
util_genDelay10MS();
util_genDelay10MS();
}
/* ************************************************
/* Method name:
lcd_writeData
/* Method description: Write data to be displayed
/* Input params:
ucData => char to be writen
/* Outpu params:
n/a
/* ************************************************
void lcd_writeData(unsigned char ucData)
{
/* just a relay to send data */
lcd_write2Lcd(ucData, LCD_RS_DATA);
}

*/
*/
*/
*/
*/
*/

/* ************************************************ */
/* Method name:
lcd_sendCommand
*/
/* Method description: Write command to LCD
*/
/* Input params:
ucCmd => command to be executed*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void lcd_sendCommand(unsigned char ucCmd)
{
/* just a relay to send command */
lcd_write2Lcd(ucCmd, LCD_RS_CMD);
}
/* ************************************************
/* Method name:
lcd_WriteString
/* Method description: Write string to be displayed
/* Input params:
ccBuffer => string to be
/*
writen in LCD
/* Outpu params:
n/a
/* ************************************************
void lcd_WriteString(const char *ccBuffer)
{
while(*ccBuffer)
{
lcd_writeData(*ccBuffer++);
};
}

*/
*/
*/
*/
*/
*/
*/

/* ************************************************ */
/* Method name:
lcd_setCursor
*/
/* Method description: Set cursor line and column
*/
/* Input params:
cLine = LINE0..LINE1
*/
/*
cColumn = COLUMN0..MAX_COLUMN*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void lcd_setCursor(unsigned char cLine, unsigned char cColumn)
{
char cCommand;
if(LINE0 == cLine)
/* line 0 */
cCommand = L0C0_BASE;
else
/* line 1 */
cCommand = L1C0_BASE;
/* maximum MAX_COLUMN columns */
cCommand += (cColumn & MAX_COLUMN);
// send the command to set the curor

39

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169

lcd_sendCommand(cCommand);
}
/* ************************************************ */
/* Method name:
lcd_dummyText
*/
/* Method description: Write a dummy hard coded text*/
/* Input params:
n/a
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void lcd_dummyText(void)
{
char buff1[]="*** ES670 ***";
char buff2[]="Prj Sis Embarcad";
// clear LCD
lcd_sendCommand(CMD_CLEAR);
// set the cursor line 0, column 1
lcd_setCursor(0,1);
// send string
lcd_WriteString(buff1);
// set the cursor line 1, column 0
lcd_setCursor(1,0);
lcd_WriteString(buff2);
}

A.17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

/*
/*
/*
/*
/*
/*
/*
/*

ledswi.h

*****************************************************************
File name:
ledswi.h
File description: Header file containing the function/methods
prototypes of ledswi.c
Author name:
tukei & legidio
Creation date:
09jan2015
Revision date:
17abr2015
*****************************************************************

#ifndef LEDSWI_H
#define LEDSWI_H
#define MAX_LED_SWI

04

typedef enum {
SWITCH_ON,
SWITCH_OFF
} switch_status_type_e;
/* ************************************************ */
/* Method name:
ledswi_initLedSwitch
*/
/* Method description: As the hardware board was
*/
/*
designed with LEDs/Switches */
/*
sharing the same pins, this */
/*
method configures how many
*/
/*
LEDS and switches will be
*/
/*
available for the application*/
/* Input params:
cLedNum
= num of LEDs
*/
/*
cSwitchNum = num of Switches */
/*
cLedNum +
*/
/*
cSwitchNum <= MAX_LED_SWI
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void ledswi_initLedSwitch(char cLedNum, char cSwitchNum);
/* ************************************************ */
/* Method name:
ledswi_setLed
*/

40

*/
*/
*/
*/
*/
*/
*/
*/

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

/* Method description: set the led ON


/* Input params:
cLedNum = which LED {1..4}
/* Outpu params:
n/a
/* ************************************************
void ledswi_setLed(char cLedNum);

*/
*/
*/
*/

/* ************************************************
/* Method name:
ledswi_readLed
/* Method description: read the led n
/* Input params:
cLedNum = which LED {1..4}
/* Outpu params:
int
/* ************************************************
int ledswi_readLed(char cLedNum);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
ledswi_clearLed
/* Method description: set the led OFF
/* Input params:
cLedNum = which LED {1..4}
/* Outpu params:
n/a
/* ************************************************
void ledswi_clearLed(char cLedNum);

*/
*/
*/
*/
*/
*/

/* ************************************************ */
/* Method name:
ledswi_getSwitchStatus
*/
/* Method description: return the switch status
*/
/* Input params:
cSwitchNum = which switch
*/
/* Outpu params:
switch_status_type_e
*/
/* ************************************************ */
switch_status_type_e ledswi_getSwitchStatus(char cSwitchNum);
/* ************************************************
/* Method name:
ledswi_playWithLeds
/* Method description: Play with leds
/* Input params:
iRounds => number of rounds
/* Outpu params:
n/a
/* ************************************************
void ledswi_playWithLeds(int iRounds);
#endif /* LEDSWI_H */

A.18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

*/
*/
*/
*/
*/
*/

/*
/*
/*
/*
/*
/*
/*
/*

ledswi.c

*****************************************************************
File name:
ledswi.c
File description: This file has a couple of useful functions to
control LEDs and Switches from MCLAB2 dev kit
Author name:
tukei & legidio
Creation date:
20jan2015
Revision date:
17abr2015
*****************************************************************

#include "ledswi.h"
#include "mclab2.h"
#include "util.h"
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*

************************************************ */
Method name:
ledswi_initLedSwitch
*/
Method description: As the hardware board was
*/
designed with LEDs/Switches */
sharing the same pins, this */
method configures how many
*/
LEDS and switches will be
*/
available for the application*/
Input params:
cLedNum
= num of LEDs
*/
cSwitchNum = num of Switches */
cLedNum +
*/

41

*/
*/
*/
*/
*/
*/
*/
*/

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

/*
cSwitchNum <= MAX_LED_SWI
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void ledswi_initLedSwitch(char cLedNum, char cSwitchNum)
{
/* check if the number to configured is according to
hardware dev kit */
if((cLedNum + cSwitchNum) <= MAX_LED_SWI)
{
/* max number of peripherals to configure is ok, carry on */
switch(cSwitchNum)
{
case 0:
LED_01_DIR = OUTPUT;
LED_02_DIR = OUTPUT;
LED_03_DIR = OUTPUT;
LED_04_DIR = OUTPUT;
break;
case 1:
SWITCH_01_DIR = INPUT;
LED_02_DIR = OUTPUT;
LED_03_DIR = OUTPUT;
LED_04_DIR = OUTPUT;
break;
case 2:
SWITCH_01_DIR = INPUT;
SWITCH_02_DIR = INPUT;
LED_03_DIR = OUTPUT;
LED_04_DIR = OUTPUT;
break;
case 3:
SWITCH_01_DIR = INPUT;
SWITCH_02_DIR = INPUT;
SWITCH_03_DIR = INPUT;
LED_04_DIR = OUTPUT;
break;
case 4:
SWITCH_01_DIR =
SWITCH_02_DIR =
SWITCH_03_DIR =
SWITCH_04_DIR =
break;
} /* switch(cSwitchNum)

INPUT;
INPUT;
INPUT;
INPUT;
*/

} /* if((cLedNum + cSwitchNum) <= MAX_LED_SWI) */


}
/* ************************************************
/* Method name:
ledswi_setLed
/* Method description: set the led ON
/* Input params:
cLedNum = which LED {1..4}
/* Outpu params:
n/a
/* ************************************************
void ledswi_setLed(char cLedNum)
{
/* sanity check */
if(cLedNum <= MAX_LED_SWI && cLedNum > 0)
{
switch(cLedNum)
{
case 1:
LED_01 = _ON;
break;
case 2:
LED_02 = _ON;

42

*/
*/
*/
*/
*/
*/

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

break;
case 3:
LED_03 = _ON;
break;
case 4:
LED_04 = _ON;
break;
} /* switch(cLedNum) */
} /* if(cLedNum <= MAX_LED_SWI) */
}
/* ************************************************
/* Method name:
ledswi_readLed
/* Method description: read the led n
/* Input params:
cLedNum = which LED {1..4}
/* Outpu params:
int
/* ************************************************
int ledswi_readLed(char cLedNum)
{
/* sanity check */
if(cLedNum <= MAX_LED_SWI && cLedNum > 0)
{
switch(cLedNum)
{
case 1:
return LED_01;
break;
case 2:
return LED_02;
break;
case 3:
return LED_03;
break;
case 4:
return LED_04;
break;
} /* switch(cLedNum) */

*/
*/
*/
*/
*/
*/

} /* if(cLedNum <= MAX_LED_SWI) */


}
/* ************************************************
/* Method name:
ledswi_clearLed
/* Method description: set the led OFF
/* Input params:
cLedNum = which LED {1..4}
/* Outpu params:
n/a
/* ************************************************
void ledswi_clearLed(char cLedNum)
{
/* sanity check */
if(cLedNum <= MAX_LED_SWI)
{
switch(cLedNum)
{
case 1:
LED_01 = _OFF;
break;
case 2:
LED_02 = _OFF;
break;
case 3:
LED_03 = _OFF;
break;
case 4:
LED_04 = _OFF;
break;
} /* switch(cLedNum) */
} /* if(cLedNum <= MAX_LED_SWI) */

43

*/
*/
*/
*/
*/
*/

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

}
/* ************************************************ */
/* Method name:
ledswi_getSwitchStatus
*/
/* Method description: return the switch status
*/
/* Input params:
cSwitchNum = which switch
*/
/* Outpu params:
switch_status_type_e
*/
/* ************************************************ */
switch_status_type_e ledswi_getSwitchStatus(char cSwitchNum)
{
switch_status_type_e sstReturn = SWITCH_OFF;
/* sanity check */
if(cSwitchNum <= MAX_LED_SWI)
{
switch(cSwitchNum)
{
case 1:
if(SWITCH_ON == SWITCH_01)
sstReturn = SWITCH_ON;
break;
case 2:
if(SWITCH_ON == SWITCH_02)
sstReturn = SWITCH_ON;
break;
case 3:
if(SWITCH_ON == SWITCH_03)
sstReturn = SWITCH_ON;
break;
case 4:
if(SWITCH_ON == SWITCH_04)
sstReturn = SWITCH_ON;
break;
} /* switch(cSwitchNum) */
/* return the result */
return(sstReturn);
} /* if(cSwitchNum <= MAX_LED_SWI) */
}
/* ************************************************
/* Method name:
ledswi_playWithLeds
/* Method description: Play with leds
/* Input params:
iRounds => number of rounds
/* Outpu params:
n/a
/* ************************************************
void ledswi_playWithLeds(int iRounds)
{
int i;
for(i=0; i<iRounds*4+1; i++) {
ledswi_setLed(i%4+1);
ledswi_clearLed((i-1)%4+1);
util_genDelay500MS();
util_genDelay500MS();
}
ledswi_clearLed((i-1)%4+1);
}

A.19

mclab2.h

44

*/
*/
*/
*/
*/
*/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

/*
/*
/*
/*
/*
/*
/*
/*

*****************************************************************
File name:
mclab2.h
File description: Header file containing the peripherals mapping
of the target development kit MCLAB2 V5.0
Author name:
tukei & legidio
Creation date:
09jan2015
Revision date:
17abr2015
*****************************************************************

#ifndef MCLAB2_H
#define MCLAB2_H
/* uC registers definition */
#include <p18F4550.h>
/* port directions */
#define INPUT
#define OUTPUT

1
0

/* on/off definition */
#define _ON
1
#define _OFF
0
/* switches definition */
#define SWITCH_01
PORTBbits.RB0
#define SWITCH_01_DIR
TRISBbits.RB0
#define SWITCH_02
#define SWITCH_02_DIR

PORTBbits.RB1
TRISBbits.RB1

#define SWITCH_03
#define SWITCH_03_DIR

PORTBbits.RB2
TRISBbits.RB2

#define SWITCH_04
#define SWITCH_04_DIR

PORTBbits.RB3
TRISBbits.RB3

/* LEDs definition */
#define LED_01
#define LED_01_DIR

SWITCH_01
SWITCH_01_DIR

#define LED_02
#define LED_02_DIR

SWITCH_02
SWITCH_02_DIR

#define LED_03
#define LED_03_DIR

SWITCH_03
SWITCH_03_DIR

#define LED_04
#define LED_04_DIR

SWITCH_04
SWITCH_04_DIR

/* 7 Seg Diplays definition */


#define DSP_OUT
PORTD
#define DSP_OUT_DIR
TRISD
#define DSP1_EN
#define DSP1_EN_DIR

PORTBbits.RB7
TRISBbits.RB7

#define DSP2_EN
#define DSP2_EN_DIR

PORTBbits.RB6
TRISBbits.RB6

#define DSP3_EN
#define DSP3_EN_DIR

PORTBbits.RB5
TRISBbits.RB5

#define DSP4_EN
#define DSP4_EN_DIR

PORTBbits.RB4
TRISBbits.RB4

/* USART definition */
#define EN_BIT
#define TX_DIR
#define RX_DIR
#define BAUDH

RCSTAbits.SPEN
TRISCbits.RC6
TRISCbits.RC7
SPBRGH

45

*/
*/
*/
*/
*/
*/
*/
*/

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define

BAUDL
RX_EN
TX_EN
RX_DATA
TX_DATA
RX_READY
TX_READY
OVER_ERR
FRAM_ERR
HI_BAUD
RXINT_EN
RX_PR

SPBRG
RCSTAbits.CREN
TXSTAbits.TXEN
RCREG
TXREG
PIR1bits.RCIF
PIR1bits.TXIF
RCSTAbits.OERR
RCSTAbits.FERR
TXSTAbits.BRGH
PIE1bits.RCIE
IPR1bits.RCIP

/* Interruption definition */
#define PRIO_EN
RCONbits.IPEN
#define GIEH_EN
INTCONbits.GIEH
#define GIEL_EN
INTCONbits.GIEL
/* Buzzer definition */
#define BUZZER
PORTAbits.RA5 // buzzer perip definition
#define BUZZ_DIR
TRISAbits.RA5 // buzzer direction
/* LCD definitions */
/* LCD Register Selector
* Used as register selector input
* When (LCD_RS = LCD_RS_HIGH) => DATA register is selected
* When (LCD_RS = LCD_RS_LOW) => INSTRUCTION register is selected
*/
#define LCD_RS
PORTEbits.RE0
#define LCD_RS_DIR
TRISEbits.RE0
#define LCD_RS_HIGH
#define LCD_RS_DATA

1
LCD_RS_HIGH

#define LCD_RS_LOW
#define LCD_RS_CMD

0
LCD_RS_LOW

#define LCD_ENABLE
#define LCD_ENABLE_DIR

PORTEbits.RE1
TRISEbits.RE1

#define LCD_ENABLED
#define LCD_DISABLED

1
0

#define LCD_DATA
#define LCD_DATA_DIR

PORTD
TRISD

/* Cooler definitions */
#define COOLER
PORTCbits.RC1
#define COOLER_DIR
TRISCbits.RC1
#define COOLER_ON
#define COOLER_OFF

1
0

/* Timer0 definitions */
#define T0_IF
INTCONbits.TMR0IF
#define T0_OV_INT
INTCONbits.TMR0IE
#define T0_EN
T0CONbits.TMR0ON
#define T0_PS
T0CONbits.T0PS
#define T0_PSA
T0CONbits.PSA
#define T0_CLOCK
T0CONbits.T0CS
#define T0_8BIT
T0CONbits.T08BIT
/* Timer1 definitions */
#define T1_16BIT
T1CONbits.RD16
#define T1_CLOCK
T1CONbits.T1RUN
#define T1_PS
T1CONbits.T1CKPS
#define T1_OSC_EN
T1CONbits.T1OSCEN
#define T1_SYNC
T1CONbits.NOT_T1SYNC
#define T1_CS
T1CONbits.TMR1CS

46

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

#define T1_EN

/* Tachometer definitions */
#define TC
PORTCbits.RC0
#define TC_DIR
TRISCbits.RC0
/* PWM (Timer2) definitions */
#define PWM_PERIOD
PR2
#define PWM_PERIOD_PS0 T2CONbits.T2CKPS0
#define PWM_PERIOD_PS1 T2CONbits.T2CKPS1
#define CCP2_PWM_CONFIG CCP2CON
#define CCP1_PWM_CONFIG CCP1CON
#define PWM_EN
T2CONbits.TMR2ON
#define PWM2_DC_L
CCPR2L //8bits
#define PWM2_DC_H
CCP2CONbits.DC2B //2bits
#define PWM1_DC_L
CCPR1L //8bits
#define PWM1_DC_H
CCP1CONbits.DC1B //2bits
/* ADC definition */
#define ADC_CON0
#define ADC_CON1
#define ADC_CON2

ADCON0
ADCON1
ADCON2

/* HEATER definition */
#define HEATER
PORTCbits.RC2
#define HEATER_DIR
TRISCbits.RC2
#endif /* MCLAB2_H */

A.20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

T1CONbits.TMR1ON

/*
/*
/*
/*
/*
/*
/*
/*

pidlib.h

*****************************************************************
File name:
pidlib.h
File description: Header file containing the functions/methods
interfaces for the PID controller
Author name:
tukei & legidio
Creation date:
26jun2015
Revision date:
26jun2015
*****************************************************************

#ifndef PIDLIB_H
#define PIDLIB_H
typedef struct PID_DATA {
double dKP, dKD, dKI;
double dU[3], dE[3], dReff;
double dT;
}PID_DATA;
/* ************************************************
/* Method name:
pidlib_init
/* Method description: Initialize PID
/* Input params:
data = PID data address
/*
dT = Sampling time
/* Outpu params:
n/a
/* ************************************************
void pidlib_init(PID_DATA* data, double dT);

*/
*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
pidlib_computeOutput
/* Method description: Computes output of PID contr
/* Input params:
data = PID data address
/* Outpu params:
int control signal
/* ************************************************
int pidlib_computeOutput(PID_DATA* data);

*/
*/
*/
*/
*/
*/

47

*/
*/
*/
*/
*/
*/
*/
*/

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

/* ************************************************ */
/* Method name:
pidlib_updateInput
*/
/* Method description: Updates input of PID contr
*/
/* Input params:
data = PID data address
*/
/*
uiMeas = Temp measured
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void pidlib_updateInput(PID_DATA* data, unsigned int uiMeas);
/* ************************************************ */
/* Method name:
pidlib_updateReff
*/
/* Method description: Updates reference temp
*/
/* Input params:
data = PID data address
*/
/*
dReff = Reference temp
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void pidlib_updateReff(PID_DATA* data, double dReff);
/* ************************************************ */
/* Method name:
pidlib_updateGain
*/
/* Method description: Updates controller gains
*/
/* Input params:
data = PID data address
*/
/*
dKP = Proportional gain
*/
/*
dKD = Derivative gain
*/
/*
dKI = Integral gain
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void pidlib_updateGain(PID_DATA* data, double dKP, double dKD, double dKI);
#endif

A.21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

/*
/*
/*
/*
/*
/*
/*
/*

/* PIDLIB_H */

pidlib.c

*****************************************************************
File name:
pidlib.c
File description: This file has some functions that implement the
PID controller for the temperature
Author name:
tukei & legidio
Creation date:
26jun2015
Revision date:
26jun2015
*****************************************************************

#include "es670_pp.h"
#include "pidlib.h"
#define K 2
extern unsigned int uiTemperature;
/* ************************************************
/* Method name:
pidlib_init
/* Method description: Initialize PID
/* Input params:
data = PID data address
/*
dT = Sampling time
/* Outpu params:
n/a
/* ************************************************
void pidlib_init(PID_DATA* data, double dT) {
data->dKP = 10;
data->dKD = 0;
data->dKI = 10;
data->dU[0] = 0;
data->dU[1] = 0;
data->dU[2] = 0;
data->dE[0] = 0;
data->dE[1] = 0;
data->dE[2] = 0;

48

*/
*/
*/
*/
*/
*/
*/

*/
*/
*/
*/
*/
*/
*/
*/

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

data->dReff = 50.0;
data->dT = dT;
}
/* ************************************************
/* Method name:
pidlib_computeOutput
/* Method description: Computes output of PID contr
/* Input params:
data = PID data address
/* Outpu params:
int control signal
/* ************************************************
int pidlib_computeOutput(PID_DATA* data) {
int iU;
double dQ[3], dKP = data->dKP, dKI = data->dKI,
dQ[0] = dKP + dKI*dT/2 + dKD/dT;
dQ[1] = -dKP - 2*dKD/2 + dT*dKI/2;
dQ[2] = dKD/dT;

*/
*/
*/
*/
*/
*/

dKD = data->dKD, dT = data->dT;

data->dU[K] = data->dU[K-1] + dQ[0]*data->dE[K] +dQ[1]*data->dE[K-1] + dQ[2]*data->dE[K-2];


if(data->dU[K]>1023)
data->dU[K] = 1023;
if(data->dU[K]<0)
data->dU[K] =0;
iU = (int) data->dU[K];
return iU;
}
/* ************************************************ */
/* Method name:
pidlib_updateInput
*/
/* Method description: Updates input of PID contr
*/
/* Input params:
data = PID data address
*/
/*
uiMeas = Temp measured
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void pidlib_updateInput(PID_DATA* data, unsigned int uiMeas) {
data->dE[K-2] = data->dE[K-1];
data->dE[K-1] = data->dE[K];
data->dU[K-2] = data->dU[K-1];
data->dU[K-1] = data->dU[K];
data->dE[K] = data->dReff - (double) uiMeas;
}
/* ************************************************ */
/* Method name:
pidlib_updateReff
*/
/* Method description: Updates reference temp
*/
/* Input params:
data = PID data address
*/
/*
dReff = Reference temp
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void pidlib_updateReff(PID_DATA* data, double dReff) {
data->dReff = (dReff - ADC_TRANSF_EQ_PARAM_B)/ADC_TRANSF_EQ_PARAM_A;
}
/* ************************************************ */
/* Method name:
pidlib_updateGain
*/
/* Method description: Updates controller gains
*/
/* Input params:
data = PID data address
*/
/*
dKP = Proportional gain
*/
/*
dKD = Derivative gain
*/
/*
dKI = Integral gain
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void pidlib_updateGain(PID_DATA* data, double dKP, double dKD, double dKI) {
data->dKP = dKP;
data->dKD = dKD;
data->dKI = dKI;
}

49

A.22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

/*
/*
/*
/*
/*
/*
/*
/*

*****************************************************************
File name:
pwm.h
File description: Header file containing the functions/methods
interfaces for handling the PWM module from uC
Author name:
dloubach
Creation date:
14mai2015
Revision date:
29mai2015
*****************************************************************

*/
*/
*/
*/
*/
*/
*/
*/

#ifndef PWM_H
#define PWM_H
/* duty
#define
#define
#define
#define
#define
#define

cycle definitions */
PWM_DC_100
1023 /* (210)-1 */
PWM_DC_75
767
PWM_DC_50
511
PWM_DC_25
255
PWM_DC_00
0
PWM_INIT_DC
PWM_DC_00

#define PWM_COOLER
#define PWM_HEATER

0
1

/* ************************************************
/* Method name:
pwm_initPwm
/* Method description: initialize the PWM configs
/* Input params:
ucDevice => PWM_COOLER
/*
=> PWM_HEATER
/* Outpu params:
n/a
/* ************************************************
void pwm_initPwm(unsigned char ucDevice);

*/
*/
*/
*/
*/
*/
*/

/* ************************************************ */
/* Method name:
pwm_setDutyCycle
*/
/* Method description: configure PWM duty cycle
*/
/* Input params:
uiDutyCycle => duty cyle value*/
/*
from 0 to 210 -1
*/
/*
ucDevice => PWM_COOLER
*/
/*
=> PWM_HEATER
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void pwm_setDutyCycle(const unsigned int uiDutyCycle,
unsigned char ucDevice);
#endif /* PWM_H */

A.23
1
2
3
4
5
6
7
8
9
10
11
12

pwm.h

/*
/*
/*
/*
/*
/*
/*
/*

pwm.c

*****************************************************************
File name:
pwm.c
File description: File dedicated to the function implementation
related to PWM module from the uC target
Author name:
dloubach
Creation date:
14mai2015
Revision date:
29mai2015
*****************************************************************

#include "pwm.h"
#include "mclab2.h"

50

*/
*/
*/
*/
*/
*/
*/
*/

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

/* constant for PWM module activation */


#define PWM_MODE_MASK
0x0C
/* duty cycle shift and maks definitions */
#define PWM_DC_SHIFT
0x02
#define PWM_DC_MASK
0x3FF
/* ************************************************
/* Method name:
pwm_initPwm
/* Method description: initialize the PWM configs
/* Input params:
ucDevice => PWM_COOLER
/*
=> PWM_HEATER
/* Outpu params:
n/a
/* ************************************************
void pwm_initPwm(unsigned char ucDevice)
{

*/
*/
*/
*/
*/
*/
*/

/* configure PWM frequency for 46.875 kHz*/


PWM_PERIOD = 0xFF;
// TMR2 counter
PWM_PERIOD_PS0 = 0; // TMR2 prescaler configuration = 1
PWM_PERIOD_PS1 = 0; // TMR2 prescaler configuration = 1
/*
* Target is built to use CCP2 PWM module to
* activate the cooler
*/
if(PWM_COOLER == ucDevice)
{
/* configure initial duty cycle */
pwm_setDutyCycle(PWM_INIT_DC, ucDevice);
/* configure the COOLER direction */
COOLER = 0x0;
COOLER_DIR = OUTPUT;
/* CCPxM3:CCPxM2 = 11 => PWM mode */
CCP2_PWM_CONFIG |= PWM_MODE_MASK;
}
/*
* Target is built to use CCP1 PWM module to
* activate the heater
*/
if(PWM_HEATER == ucDevice)
{
/* configure initial duty cycle */
pwm_setDutyCycle(PWM_INIT_DC, ucDevice);
/* configure the COOLER direction */
HEATER = 0x0;
HEATER_DIR = OUTPUT;
/* CCPxM3:CCPxM2 = 11 => PWM mode */
CCP1_PWM_CONFIG |= PWM_MODE_MASK;
}
/* enable TMR2 */
PWM_EN = 1;
}
/* ************************************************ */
/* Method name:
pwm_setDutyCycle
*/
/* Method description: configure PWM duty cycle
*/
/* Input params:
uiDutyCycle => duty cyle value*/
/*
from 0 to 210 -1
*/
/*
ucDevice => PWM_COOLER
*/
/*
=> PWM_HEATER
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void pwm_setDutyCycle(const unsigned int uiDutyCycle,

51

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

unsigned char ucDevice)


{
/* cooler */
if(PWM_COOLER == ucDevice)
{
PWM2_DC_L = ((uiDutyCycle & PWM_DC_MASK) >> PWM_DC_SHIFT);
PWM2_DC_H = (uiDutyCycle & PWM_DC_SHIFT);
}
/* heater */
if(PWM_HEATER == ucDevice)
{
PWM1_DC_L = ((uiDutyCycle & PWM_DC_MASK) >> PWM_DC_SHIFT);
PWM1_DC_H = (uiDutyCycle & PWM_DC_SHIFT);
}
}

A.24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

/*
/*
/*
/*
/*
/*
/*
/*

rs232lib.h

*****************************************************************
File name:
rs232lib.h
File description: Header file containing the functions/methods
prototypes of rs232lib.c
Author name:
tukei & legidio
Creation date:
10abr2015
Revision date:
17abr2015
*****************************************************************

#ifndef RS232LIB_H
#define RS232LIB_H
#define SIZE_OF_BUFFER 20
#define TIMEOUT 1000
/* ************************************************
/* Method name:
rs232lib_init
/* Method description: Initial config of RS232
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void rs232lib_init(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
rs232lib_isRxReady
/* Method description: Checks if received data is
/*
ready
/* Input params:
n/a
/* Outpu params:
returns 1 if ok, 0 otherwise
/* ************************************************
int rs232lib_isRxReady(void);

*/
*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
rs232lib_receiveByte
/* Method description: Get data from register
/* Input params:
n/a
/* Outpu params:
byte received
/* ************************************************
char rs232lib_receiveByte(void);

*/
*/
*/
*/
*/
*/

/*
/*
/*
/*
/*
/*

*/
*/
*/
*/
*/
*/

************************************************
Method name:
rs232lib_sendByte
Method description: Send data
Input params:
byte to be sent
Outpu params:
n/a
************************************************

52

*/
*/
*/
*/
*/
*/
*/
*/

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

void rs232lib_sendByte(char);
/* ************************************************
/* Method name:
rs232lib_receiveBuffer
/* Method description: Get buffer from register
/* Input params:
variable that receives
/*
buffer
/* Outpu params:
n/a
/* ************************************************
void rs232lib_receiveBuffer(char*);

*/
*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
rs232lib_sendBuffer
/* Method description: Send buffer
/* Input params:
buffer to be sent
/* Outpu params:c
n/a
/* ************************************************
void rs232lib_sendBuffer(char*);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
rs232lib_sendNewLine
/* Method description: Send new line
/* Input params:
n/a
/* Outpu params:c
n/a
/* ************************************************
void rs232lib_sendNewLine(void);

*/
*/
*/
*/
*/
*/

#endif /* RS232LIB_H */

A.25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

/*
/*
/*
/*
/*
/*
/*
/*

rs232lib.c

*****************************************************************
File name:
rs232lib.c
File description: This file has some useful functions to
implement a protocol for serial communication
Author name:
tukei & legidio
Creation date:
10abr2015
Revision date:
17abr2015
*****************************************************************

#include "mclab2.h"
#include "rs232lib.h"
/* ************************************************
/* Method name:
rs232lib_init
/* Method description: Initial config of RS232
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void rs232lib_init(void) {
EN_BIT = _ON;
TX_DIR = INPUT;
RX_DIR = INPUT;
BAUDH = 0;
BAUDL = 0x4D;
//Baud rate = 9600
RX_EN = _ON;
TX_EN = _ON;
HI_BAUD = 0;
//Low baud rate
RXINT_EN = _ON;
//Enables interrupt
RX_PR = _ON;
//High priority interrupt
}

*/
*/
*/
*/
*/
*/

/* ************************************************ */
/* Method name:
rs232lib_isRxReady
*/
/* Method description: Checks if received data is
*/

53

*/
*/
*/
*/
*/
*/
*/
*/

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

/*
ready
/* Input params:
n/a
/* Outpu params:
returns 1 if ok, 0 otherwise
/* ************************************************
int rs232lib_isRxReady(void) {
if(OVER_ERR){
//If error occured, reset RX_EN
RX_EN = _OFF;
RX_EN = _ON;
}
if(FRAM_ERR)
rs232lib_receiveByte();
return RX_READY;
}

*/
*/
*/
*/

/* ************************************************
/* Method name:
rs232lib_receiveByte
/* Method description: Get data from register
/* Input params:
n/a
/* Outpu params:
byte received
/* ************************************************
char rs232lib_receiveByte(void) {
return RX_DATA;
}

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
rs232lib_sendByte
/* Method description: Send data
/* Input params:
cByte = byte to be sent
/* Outpu params:
n/a
/* ************************************************
void rs232lib_sendByte(char cByte) {
while(!TX_READY);
TX_DATA = cByte;
}

*/
*/
*/
*/
*/
*/

/* ************************************************ */
/* Method name:
rs232lib_receiveBuffer
*/
/* Method description: Get buffer from register
*/
/* Input params:
cBuf = variable that
*/
/*
receives buffer
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void rs232lib_receiveBuffer(char* cBuf) {
int i,j=0;
while(rs232lib_isRxReady() && ++j < SIZE_OF_BUFFER) {
*(cBuf++) = RX_DATA;
if(!rs232lib_isRxReady())
for(i=0;i<TIMEOUT && !rs232lib_isRxReady();i++);
}
*cBuf='\0';
}
/* ************************************************
/* Method name:
rs232lib_sendBuffer
/* Method description: Send buffer
/* Input params:
cBuf = buffer to be sent
/* Outpu params:c
n/a
/* ************************************************
void rs232lib_sendBuffer(char* cBuf) {
while(*cBuf != '\0'){
while(!TX_READY);
TX_DATA = *cBuf;
cBuf++;
}
}

*/
*/
*/
*/
*/
*/

/*
/*
/*
/*

*/
*/
*/
*/

************************************************
Method name:
rs232lib_sendNewLine
Method description: Send new line
Input params:
n/a

54

105
106
107
108
109
110
111
112
113

/* Outpu params:c
n/a
*/
/* ************************************************ */
void rs232lib_sendNewLine(void) {
char cBuff[3];
cBuff[0] = '\r';
cBuff[1] = '\n';
cBuff[2] = '\0';
rs232lib_sendBuffer(cBuff);
}

A.26
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

/*
/*
/*
/*
/*
/*
/*
/*

*****************************************************************
File name:
tachlib.h
File description: Header file containing the functions/methods
prototypes of tachlib.c
Author name:
tukei & legidio
Creation date:
08mai2015
Revision date:
15mai2015
*****************************************************************

*/
*/
*/
*/
*/
*/
*/
*/

#ifndef TACHLIB_H
#define TACHLIB_H
/* ************************************************
/* Method name:
tachlib_init
/* Method description: Initialize the tachometer
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void tachlib_init(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
tachlib_read
/* Method description: Reads state of tachometer
/* Input params:
n/a
/* Outpu params:
state of the tachometer
/* ************************************************
int tachlib_read(void);

*/
*/
*/
*/
*/
*/

/* ************************************************ */
/* Method name:
tachlib_computeCoolerVelocity*/
/* Method description: compute the cooler speed in */
/*
RPS (revolutions per second) */
/*
*/
/*
Period = 1 s
*/
/*
*/
/* Input params:
n/a
*/
/* Outpu params:
cooler speed in RPS
*/
/* ************************************************ */
unsigned int tachlib_computeCoolerVelocity(void);
#endif /* TACHLIB_H */

A.27
1
2
3
4
5

tachlib.h

/*
/*
/*
/*
/*

tachlib.c

*****************************************************************
File name:
tachlib.c
File description: This file has some functions that handle the
tachometer
Author name:
tukei & legidio

55

*/
*/
*/
*/
*/

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

/* Creation date:
08mai2015
*/
/* Revision date:
15mai2015
*/
/* ***************************************************************** */
#include
#include
#include
#include

/* ************************************************
/* Method name:
tachlib_init
/* Method description: Initialize the tachometer
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void tachlib_init(void) {
TC_DIR = INPUT;
}

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
tachlib_read
/* Method description: Reads state of tachometer
/* Input params:
n/a
/* Outpu params:
state of the tachometer
/* ************************************************
int tachlib_read(void) {
return TC;
}

*/
*/
*/
*/
*/
*/

/* ************************************************ */
/* Method name:
tachlib_computeCoolerVelocity*/
/* Method description: compute the cooler speed in */
/*
RPS (revolutions per second) */
/*
*/
/*
Period = 1 s
*/
/*
*/
/* Input params:
n/a
*/
/* Outpu params:
cooler speed in RPS
*/
/* ************************************************ */
unsigned int tachlib_computeCoolerVelocity(void) {
unsigned int uiTimer1Value = timerlib_getTimer1Count();
timerlib_resetTimer1Counter();
return uiTimer1Value/COOLER_BLADES_NUM;
}

A.28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

"mclab2.h"
"tachlib.h"
"timerlib.h"
"cooler.h"

/*
/*
/*
/*
/*
/*
/*
/*

timerlib.h

*****************************************************************
File name:
timerlib.h
File description: Header file containing the functions/methods
prototypes of timerlib.c
Author name:
tukei & legidio
Creation date:
08mai2015
Revision date:
15mai2015
*****************************************************************

#ifndef TIMER_H
#define TIMER_H
/*
/*
/*
/*
/*
/*
/*

************************************************
Method name:
timerlib_initTimer1AsCounter
Method description: configure TIMER1
to be a 16b counter
Input params:
n/a
Outpu params:
n/a
************************************************

56

*/
*/
*/
*/
*/
*/
*/

*/
*/
*/
*/
*/
*/
*/
*/

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

void timerlib_initTimer1AsCounter(void);
/* ************************************************
/* Method name:
timerlib_resetTimer1Counter
/* Method description: reset the count of TIMER1
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void timerlib_resetTimer1Counter(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
timerlib_startTimer1Counter
/* Method description: init the counting
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void timerlib_startTimer1Counter(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
timerlib_stopTimer1Counter
/* Method description: stop the counting
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void timerlib_stopTimer1Counter(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
timerlib_getTimer1Count
/* Method description: return the counting value
/*
related to TIMER1 as counter
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
unsigned int timerlib_getTimer1Count(void);

*/
*/
*/
*/
*/
*/
*/

/* ************************************************ */
/* Method name:
timerlib_configCyclicExecutive*/
/* Method description: configures the Cyclic Executive*/
/*
timer interruption = 100ms
*/
/* Input params:
n/a
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void timerlib_configCyclicExecutive(void);
/* ************************************************ */
/* Method name:
timerlib_resetCyclicExecutive*/
/* Method description: reset the TIMER0 high and low*/
/*
values
*/
/* Input params:
n/a
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void timerlib_resetCyclicExecutive(void);
#endif /* TIMER_H */

A.29
1
2
3
4
5
6
7
8
9

/*
/*
/*
/*
/*
/*
/*
/*

timerlib.c

*****************************************************************
File name:
timerlib.c
File description: This file constains some functions that config
the timers
Author name:
tukei & legidio
Creation date:
08mai2015
Revision date:
15mai2015
*****************************************************************

57

*/
*/
*/
*/
*/
*/
*/
*/

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

#include "mclab2.h"
#include "timerlib.h"
/*
FOSC = 48 MHz
tick = 1 / (FOSC/4)
count = time [ms] / tick
timer = 65536 - (Count/prescale)
OR
timer = 65536 - ( (tempo/ (1 / (FOSC/4))) / ps)
*/
/* timer config for 100ms */
#define TIMERLIB_TIMER0_RESET_VALUE
#define TIMERLIB_TIMER0_RESET_VALUE_HIGH
8)
#define TIMERLIB_TIMER0_RESET_VALUE_LOW

60849
((TIMERLIB_TIMER0_RESET_VALUE & 0xff00) >>( TIMERLIB_TIMER0_RESET_VALUE & 0x00ff)

/* ************************************************ */
/* Method name:
timerlib_initTimer1AsCounter
*/
/* Method description: configure TIMER1
*/
/*
to be a 16b counter
*/
/* Input params:
n/a
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void timerlib_initTimer1AsCounter(void)
{
T1_16BIT = 1;
// 16-bit operation
T1_CLOCK = 0;
// Device clock from another source (COOLER from target)
T1_PS = 0;
// 1:1 prescaler
T1_OSC_EN = 0;
// oscilator is off
T1_SYNC = 1;
// do not synchronize
T1_CS = 1;
// external clock source (rising edge)
T1_EN = 0;
// disable timer1
timerlib_resetTimer1Counter();
}
/* ************************************************
/* Method name:
timerlib_resetTimer1Counter
/* Method description: reset the count of TIMER1
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void timerlib_resetTimer1Counter(void)
{
/* reset any previous counter */
TMR1H = 0;
TMR1L = 0;
}

*/

/* ************************************************
/* Method name:
timerlib_startTimer1Counter
/* Method description: init the counting
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void timerlib_startTimer1Counter(void)
{
T1_EN = 1;
// enable timer1
}

*/

/* ************************************************
/* Method name:
timerlib_stopTimer1Counter
/* Method description: stop the counting
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void timerlib_stopTimer1Counter(void)

*/

58

*/
*/
*/
*/
*/

*/
*/
*/
*/
*/

*/
*/
*/
*/
*/

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

{
T1_EN = 0;

/* ************************************************
/* Method name:
timerlib_getTimer1Count
/* Method description: return the counting value
/*
related to TIMER1 as counter
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
unsigned int timerlib_getTimer1Count(void)
{
unsigned int uiCount;

*/
*/
*/
*/
*/
*/
*/

/* return the MSB + LSB parts */


uiCount = (unsigned int) TMR1L;
uiCount += (((unsigned int)TMR1H) << 8);
return uiCount;
}
/* ************************************************ */
/* Method name:
timerlib_configCyclicExecutive*/
/* Method description: configures the Cyclic Executive*/
/*
timer interruption = 100ms
*/
/* Input params:
n/a
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void timerlib_configCyclicExecutive(void)
{
T0_OV_INT = _ON;
// enables TMR0 overflow interrup
T0_8BIT = 0;
T0_CLOCK = 0;
T0_PSA = 0;
T0_PS = 0b111;

//
//
//
//

16-bit timer
internal clock (FOSC/4)
prescaler assigned
1:256 prescale

timerlib_resetCyclicExecutive();
T0_EN = _ON;

// enables TMR0

}
/* ************************************************ */
/* Method name:
timerlib_resetCyclicExecutive*/
/* Method description: reset the TIMER0 high and low*/
/*
values
*/
/* Input params:
n/a
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void timerlib_resetCyclicExecutive(void)
{
TMR0H = TIMERLIB_TIMER0_RESET_VALUE_HIGH;
TMR0L = TIMERLIB_TIMER0_RESET_VALUE_LOW;
}

A.30
1
2
3
4
5
6
7
8

// disable timer1

/*
/*
/*
/*
/*
/*
/*
/*

util.h

*****************************************************************
File name:
util.h
File description: Header file containing the function/methods
prototypes of util.c
Those delays were tested under the following:
PLLDIV = 1, FOSC = XTPLL_XT, CPUDIV = OSC1_PLL2
For the development kit McLab2
Author name:
dloubach

59

*/
*/
*/
*/
*/
*/
*/
*/

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

/* Creation date:
09jan2015
*/
/* Revision date:
17abr2015
*/
/* ***************************************************************** */
#ifndef UTIL_H
#define UTIL_H
/* number of iterations to get 1 second
* based on cyclic executive period
*/
#define UTIL_1S_ITERATION_NUM
10
#define COMP_VEL_FREQ 10
#define COMP_TMP_FREQ 1
#define COMP_PID_FREQ 3
/* ************************************************
/* Method name:
util_genDelay1MS
/* Method description: generates 1ms delay
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void util_genDelay1MS(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
util_genDelay10MS
/* Method description: generates 10ms delay
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void util_genDelay10MS(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
util_genDelay100MS
/* Method description: generates 100ms delay
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void util_genDelay100MS(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
util_genDelay500MS
/* Method description: generates 500ms delay
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void util_genDelay500MS(void);

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
util_isNumber
/* Method description: Checks if data is a number
/* Input params:
cValue = data to be checked
/* Outpu params:
1 if is number, 0 otherwise
/* ************************************************
int util_isNumber(char);

*/
*/
*/
*/
*/
*/

/* ************************************************ */
/* Method name:
util_convertFromUi2Ascii
*/
/* Method description: Convert from unsigned int to */
/*
ASCII
*/
/* Input params:
uiVal => number to be converted*/
/* Outpu params:
*cStr => number converted
*/
/* ************************************************ */
void util_convertFromUi2Ascii(unsigned int uiVal, char *cStr);
/*
/*
/*
/*
/*

************************************************
Method name:
util_computeCycExecN
Method description: Computes number of cycles
and resets when convenient
Input params:
n/a

60

*/
*/
*/
*/
*/

79
80
81
82
83

/* Outpu params:
n/a
*/
/* ************************************************ */
void util_computeCycExecN(void);
#endif /* UTIL_H */

A.31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

/*
/*
/*
/*
/*
/*
/*
/*

util.c

*****************************************************************
File name:
util.c
File description: This file has a couple of useful functions to
make programming more productive
Author name:
dloubach
Creation date:
09jan2015
Revision date:
17abr2015
*****************************************************************

#include "util.h"
#include "mclab2.h"
extern unsigned int uiCycExecN;
/* ************************************************
/* Method name:
util_genDelay1MS
/* Method description: generates 1ms delay
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void util_genDelay1MS(void)
{
char i;
for(i=0; i<69; i++)
{
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
}
}

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
util_genDelay10MS
/* Method description: generates 10ms delay
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void util_genDelay10MS(void)
{
char i;
for(i=0; i<9; i++)
util_genDelay1MS();
for(i=0; i<59; i++)
{
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();

*/
*/
*/
*/
*/
*/

61

*/
*/
*/
*/
*/
*/
*/
*/

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

}
}
/* ************************************************
/* Method name:
util_genDelay100MS
/* Method description: generates 100ms delay
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void util_genDelay100MS(void)
{
char i;
for(i=0; i<9; i++)
util_genDelay10MS();
for(i=0; i<9; i++)
util_genDelay1MS();
for(i=0; i<49; i++)
{
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
}
}

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
util_genDelay500MS
/* Method description: generates 500ms delay
/* Input params:
n/a
/* Outpu params:
n/a
/* ************************************************
void util_genDelay500MS(void)
{
char i;
for(i=0; i<4; i++)
util_genDelay100MS();
for(i=0; i<9; i++)
util_genDelay10MS();
for(i=0; i<9; i++)
util_genDelay1MS();
for(i=0; i<44; i++)
{
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
}
}

*/
*/
*/
*/
*/
*/

/* ************************************************
/* Method name:
util_isNumber
/* Method description: Checks if data is a number
/* Input params:
cValue = data to be checked
/* Outpu params:
1 if is number, 0 otherwise
/* ************************************************
int util_isNumber(char cValue)
{

*/
*/
*/
*/
*/
*/

62

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169

return (cValue>=48) && (cValue<=57);


}
/* ************************************************ */
/* Method name:
util_convertFromUi2Ascii
*/
/* Method description: Convert from unsigned int to */
/*
ASCII
*/
/* Input params:
uiVal => number to be converted*/
/* Outpu params:
*cStr => number converted
*/
/* ************************************************ */
void util_convertFromUi2Ascii(unsigned int uiVal, char *cStr)
{
if (uiVal >= 10000)
*cStr++ = (uiVal/10000 % 10) + '0';
if (uiVal >= 1000)
*cStr++ = (uiVal/1000 % 10) + '0';
if (uiVal >= 100)
*cStr++ = (uiVal/100 % 10) + '0';
if (uiVal >= 10)
*cStr++ = (uiVal/10 % 10) + '0';
*cStr++ = (uiVal % 10) + '0';
*cStr = '\0';
}
/* ************************************************ */
/* Method name:
util_computeCycExecN
*/
/* Method description: Computes number of cycles
*/
/*
and resets when convenient
*/
/* Input params:
n/a
*/
/* Outpu params:
n/a
*/
/* ************************************************ */
void util_computeCycExecN(void)
{
uiCycExecN++;
if(uiCycExecN == COMP_VEL_FREQ*COMP_TMP_FREQ*COMP_PID_FREQ)
uiCycExecN=0;
}

63