manual excitador-vaca

29
Excitador La vaca Manual de usuario Índice 1. Sin computadora 2 1.1. Cómo seleccionar la frecuencia ............................... 2 2. Con computadora 2 2.1. Cómo conectar a una computadora y probar la comunicación ............. 2 2.2. Cómo seleccionar la frecuencia ............................... 3 2.3. Cómo controlar la potencia ................................ 3 2.4. Referencia de comandos .................................. 4 3. Diagramas 4 3.1. Esquemático ......................................... 4 3.2. PCB ............................................. 6 3.2.1. Tarjeta madre .................................... 7 3.2.2. Tarjeta de comunicación serial .......................... 8 3.2.3. Tarjeta del amplificador operacional ....................... 8 3.2.4. Tarjeta de contadores ............................... 8 4. Código Fuente 9 4.1. modos.c ........................................... 9 4.2. modos.h ........................................... 12 4.3. serial.h ............................................ 13 4.4. serial.rl ........................................... 14 4.5. vaca.c ............................................ 22 4.6. vaca.h ............................................ 25 4.7. Makefile ........................................... 27 1

Upload: radio-bronka-1045-fm

Post on 21-Feb-2017

438 views

Category:

Education


0 download

TRANSCRIPT

Page 1: Manual excitador-vaca

Excitador

La vaca

Manual de usuario

Índice

1. Sin computadora 2

1.1. Cómo seleccionar la frecuencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2. Con computadora 2

2.1. Cómo conectar a una computadora y probar la comunicación . . . . . . . . . . . . . 22.2. Cómo seleccionar la frecuencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.3. Cómo controlar la potencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.4. Referencia de comandos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

3. Diagramas 4

3.1. Esquemático . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43.2. PCB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3.2.1. Tarjeta madre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.2.2. Tarjeta de comunicación serial . . . . . . . . . . . . . . . . . . . . . . . . . . 83.2.3. Tarjeta del amplificador operacional . . . . . . . . . . . . . . . . . . . . . . . 83.2.4. Tarjeta de contadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

4. Código Fuente 9

4.1. modos.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94.2. modos.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124.3. serial.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134.4. serial.rl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144.5. vaca.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224.6. vaca.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254.7. Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

1

Page 2: Manual excitador-vaca

2011, La kehuelga radio.

El excitador puede ser configurado de dos maneras; con 8 interruptores que están soldados a latarjeta y mediante un puerto de comunicación serial RS232.

Con los interruptores solo es posible seleccionar la frecuencia de operación, mientras que conel puerto serial el excitador puede comunicar información referente a su funcionamiento, como elestado de algunos contadores, además de poder seleccionar la frecuencia y la potencia de salida.

1. Sin computadora

Si no tienes disponible una computadora con puerto serial o simplemente no quieres usarlapara configurar los parámetros del excitador, debes prender el interruptor número 8 del dipswitch;entonces, el aparato leerá la frecuencia de los 7 interruptores restantes del mismo dipswitch y no desu memoria.

1.1. Cómo seleccionar la frecuencia

Podemos considerar que los 7 interruptores definen un número binario, el cual corresponde se-cuencialmente a las frecuencias de operación que van de 87.9 MHz hasta 107.9 MHz. Es decir alnúmero binario 0000000 corresponde la frecuencia 87.9 MHz, al número 0000001 la frecuencia 88.0MHz y así sucesivamente hasta llegar a 107.9 MHz, o sea 1100100.

En lugar de contar desde 0 hasta el número que corresponde a la frecuencia que queremosconfigurar, podemos usar la siguiente relación:

n =f × 10− 879

2(1)

Donde, f es la frecuencia en MHz, y n es el número que hay que configurar en el dipswitch; nestá en base decimal, hace falta convertirlo a base binaria.

Digamos por ejemplo, que queremos operar en la frecuencia de los 93.5 MHz.Si aplicamos la relación (1), tenemos:

n =93,5× 10− 879

2

= 28

28 en base binaria es 0011100.

2. Con computadora

2.1. Cómo conectar a una computadora y probar la comunicación

El excitador cuenta con un puerto de comunicación serial que sigue el estándar RS232; puedesconectarlo a un puerto serial de una computadora, necesitarás un programa emulador de terminal quese pueda conectar a un puerto serie, en GNU/Linux puedes usar gtkterm; además debes configurarlocon los siguientes parámetros:

2

Page 3: Manual excitador-vaca

2011, La kehuelga radio.

Velocidad 9600Bits de datos 8Bits de paro 1Paridad Ninguna

Prueba la comunicación, por ejemplo, pregúntale al excitador en qué frecuencia está trabajando;debes escribir en la terminal el comando:

f?

Para que el comando sea enviado al excitador, debes oprimir la tecla enter después de escribir elcomando. Si la comunicación funciona correctamente, el excitador responderá con la frecuencia deoperación, así:

F1021

Eso significa que la frecuencia de operación del excitador es 102.1 MHz.

2.2. Cómo seleccionar la frecuencia

El comando para seleccionar la frecuencia tiene la forma

Fiiii

La f puede ser minúscula o mayúscula, iiii debe sustituirse por la frecuencia de operación enmegahertz multiplicada por 10.

El excitador responde con el mensaje:

Fiiii

Por ejemplo, si queremos operar el excitador a 105.3 MHz el comando sería:

F1053

2.3. Cómo controlar la potencia

Es posible controlar la potencia del excitador; el comando tiene la forma:

Ahh

hh es un número expresado en base hexadecimal, que va desde 00 hasta FF; 00 es la potenciamínima y FF la máxima.

El excitador debe responder con:

Ahh

3

Page 4: Manual excitador-vaca

2011, La kehuelga radio.

2.4. Referencia de comandos

Hay bastantes comandos para cambiar y conocer el estado del excitador, están resumidos en elsiguiente cuadro, en el que i se refiere a un dígito decimal y h a un dígito hexadecimal.

Comando Descripción Respuesta Error

Ahh Cambia la potencia Ahh

A? Reporta la potencia Ahh

GA Guarda la potencia en la EEPROM GAhh

RA Restaura la potencia desde la EE-PROM

RAhh

IAM La potencia de inicio se lee de la EE-PROM

IAM

IA0 Hace que la potencia de inicio sea 0 IA0IA? Reporta la fuente de la potencia de

inicioIAM, IA0

Fiiii Cambia la frecuencia Fiiii ERROR: Frec. INVALIDA!F? Reporta la frecuencia Fiiii

GF Guarda la frecuencia seleccionada enla EEPROM

GFiiii

IFS La frecuencia de inicio se lee deldipswitch

IFS

RF Restaura la frecuencia desde la EE-PROM

RFiiii ERROR: Frec. INVALIDA!

IFM La frecuencia de inicio se lee de laEEPROM

IFM

IF? Reporta la fuente de la frecuencia deinicio

IFM, IFS

S? Reporta el dipswitch Shh

P[0-3][01] Cambia el valor de un pin de control P[0-3][01]P[0-3] Reporta el valor del pin de un con-

trolP[0-3][01]

V[0-7] Reporta un canal del ADC (conver-tidor analógico digital)

V[0-7]hhh

3. Diagramas

3.1. Esquemático

4

Page 5: Manual excitador-vaca

3 2

1

3 2

1

1 2

3 2

1

12

D9

Q

13

CL

R8

Q

10

PR

E

11

CL

K

2D

5Q

1C

LR

6Q

4P

RE

3C

LK

+5

V

AT

mega32 D

IP40

1P

B0 (

XC

K/T

0)

2P

B1 (

T1)

3P

B2 (

INT

2/A

IN0)

4P

B3 (

OC

0/A

IN1)

5P

B4 (

SS

_L)

6P

B5 (

MO

SI)

7P

B6 (

MIS

O)

8P

B7 (

SC

K)

22

PC

0 (

SC

L)

23

PC

1 (

SD

A)

24

PC

2 (

TC

K)

25

PC

3 (

TM

S)

26

PC

4 (

TD

O)

27

PC

5 (

TD

I)

28

PC

6 (

TO

SC

1)

29

PC

7 (

TO

SC

2)

14

PD

0 (

RX

D)

15

PD

1 (

TX

D)

16

PD

2 (

INT

0)

17

PD

3 (

INT

1)

18

PD

4 (

OC

1B

)

19

PD

5 (

OC

1A

)

20

PD

6 (

ICP

)

21

PD

7 (

OC

2)

9R

ES

ET

_L

10 VCC

13

XT

AL1

12

XT

AL2

PA

7 (

AD

C7)

33

PA

6 (

AD

C6)

34

PA

5 (

AD

C5)

35

PA

4 (

AD

C4)

36

PA

3 (

AD

C3)

37

PA

2 (

AD

C2)

38

PA

1 (

AD

C1)

39

PA

0 (

AD

C0)

40

31GND

11GND

32

AR

EF

30

AV

CC

+5

V

+5

V

+5

V

32

1

8 4

+5

V

1 2

3 2

1

3 2

1

12345678

16

15

14

13

12

11

10

9

SW

DIP

−8

56

7

8 4

2V

+

3C

1−

4C

2+

5C

2−

6V

7T

x2

Ou

t

8R

x2

In

9R

x2

Ou

t

10

Tx2

In

11

Tx1

In

12

Rx1

Ou

t1

3R

x1

In

14

Tx1

Ou

t

1C

1+

MA

X232

12

12

12

+5

V

12

+1

2V

+1

2V

10

CL

K

11

Re

se

t

9Q

1

7Q

2

5Q

4

4Q

7

6Q

3

13

Q8

12

Q9

14

Q1

0

15

Q1

1

1Q

12

2Q

6

3Q

5

1 2

2 1

1 2

+5

V

INO

UT

GN

D

1

2

3

1 2

1 2

INO

UT

GN

D

1

2

3

1 2

1 2

INO

UT

GN

D

1

2

3

1 2

1 2

1 2

Q3

MP

SH

10

R8

12k

R14

4k7

R22

220

C19

33pF

C16

4p7

C22

.1uF

D1

MV

209

Q1

MP

SH

10

R5

4K

7

R11

4k7R

6220

C11

1000pF

C17

47pF

L2

6v. #18 1

/4in

d.i.

C21

220pF

C6

1000pF

R2

47

C5

1000pF

C3

.01uF

C2

4u7

+12V

Q2

MP

SH

10

R19

22

C18

1000pF

R9

4K

7

R16

470

C14

100pF

L1

8v. #18 1

/4in

d.i.

U5

74A

C74

U5

74A

C74

R25

220

R24

4K

7

U7

X1

16M

Hz

C46

15pFC

36

.01uF

R34

22k

U4

Vcc

C26 .1uF

R23

3k3

R26

4k7

R20

4k7

C25

.1uF

R29

22k

R28

39k

R30

4k7

C24

150pF

R31

3k3

R18

33k

C27

1uF

MP

SH

10

Q4

C20

100pF

R17

4K

7

R21

470

2sc1970

Q6

L3

6v. #16 1

/4in

d.i.

C23

1000pF

R27

18

C31

.1uF

C33

1000pF

Salid

a R

F

U9

U4

R37

100k

C35

.1uF

R35

1k

U8

RS

232 R

xD

(D

B9 H

em

bra

pin

2)

RS

232 T

xD

(D

B9 H

em

bra

pin

3)

C50

1uF

C47

1uF

C51

1uF

C48

1uF

C44

5−

30pf

U6

74H

C4040

RS

232 G

ND

(D

B9 H

em

bra

pin

5)

LE

D1

Fre

c. F

ija

R44

2k2

C49

4u7

R33

220

C32

.01uF

RS

232 D

TR

(D

B9 H

em

bra

pin

4)

RS

232 R

TS

(D

B9 H

em

bra

pin

7)

RS

232 C

TS

(D

B9 H

em

bra

pin

8)

Z1

1n4733 5

.1V

R48

4k7

R49

4k7

R50

4k7

R47

4k7

J1

jum

per,

para

pro

gra

mar

C28

330pF

T1

L4

70nH

C37

12pF

C38

27pF

C43

56pF

L5 1

14nH

C45

33pF

C40

0.2

2uF

C39

.022uF

R40

6k8

R38

68k

R42

680

C41

2.2

uF

D2 1n4148

C42

.01uFR41

1k

R39

20k

P1 D

B15H

D−

1

P2 D

B15H

D−

2

P3 D

B15H

D−

3

P4 D

B15H

D−

4

AN

7 D

B15H

D−

15

AN

6 D

B15H

D−

14

AN

5 D

B15H

D−

13

AN

4 D

B15H

D−

12

AN

3 D

B15H

D−

11

AN

2 D

B15H

D−

8

AN

1 D

B15H

D−

7

AN

0 D

B15H

D−

6

+5V

DB

15H

D−

9

AG

ND

DB

15H

D−

10

DG

ND

DB

15H

D−

5

R46

4k7

R45

33k

C52

100p

R43

4k7

R32

4k7

R36

12k

C29

4u7 tant.

C30

.01uF

Q5

MT

P2955

Apagar

RF

Apagar

RF

C34

470pF

+5V

Conta

dore

s78L05

U3

C9

4u7

C12

4u7

R4

100

VS

S

Vee

+5V

RS

232

78L05

U2

C7

4u7

C10

4u7

R3

100

VS

S

Vee

+5V

AtM

ega

78L05

U1

C4

4u7

C8

4u7

R1

100

VS

S

Vee

Audio

R

R7

12k

C13

.0068uF

R12

12k

C15

.0068uF

Audio

L

R15

1k

R10

470

R13

470

C1

47uF

C42

.001uF

3v. #16,

1/4

in. d.i.

4v. #16,

1/4

in. d.i.

par

trensado d

e c

at5

,

2v, 3/8

in. d.i.

2011, La kehuelga radio.

Page 6: Manual excitador-vaca

2011, La kehuelga radio.

3.2. PCB

6

Page 7: Manual excitador-vaca

2011, La kehuelga radio.

3.2.1. Tarjeta madre

7

Page 8: Manual excitador-vaca

2011, La kehuelga radio.

3.2.2. Tarjeta de comunicación serial

3.2.3. Tarjeta del amplificador operacional

3.2.4. Tarjeta de contadores

8

Page 9: Manual excitador-vaca

2011, La kehuelga radio.

4. Código Fuente

4.1. modos.c

/*

Copyright 2010, la kehuelga radio.

This program is free software: you can redistribute it and/or modify qit under

the terms of the GNU General Public License as published by the Free Software

Foundation, either version 3 of the License, or (at your option) any later

version.

This program is distributed in the hope that it will be useful, but WITHOUT

ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS

FOR A PARTICULAR PURPOSE. See the GNU General Public License for more

details.

You should have received a copy of the GNU General Public License along with

this program. If not, see <http://www.gnu.org/licenses/>.

*/

#include <stdlib.h>

#include <stdint.h>

#include <stdio.h>

#include <math.h>

#include <string.h>

#include <avr/io.h>

#include <avr/eeprom.h>

#include <avr/interrupt.h>

#include <util/delay.h>

#include "vaca.h"

#include "serial.h"

/* las funciones que corren en main y en la interrupción, respectivamente */

void (*funmain)(), (*funinter)();

/* semáforo de la interrupción pwm, definido en vaca.c */

uint8_t pwmsema;

uint8_t estado = 0, amp;

uint16_t dif, contvco, ucontvco, veces;

int16_t frec;

uint32_t ds, lvco=7, vco = 0x80707007;

int32_t error;

static uint32_t acc = 7;

9

Page 10: Manual excitador-vaca

2011, La kehuelga radio.

uint16_t nvfrec __attribute__((section (".eeprom"))) = (NV_FREC);

uint8_t nvamp __attribute__((section (".eeprom"))) = (NV_AMP);

uint8_t nvfi __attribute__((section (".eeprom"))) = (NV_IF);

uint8_t nvai __attribute__((section (".eeprom"))) = (NV_IA);

void pll_main()

{

static uint8_t upwmsema=0;

if ( estado == 1 ) {

PORTB |= _BV(PB0);

} else {

PORTB &= ~_BV(PB0);

}

if (pwmsema ^ upwmsema) {

if(veces < 65500) veces += (uint8_t)(pwmsema - upwmsema);

upwmsema = pwmsema;

if(veces > 62000) {

estado = 1;

}

if(veces > 50000) {

OCR0 = amp;

}

}

}

void pll_inter()

{

OCR2 = (uint8_t)(acc >> 24);

if(TIFR & _BV(ICF1)) {

TIFR |= _BV(ICF1);

contvco = ICR1;

dif = contvco - ucontvco;

ucontvco = contvco;

error = ((int32_t)dif * (int32_t)(BITS_FREC) * (int32_t)((ESCALA) / (DIV_HW))) - ds;

lvco &= (0xffffffff >> (KS));

lvco += error;

vco += (((int32_t)lvco) >> (KS));

if( estado == 0) {

vco += (error >> (KRAPIDO));

}

}

10

Page 11: Manual excitador-vaca

2011, La kehuelga radio.

acc &= 0x00ffffff;

acc += vco;

}

void modo_pll()

{

estado = 0;

veces = 0;

/* si el pin #7 del dipswitch. no está en modo manual, y la fuente de la

amplitud de inicio es cero, entonces la amplitud de inicio es 0. En todos

los demás casos, la amplitud de inicio es la que está guardada en la

EEPROM. */

if((PINC & 0x80) && (eeprom_read_byte(&nvai) == ’0’)) {

amp = 0;

} else {

amp = eeprom_read_byte(&nvamp);

}

if((PINC & 0x80) && (eeprom_read_byte(&nvfi))) {

frec = eeprom_read_word(&nvfrec);

} else {

frec = 879 + 2 * (uint16_t)(PINC & 0x7f);

}

ds = calcds(frec);

funmain = pll_main;

funinter = pll_inter;

}

void debug_main() {}

void debug_inter()

{

OCR2 = (uint8_t)(acc >> 24);

if(TIFR & _BV(ICF1)) {

TIFR |= _BV(ICF1);

contvco = ICR1;

dif = contvco - ucontvco;

ucontvco = contvco;

error = ((int32_t)dif * (int32_t)(BITS_FREC) * (int32_t)((ESCALA) / (DIV_HW))) - ds;

}

acc &= 0x00ffffff;

acc += vco;

11

Page 12: Manual excitador-vaca

2011, La kehuelga radio.

}

void modo_debug()

{

amp = 0x00;

acc = 0x80000007;

funmain = debug_main;

funinter = debug_inter;

}

int32_t calcds(int16_t frec)

{

ldiv_t debe_ser;

int32_t dsint;

debe_ser = ldiv(((long)(FREC_CPU)*(long)(ESCALA)),(long)frec);

dsint = debe_ser.quot * (BITS_FREC);

debe_ser = ldiv((debe_ser.rem * (BITS_FREC)),(long)frec);

dsint += debe_ser.quot;

return dsint;

}

4.2. modos.h

/*

Copyright 2010, la kehuelga radio.

This program is free software: you can redistribute it and/or modify qit under

the terms of the GNU General Public License as published by the Free Software

Foundation, either version 3 of the License, or (at your option) any later

version.

This program is distributed in the hope that it will be useful, but WITHOUT

ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS

FOR A PARTICULAR PURPOSE. See the GNU General Public License for more

details.

You should have received a copy of the GNU General Public License along with

this program. If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef MODOS_H

#define MODOS_H

/* para definir un modo, hay que escribir 3 elementos:

1. las funciones que corren en main y en la interrupción del pwm. Estas 2

12

Page 13: Manual excitador-vaca

2011, La kehuelga radio.

funciones tienen la forma

void nombre_main(void)

void nombre_inter(void)

2. una función para inicializar el modo, con la forma

void modo_nombre(void)

3. Un comando del puerto serial definido en serial.rl para entrar en el

modo. Y quizás más comandos para usarlo.

Para ver ejemplos, mira los que están en serial.rl y modos.c

*/

extern void modo_debug();

extern void modo_pll();

extern void (*funinter)(), (*funmain)();

extern uint8_t pwmsema, estado, vestado, amp;

extern int16_t frec;

extern uint16_t veces, dif;

extern int32_t ds;

extern int32_t error;

extern uint32_t vco;

extern uint16_t nvfrec __attribute__((section (".eeprom")));

extern uint8_t nvamp __attribute__((section (".eeprom")));

extern uint8_t nvai __attribute__((section (".eeprom")));

extern uint8_t nvfi __attribute__((section (".eeprom")));

#endif

4.3. serial.h

/*

Copyright 2010, la kehuelga radio.

This program is free software: you can redistribute it and/or modify qit under

the terms of the GNU General Public License as published by the Free Software

Foundation, either version 3 of the License, or (at your option) any later

version.

This program is distributed in the hope that it will be useful, but WITHOUT

ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS

FOR A PARTICULAR PURPOSE. See the GNU General Public License for more

details.

13

Page 14: Manual excitador-vaca

2011, La kehuelga radio.

You should have received a copy of the GNU General Public License along with

this program. If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef SERIAL_H

#define SERIAL_H

extern uint8_t *btx, *brx, bufrx[], buftx[];

void init_UART();

void init_scaner();

void bufrx_inicio();

void envia_UART();

void leer_cmds();

#endif

4.4. serial.rl

/*

Copyright 2010, la kehuelga radio.

This program is free software: you can redistribute it and/or modify qit under

the terms of the GNU General Public License as published by the Free Software

Foundation, either version 3 of the License, or (at your option) any later

version.

This program is distributed in the hope that it will be useful, but WITHOUT

ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS

FOR A PARTICULAR PURPOSE. See the GNU General Public License for more

details.

You should have received a copy of the GNU General Public License along with

this program. If not, see <http://www.gnu.org/licenses/>.

*/

/* -*-c-*- */

#include <stdlib.h>

#include <stdint.h>

#include <stdio.h>

#include <math.h>

#include <string.h>

#include <avr/io.h>

#include <avr/eeprom.h>

#include <avr/interrupt.h>

#include <util/delay.h>

#include "vaca.h"

14

Page 15: Manual excitador-vaca

2011, La kehuelga radio.

#include "modos.h"

/* para transmitir datos solo es necesaria la función printf */

char *btx, *brx, bufrx[(CARS_BUFRX)];

char buftx[(CARS_BUFTX)] = "La Vaca: Muuuu!\r";

int8_t cs, act, hay=0;

char *ts, *te=0, *p=bufrx, *pe=bufrx, *eof=0;

uint8_t resadch, resadcl, bitc;

uint16_t argnum;

uint32_t argnum32;

%%{

machine cmds;

action err_cmd {

strcat(buftx, "KE?\r");

}

main := |*

# Cambiar la Amplitud:

( [Aa] (xdigit{2} @{sscanf((ts+1),"%02x", &argnum);}) (’\r’)) =>

{

amp = (uint8_t)argnum;

OCR0 = amp;

sprintf((buftx+strlen(buftx)), "A%02X\r", amp);

};

# Reportar la Amplitud:

( [Aa] (’?’) (’\r’)) =>

{

sprintf((buftx+strlen(buftx)), "A%02X\r", amp);

};

# Guardar la Amp. en la EEPROM:

( [Gg] [Aa] (’\r’)) =>

{

eeprom_write_byte(&nvamp, amp);

sprintf((buftx+strlen(buftx)), "GA%02X\r", amp);

};

# Restaurar la Amp. de la EEPROM:

( [Rr] [Aa] (’\r’)) =>

{

amp = eeprom_read_byte(&nvamp);

15

Page 16: Manual excitador-vaca

2011, La kehuelga radio.

_delay_us(100);

OCR0 = amp;

sprintf((buftx+strlen(buftx)), "RA%02X\r", amp);

};

# Amplitud de Inicio = Memoria

# (si dipsw #7 = 1, cuando estado = 1, la amplitud se inicia con el valor de la nvram):

( [Ii] [Aa] [Mm] (’\r’) ) =>

{

eeprom_write_byte(&nvai, ’M’);

sprintf((buftx+strlen(buftx)), "IAM\r");

};

# Amplitud de Inicio = cero

# (si dipsw #7 = 1, cuando estado = 1, la amplitud no se prende sola):

( [Ii] [Aa] (’0’) (’\r’) ) =>

{

eeprom_write_byte(&nvai, 0x00);

sprintf((buftx+strlen(buftx)), "IA0\r");

};

# Reportar fuente de la amplitud de inicio:

( [Ii] [Aa] (’?’) (’\r’) ) =>

{

argnum = eeprom_read_byte(&nvai);

sprintf((buftx+strlen(buftx)), "IA%1c\r", (argnum)? ’M’ : ’0’);

};

# Cambiar la Frecuencia:

( [Ff] (digit{4}) @{sscanf((ts+1), "%04d", (int *)&argnum);} (’\r’)) =>

{

if((argnum >= 879) && (argnum <= 1079)) {

veces = 0;

estado = 0;

frec = argnum;

ds = calcds((uint16_t)frec);

sprintf((buftx+strlen(buftx)), "F%04d\r", frec);

} else {

sprintf((buftx+strlen(buftx)), "ERROR: Frec. MALA!\r");

}

};

# Reportar la Frecuencia:

( [Ff] (’?’) (’\r’)) =>

{

sprintf((buftx+strlen(buftx)), "F%04d\r", frec);

16

Page 17: Manual excitador-vaca

2011, La kehuelga radio.

};

# Guardar la frecuencia seleccionada en la EEPROM:

( [Gg] [Ff] (’\r’)) =>

{

eeprom_write_word(&nvfrec, frec);

sprintf((buftx+strlen(buftx)), "GF%04d\r", frec);

};

# Restaurar la frecuencia de la EEPROM:

( [Rr] [Ff] (’\r’)) =>

{

argnum = eeprom_read_word(&nvfrec);

if((argnum >= 879) && (argnum <= 1079)) {

veces = 0;

estado = 0;

frec = argnum;

ds = calcds((uint16_t)frec);

sprintf((buftx+strlen(buftx)), "RF%04d\r", frec);

} else {

sprintf((buftx+strlen(buftx)), "ERROR: Frec. MALA!\r");

}

};

# Frecuencia de inicio de los dipswitch:

( [Ii] [Ff] [Ss] (’\r’) ) =>

{

eeprom_write_byte(&nvfi, 0x00);

sprintf((buftx+strlen(buftx)), "IFS\r");

};

# Frecuencia de inicio de la nvram:

( [Ii] [Ff] [Mm] (’\r’) ) =>

{

eeprom_write_byte(&nvfi, 0x01);

sprintf((buftx+strlen(buftx)), "IFM\r");

};

# Reportar fuente de la frecuencia de inicio:

( [Ii] [Ff] (’?’) (’\r’) ) =>

{

argnum = eeprom_read_byte(&nvfi);

sprintf((buftx+strlen(buftx)), "IF%1c\r", (argnum) ? ’M’ : ’S’);

};

# Reportar los interruptores:

17

Page 18: Manual excitador-vaca

2011, La kehuelga radio.

( [Ss] (’?’) (’\r’)) =>

{

sprintf((buftx+strlen(buftx)), "S%02X\r", leer_dipsw());

};

# Cambiar un pin de control:

( [Pp] ([0-3] @{argnum = *(ts+1) - ’0’;}) ([01] @{bitc = *(ts+2);}) (’\r’) ) =>

{

if(bitc - ’0’) {

PINES_CONTROL |= _BV(PCIZQ + (uint8_t)argnum);

} else {

PINES_CONTROL &= ~(_BV(PCIZQ + (uint8_t)argnum));

}

sprintf((buftx+strlen(buftx)), "P%1X%1c\r", argnum, bitc);

};

# Reportar un pin de control:

( [Pp] ([0-3] @{argnum = *(ts+1) - ’0’;}) (’?’) (’\r’) ) =>

{

printf((buftx+strlen(buftx)), "P%1X%1c\r",

argnum, (PINES_CONTROL & _BV(PCIZQ + argnum)) ? ’1’ : ’0’);

};

# Reportar un canal del ADC:

( [Vv] ([0-7] @{sscanf((ts+1),"%1x", &argnum);}) (’?’) (’\r’) ) =>

{

ADMUX &= 0xf8;

ADMUX |= ((uint8_t) argnum);

/* un poco más tiempo para el muestreo */

_delay_us(100);

ADCSRA |= _BV(ADSC);

loop_until_bit_is_clear(ADCSRA, ADSC);

resadcl = ADCL;

resadch = ADCH;

sprintf((buftx+strlen(buftx)), "V%1X%01X%02X\r", argnum, resadch, resadcl);

};

# Cambiar el vco:

( [Pp] [Vv] (xdigit{8} @{sscanf((ts+2),"%08lx", &argnum32);}) ’\r’) =>

{ /* espera la próxima consulta del UART antes de cambiar el

apuntador del bufrx */

lcpwmsema = pwmsema;

while(pwmsema == lcpwmsema)

;

vco = argnum32;

sprintf((buftx+strlen(buftx)), "PV%08lX\r", argnum32);

18

Page 19: Manual excitador-vaca

2011, La kehuelga radio.

};

# Reportar el vco:

( [Pp] [Vv] ’?’ ’\r’) =>

{ /* espera la próxima consulta del UART antes de cambiar el

apuntador del bufrx */

lcpwmsema = pwmsema;

while(pwmsema == lcpwmsema)

;

argnum32 = vco;

sprintf((buftx+strlen(buftx)), "PV%08lX\r", argnum32);

};

# Reportar el error:

( [Pp] [Ee] ’?’ ’\r’) =>

{ /* espera la próxima consulta del UART antes de cambiar el

apuntador del bufrx */

lcpwmsema = pwmsema;

while(pwmsema == lcpwmsema)

;

argnum32 = error;

sprintf((buftx+strlen(buftx)), "PE%08lX\r", argnum32);

};

# Reportar el contador:

( [Pp] [Cc] ’?’ ’\r’) =>

{ /* espera la próxima consulta del UART antes de cambiar el

apuntador del bufrx */

lcpwmsema = pwmsema;

while(pwmsema == lcpwmsema)

;

argnum = dif;

sprintf((buftx+strlen(buftx)), "PC%04d\r", argnum);

};

# Reportar el estado del pll::

( [Ee] ’?’ ’\r’) =>

{

sprintf((buftx+strlen(buftx)), "E%1X\r", estado);

};

# Cambiar al modo debug:

( [Mm] [Dd] ’\r’ ) =>

{

cli();

modo_debug();

19

Page 20: Manual excitador-vaca

2011, La kehuelga radio.

sei();

strcat(buftx, "MD\r");

};

# Cambiar al modo pll:

( [Mm] [Pp] ’\r’ ) =>

{

cli();

modo_pll();

sei();

strcat(buftx, "MP\r");

};

*|;

}%%

%% write data;

void init_scaner()

{

ts = bufrx;

te=0;

p=bufrx;

pe=bufrx;

eof=0;

%% write init;

}

void init_UART()

{

UBRRH = (uint8_t)((BAUD) >> 8);

UBRRL = (uint8_t)(BAUD);

UCSRB = (1 << RXEN) | (1 << TXEN);

UCSRC = (1 << URSEL) | (3 << UCSZ0);

brx = bufrx;

btx = buftx;

}

void envia_UART()

{

/* UART TX: */

if(*btx) {

if(UCSRA & (1<<UDRE)) {

UDR = *btx++;

}

20

Page 21: Manual excitador-vaca

2011, La kehuelga radio.

} else {

btx = buftx;

*btx = 0;

}

}

void bufrx_inicio()

{

uint8_t bipwmsema;

/* espera una interrupción de captura */

bipwmsema = pwmsema;

while(pwmsema == bipwmsema)

;

brx = p = pe = bufrx;

}

void err_bufrx()

{

bufrx_inicio();

strcat(buftx, "ERROR: BUFRX LLENO!\r");

}

void leer_cmds()

{

uint8_t lcpwmsema;

int8_t espacio=((CARS_BUFRX)-hay);

/* ¿hay algo nuevo? */

if(pe == brx) return;

/* error, se ha llenado el bufrx: */

if(espacio == 0) {

err_bufrx();

return;

}

/* espera la próxima consulta del UART antes de cambiar el apuntador del

bufrx */

lcpwmsema = pwmsema;

while(pwmsema == lcpwmsema)

;

pe = brx;

%%write exec;

21

Page 22: Manual excitador-vaca

2011, La kehuelga radio.

if(cs == cmds_error) {

strcat(buftx, "KE?\r");

init_scaner();

bufrx_inicio();

}

if(ts == 0) {

hay = 0;

bufrx_inicio();

}

else {

/* espera la próxima consulta del UART antes de cambiar el apuntador del

bufrx */

lcpwmsema = pwmsema;

while(pwmsema == lcpwmsema)

;

hay = brx - ts;

if(brx-bufrx > 12) {

brx = bufrx + hay;

memmove(bufrx, ts, hay);

te = bufrx + (te-ts);

p = bufrx +(p - ts);

ts = bufrx;

}

}

}

4.5. vaca.c

/*

Copyright 2010, la kehuelga radio.

This program is free software: you can redistribute it and/or modify qit under

the terms of the GNU General Public License as published by the Free Software

Foundation, either version 3 of the License, or (at your option) any later

version.

This program is distributed in the hope that it will be useful, but WITHOUT

ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS

FOR A PARTICULAR PURPOSE. See the GNU General Public License for more

details.

You should have received a copy of the GNU General Public License along with

this program. If not, see <http://www.gnu.org/licenses/>.

*/

#include <stdlib.h>

22

Page 23: Manual excitador-vaca

2011, La kehuelga radio.

#include <stdint.h>

#include <stdio.h>

#include <math.h>

#include <string.h>

#include <avr/io.h>

#include <avr/eeprom.h>

#include <avr/interrupt.h>

#include <util/delay.h>

#include "vaca.h"

#include "serial.h"

#include "modos.h"

/*

FUSES =

{

.low = 0xff,

.high = (FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_SPIEN & FUSE_JTAGEN & FUSE_OCDEN)

};

*/

void init_pines()

{

DDRB |= _BV(PB0);

PORTB &= ~_BV(PB0);

PINES_CONTROL &= ~(0x0f << (PCIZQ));

PC_DDR |= (0x0f << (PCIZQ));

}

void init_dipsw()

{

/* activar pull-ups para el dipswitch: */;

SFIOR &= ~_BV(PUD);

DDRC = 0;

PORTC = 0xff;

PINC = 0xff;

}

void init_adc()

{

DDRA = 0;

PORTA = 0;

ADMUX = (ADCREF);

ADCSRA = (ADCPRE);

/* una conversión para tirar */

23

Page 24: Manual excitador-vaca

2011, La kehuelga radio.

ADCSRA |= _BV(ADSC);

}

void init_timers()

{

DDRB |= _BV (PB3);

DDRD |= _BV (PD7);

PORTB |= _BV (PB3);

PORTD |= _BV (PD7);

TCCR1A = 0x0;

TCCR1B = 0x01;

TCCR2 = 0x61;

TCCR0 = 0x69;

TIMSK = 0x40; /* cambia a 0x60 para habilitar capture de timer1 */

}

uint8_t leer_dipsw()

{

return (PINC);

}

ISR(BADISR_vect)

{

}

/* el timer2 genera el pwm para controlar la frecuencia */

ISR(TIMER2_OVF_vect)

{

(*funinter)();

/* UART rcp: */

if(UCSRA & (1<<RXC)) {

*brx++ = UDR;

}

pwmsema++;

}

int main()

{

/* inicialización de los periféricos */

init_pines();

24

Page 25: Manual excitador-vaca

2011, La kehuelga radio.

init_adc();

init_dipsw();

init_timers();

init_UART();

/* scaner de los comandos que llegan por el puerto serial */

init_scaner();

/* modo inicial: */

modo_pll();

sei();

while (1) {

leer_cmds();

envia_UART();

(*funmain)();

}

return 0;

}

4.6. vaca.h

/*

Copyright 2010, la kehuelga radio.

This program is free software: you can redistribute it and/or modify qit under

the terms of the GNU General Public License as published by the Free Software

Foundation, either version 3 of the License, or (at your option) any later

version.

This program is distributed in the hope that it will be useful, but WITHOUT

ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS

FOR A PARTICULAR PURPOSE. See the GNU General Public License for more

details.

You should have received a copy of the GNU General Public License along with

this program. If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef VACA_H

#define VACA_H

#define F_CPU 16000000UL

/* estado inicial programado en la lnvram: */

#define NV_FREC 1029

25

Page 26: Manual excitador-vaca

2011, La kehuelga radio.

#define NV_AMP 0xff

#define NV_IF 0x01

#define NV_IA ’M’

/* valores para el pll */

#define KV 1

#define KS 16

#define KRAPIDO 8

/* unos valores para el reloj de UART, UBRR, con fosc=16MHz, UB2x = 0 */

#define BAUD_2400 416

#define BAUD_4800 207

#define BAUD_9600 103

#define BAUD_19200 51

#define BAUD_38400 25

#define BAUD BAUD_9600

/* ref defs en ADMUX: */

#define ADCREF _BV(REFS0)

/* ADC preescaler etc en ADCSRA */

#define ADCPRE _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0)

/* pines para controlar otros equipos */

#define PINES_CONTROL PORTD

#define PC_DDR DDRD

#define PCIZQ 2

/* tamaños de los buffers */

#define CARS_BUFTX 32

#define CARS_BUFRX 32

/* valor máximo del error del VCO para considerar fija la frecuencia */

#define ERROR_MAX 5000000

/* cuantas veces el error del VCO tiene que ser menor que ERROR_MAX para

considerar fija la frecuencia */

#define ERROR_ESPERA 300

/* frecuencia del cpu en multiplos de 100kHz: */

#define FREC_CPU 160

/* divisor de vco en hardware: */

#define DIV_HW 4096

26

Page 27: Manual excitador-vaca

2011, La kehuelga radio.

/* Potencia mínima de 2 más grande que la frec. máxima en multiplos de

100kHz: */

#define BITS_FREC 0x400

/* factor escalador de frec. para aprovechar la precisión máxima de un

int32_t: */

#define ESCALA 0x800000

int32_t calcds(int16_t frec);

uint8_t leer_dipsw();

#endif

4.7. Makefile

###############################################################################

# La vaca: MUUUU! la vaca

###############################################################################

## General:

PROJECT = vaca

MCU = atmega32

TARGET = vaca.elf

CC = avr-gcc

###############################################################################

# Opciones para los varios programadores / debug:

###############################################################################

## HFUSE debe ser 0x10 para usar el JTAG, y 0xd8 para usar los dipswitch.

## OR con 0x01 para deshabilitar el bootloader;

## OR con 0x02 para tener espacio de bootloader de 1k en lugar de 2k;

## AND con 0xf7 para preservar el eeprom a pesar del "chip erase";

## LOCK totalmente deshabilitado es 0xff;

## OR con 0x7f para proteger el bootloader (deshabilitar la instrucción SPM

## en la sección del bootloader)

PORT=’/dev/ttyUSB0’

BAUD=9600

HEXFILE=vaca.hex

EEPROMFILE=vaca.eep

PROGRAMMER=avr109

DIRBOOT="avrprog_boot_v0_85"

# Deshabilita el modo seguro, el bootloader no podrá restaurar los fusibles

27

Page 28: Manual excitador-vaca

2011, La kehuelga radio.

# de ningun modo

DIS_SAVE=-u

## Opciones de Ragel:

RAGEL_OPCIONES = -C -G1

## Opciones comunes a las reglas para compilar, ligar y ensamblar

COMMON = -mmcu=$(MCU)

## Opciones de compilación

CFLAGS = $(COMMON)

CFLAGS += -Wall -pedantic -g -O3 -funsigned-char -funsigned-bitfields \

-fpack-struct -fshort-enums

CFLAGS += -Wp,-M,-MP,-MT,$(*F).o,-MF,dep/$(@F).d

## Banderas del ensamblador

ASMFLAGS = $(COMMON)

ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2

## Banderas del linker

LDFLAGS = $(COMMON)

LDFLAGS += -lm

## Banderas para producir un archivo Intel Hex

HEX_FLASH_FLAGS = -R .eeprom

HEX_EEPROM_FLAGS = -j .eeprom

HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"

HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0

INCLUDES = -I/usr/avr/include/

## Objetos necesarios para ligar

OBJECTS = vaca.o serial.o modos.o

##

all: $(TARGET) vaca.hex vaca.eep

boot:

$(MAKE) -C $(DIRBOOT)

programar: all

avrdude $(DIS_SAVE) -p $(MCU) -P $(PORT) -c $(PROGRAMMER) -b $(BAUD) \

-v -U flash:w:$(HEXFILE) -U eeprom:w:$(EEPROMFILE)

## Compilar

28

Page 29: Manual excitador-vaca

2011, La kehuelga radio.

vaca.o: vaca.c

$(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@

modos.o: modos.c

$(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@

serial.o: serial.c

$(CC) $(INCLUDES) $(CFLAGS) -O0 -c $< -o $@

# Ragel:

serial.c: serial.rl

ragel $(RAGEL_OPCIONES) $<

## Ligar

$(TARGET): $(OBJECTS)

$(CC) $(LDFLAGS) $(OBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)

%.hex: $(TARGET)

avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@

%.eep: $(TARGET)

avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@

%.lss: $(TARGET)

avr-objdump -h -S $< > $@

## Clean target

.PHONY: clean

clean:

-rm -rf $(OBJECTS) vaca.elf serial.c dep/ vaca.hex vaca.eep

## Otras dependencias

-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)

2011. Publicado por la kehuelga radio, bajo la licencia Creative Commons (Atribución – No comercial– Licenciamiento Recíproco 2.5).Disponible en http://creativecommons.org/licenses/by-nc-sa/2.5/mx

29