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
2011, La kehuelga radio.


    El excitador puede ser configurado de dos maneras; con 8 interruptores que están soldados a la
tarjeta y mediante un puerto de comunicación serial RS232.
    Con los interruptores solo es posible seleccionar la frecuencia de operación, mientras que con
el puerto serial el excitador puede comunicar información referente a su funcionamiento, como el
estado 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 usarla
para 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 de
su 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 al
número binario 0000000 corresponde la frecuencia 87.9 MHz, al número 0000001 la frecuencia 88.0
MHz 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 queremos
configurar, podemos usar la siguiente relación:

                                               f × 10 − 879
                                          n=                                                (1)
                                                    2
    Donde, f es la frecuencia en MHz, y n es el número que hay que configurar en el dipswitch; n
está 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:
                                            93,5 × 10 − 879
                                         n =
                                                   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; puedes
conectarlo a un puerto serial de una computadora, necesitarás un programa emulador de terminal que
se pueda conectar a un puerto serie, en GNU/Linux puedes usar gtkterm; además debes configurarlo
con los siguientes parámetros:




                                                 2
2011, La kehuelga radio.


                                          Velocidad          9600
                                          Bits de datos         8
                                          Bits de paro          1
                                          Paridad         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 el
comando. Si la comunicación funciona correctamente, el excitador responderá con la frecuencia de
operació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 en
megahertz 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 potencia
mínima y FF la máxima.
   El excitador debe responder con:

Ahh




                                                     3
2011, La kehuelga radio.


2.4.         Referencia de comandos
    Hay bastantes comandos para cambiar y conocer el estado del excitador, están resumidos en el
siguiente 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-        RAhh
                     PROM
     IAM             La potencia de inicio se lee de la EE-   IAM
                     PROM
     IA0             Hace que la potencia de inicio sea 0     IA0
     IA?             Reporta la fuente de la potencia de      IAM, IA0
                     inicio
     Fiiii           Cambia la frecuencia                     Fiiii        ERROR: Frec. INVALIDA!
     F?              Reporta la frecuencia                    Fiiii
     GF              Guarda la frecuencia seleccionada en     GFiiii
                     la EEPROM
     IFS             La frecuencia de inicio se lee del       IFS
                     dipswitch
     RF              Restaura la frecuencia desde la EE-      RFiiii       ERROR: Frec. INVALIDA!
                     PROM
     IFM             La frecuencia de inicio se lee de la     IFM
                     EEPROM
     IF?             Reporta la fuente de la frecuencia de    IFM, IFS
                     inicio
     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-      P[0-3][01]
                     trol
     V[0-7]          Reporta un canal del ADC (conver-        V[0-7]hhh
                     tidor analógico digital)

3.        Diagramas
3.1.         Esquemático




                                                       4
Vcc                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         C35             R37                   R38             R40               R42
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            .1uF            100k                  68k             6k8               680
                                                                                                                                                                                                                                                                                                                                                                                                                                                 C30                     R32
                                                                                                                                                                                                                                                                                                                                                                                                                                                 .01uF                   4k7
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               1
                                                                                             R2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       +12V
+12V                                                                                         47
                                                                                                                                                                                                                                                                                                                                                                                                                                                                               R35 1k
                                                                                                                                                                                                                                                                                                                                                                                                                        Q5                                                                        U4
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               2




                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       8      6                          C39                             C41
                                                                                                                                                                                                                                                                                                              T1                                                                                                                                                                                                                                        C40            2.2uF




                                   1
                                                            1
                                                                                                                                                                                                                                                                                                                                                                                                                      MTP2955                                                                     7                                   .022uF
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     0.22uF
                                                                                                                                                                                                                                                                                                             par trensado de cat5,                                                                                                                                                                            5
                                                                                                                                                                                                                                                                                                             2v, 3/8 in. d.i.                                                                                                                                                                          4
                        C1                       C2                   C3           C5                   C6                                                                                                                                                                                                                                                                                                                                                                R36




                                   2
                                                            2
                        47uF                     4u7                .01uF         1000pF               1000pF                                                                                                                                                                                                                                                                                                                                                             12k                                                                  R41               D2
                                                                                                                                                                                                                                                                    R17                                                                                                                                                                                                                                                                        1k                1n4148
                                                                                                                                                                                                                                                                    4K7
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        R39
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        20k
                                                                                                                                                                                                                                                                                           3
                                                                                                                                                                                                                                                                                                                                                                                                    C29            C31               C33
                                                                                                                                                                                                                                                                                  1              Q4
                                                                                                                                                                                                                                                                                                                                                                                                    4u7 tant.      .1uF              1000pF                                                                                               C42                 C42
                                                                                                                                                                                                                                                                                                 MPSH10
                 R1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       .01uF               .001uF
                                                                                                                                                                                                                    L1                                                                     2
                 100               78L05               U1
                                                                                                                                                                                                                                                            C20
                                                                               +5V AtMega                                                                                                                           8v. #18 1/4in d.i.
                               3       IN      OUT          1                                                                                                                                                                                               100pF              R21
                                                                                                                                                                                                                                                                               470                                                                                                                                                                   C37
                                            GND
                                                                                                                                                                                                                                                                                                                                                                                                                                                     12pF
                                             2




                         1
                                                                1
                                                                                                                                                                                                  R9
                 C4                                                                                                                                                                              4K7                                                                           C23
                                                                    C8                                                                                R5         R6
                 4u7                                                                                                                                 4K7        220                  C14                       3                                                               1000pF                                 R27
                                                                    4u7                                                                                                                                                                                                                                                                                                      L3




                         2
                                                                2
                                                                                      VSS                                                                                                                                                                                                                              18
                                                                                                                                                                                     100pF               1                                                                                                                                                            6v. #16 1/4in d.i.
                                                                                                                                                                                                                    Q2
                                                                                                                                                                                                                    MPSH10                                                                                                                                                                                      C34                                   L4
                                                                                                                                                C11                      3
                                                                                                                                                1000pF                                                         2                                                                                                                                                                                                                                     70nH                                    L5 114nH                                                                          Salida RF
                                                                                      Vee                                                                       1                                                                                                                                                                                                                                               470pF
                                                                                                                                                                                  Q1                                                                                                                                          Apagar RF
                                                                                                                                                                                  MPSH10
                                                                                                                                                                                                                                                   +5V                                                                                                        C28
                                                                                                                                                                         2
                 R3                                                                                                                                                                                                                                                                                                                                           330pF                        3                                                        3v. #16,                                  4v. #16,
                 100               78L05               U2                                                                                                                                                                                                                                                                                                                                                                                           1/4in. d.i.                               1/4in. d.i.
                                                                                                                                                                                                                                                                                                                                                                                      1        Q6
                                                                                +5V RS232
                               3       IN      OUT          1                                                                                                                                                                                            R24                                                                                                                                   2sc1970
                                                                                                                                                                                                 R16   C18                 R19                                                                                                                                                                                                            C38                                    C43                                           C45
                                            GND                                                                                                                                                                                                          4K7                                                                                                                               2
                                                                                                                                                           R11                                   470                        22
                                                                                                                                                                                                       1000pF                                                                                                                                                         R33                                                                 27pF                                   56pF                                          33pF
                                             2                                                                                                             4k7                                                                                                                                               74HC4040         U6




                         1
                                                                1
                                                                                                                                                                                                                                                                                                                                                                      220
                 C7                                                                                                                                                                                                                                                 74AC74            U5                                           9
                                                                    C10                                                                       R8                                                                                                                                                                              Q1
                 4u7
                                                                    4u7                                                                      12k                                                                                                                2                          5                                       7




                         2
                                                                2
                                                                                      VSS                                                                                                                                                                           D                 Q                                       Q2

                                                                                                                                                                                                                                                                                                                              Q4   5
                                                                                                                                                                                                                                                                1   CLR               Q    6
                                                                                                                                                                                                                                                                                                                              Q7   4
                                                                                      Vee                                                                                3
                                                                                                                                                                                                                                                                4   PRE
                                                                                                                                                                                                                                                                                                                              Q3   6
                                                                                                                                                                1                 Q3
                                                                                                                                                                                  MPSH10                                                 R25                    3   CLK                                                       Q8   13
                                                                                                                                                                                                                                                                                                        10    CLK
                                                                                                                                                                                                                                         220
                                                                                                                                                                         2                                                                                                                                                    Q9   12
                  R4                                                                                                                                       C17                                                                                                                                          11    Reset
                  100              78L05               U3                                                                                                                                                                                                                                                                          14
                                                                                                                                                           47pF                                                                                                                                                              Q10
                                                                            +5V Contadores                                 C16
                               3       IN      OUT          1                                                                                                                                                                            C24                                                                                 Q11   15
                                                                                                                           4p7
                                            GND                                                                                                                                                                                          150pF
                                                                                                                                                                                                                                                                                                                             Q12   1
                                                                                                                                                                                                                                                                    74AC74            U5
                                             2




                         1
                                                                1
                                                                                                                                                                                                                                                                                                                              Q6   2
                 C9                                                                                                                                                                                                                                            12   D                 Q    9
                                                                    C12                                                                                                                                                                                                                                                       Q5   3
                 4u7
                                                                    4u7                                                           R14                                                                                                                          13                          8




                         2
                                                                2
                                                                                      VSS                                                                                                                                                                           CLR               Q
                                                                                                                                 4k7                        C19                          R22
                                                                                                                                                                                                              +5V
                                                                                                                                                           33pF                          220                        R26                                        10   PRE
                                                                                                                                                                                                                    4k7
                                                                                      Vee                                                                                                                                                                      11   CLK

                                                                                                                            L2
                                                                                                                                                R18                     R20              R23
                                                                                                                        6v. #18 1/4in d.i.      33k                     4k7              3k3
                                                                                                                                                                                                                            R30
                                            C13                        R10                                                                                                                                                  4k7
       Audio L                              .0068uF                    470
                                                                                                                                                                    +12V

                                                                                                                                                           U4
                                                                                     R15                                 D1                                         8         2                                                                                     R34
                                                                                                                                                                                                                                                         +5V
                                                                                     1k                                                      C22            1                                                                                                       22k
                               R7                                                                                        MV209                .1uF                            3
                               12k                                                                                                                                  4
                                                                                                                                                                                           R28         R29                            R31
                                             C15                       R13
                                                                                                                                                                                           39k         22k                            3k3
                                             .0068uF                   470
                                                                                                                          C21
                                                                                                                                                                                                                                                                                                                                                                                                                          +5V




                                                                                                                                                                                                                    1
       Audio R                                                                                                            220pF                                                                                                                                                                +5V
                                                                                                                                                                                                             C27                   C32                                      C36
                                                                                                                                                                                                             1uF
                                                                                                                                                                                                                                                                                                                                                                                                                         2




                                                                                                                                                                                                                                 .01uF                                    .01uF                                                                         +5V
                               R12                                                                                                                                                 C25         C26




                                                                                                                                                                                                                    2
                               12k                                                                                                                                                .1uF          .1uF                                                                                                         U7
                                                                                                                                                                                                                                                                                                                                                                          +5V DB15HD−9                                                                                    C50
                                                                                                                                                                                                                                                                                                                                                                                                                                     U8         MAX232




                                                                                                                                                                                                                                                                                               10
                                                                                                                                                                                                                                                                                                                                                                                                                         1




                                                                                                                                                                                                                                                                                                             ATmega32 DIP40                                                                                                                                               1uF
                                                                                                                                                                                                                                                                                                                                                                                                                  C47
                                                                                                                                                                                                                                                                                                                                                                          AGND DB15HD−10                                        2    V+             C1+    1      1        2
                                                                                                                                                                                                                                                                                                                                                                                                                 1uF
                                                                                                                                                                                                                                                                          9    RESET_L




                                                                                                                                                                                                                                                                                               VCC
                                                                                                                                                                                                                                                                                                                                                                          DGND DB15HD−5                                                             C1−    3


                                                                                                                                                                                                                                                                          33   PA7 (ADC7)                             PD7 (OC2) 21                                                                                              6    V−             C2+    4
                                                                                                                                                                                                             AN7 DB15HD−15
                                                                                                                                                                                                                                                                                                                                              R43 4k7
                                                                                                                                                                                                                                                                                                                                                                                                                  2




                                                                                                                                                                                                                                                                          34   PA6 (ADC6)                              PD6 (ICP) 20                                                                                                                 C2−    5      2        1
                                                                                                                                                                                                             AN6 DB15HD−14
                                                                                                                                                                                                                                                                                                                                                                                                                                11                         14              C51
                                                                                                                                                                                                             AN5 DB15HD−13                                                35   PA5 (ADC5)                           PD5 (OC1A) 19                                         P1 DB15HD−1                                                Tx1 In      Tx1 Out
                                                                                                                                                                                                                                                                                                                                                                                                                  1




                                                                                                                                                                                                                                                                                                                                                                                                           C48                                                             1uF
                                                                                                                                                                                                                                                                          36   PA4 (ADC4)                           PD4 (OC1B) 18                                                                         1uF                   12   Rx1 Out      Rx1 In   13
                                                                                                                                                                                                             AN4 DB15HD−12                                                                                                                                                P2 DB15HD−2                                                                                                                          C52
                                                                                                                                                                                                                                                                                                                                                                                                                                10                         7                                                  100p
                                                                                                                                                                                                              AN3 DB15HD−11                                               37   PA3 (ADC3)                             PD3 (INT1) 17                                       P3 DB15HD−3                                                Tx2 In      Tx2 Out                                                                                 RS232 RxD (DB9 Hembra pin 2)
                                                                                                                                                                                                                                                                          38   PA2 (ADC2)                             PD2 (INT0) 16                                                                                             9    Rx2 Out      Rx2 In   8
                                                                                                                                                                                                              AN2 DB15HD−8                                                                                                                                                P4 DB15HD−4                                                                                                                                                    RS232 TxD (DB9 Hembra pin 3)
                                                                                                                                                                                                                                                                                                                                              R45 33k
                                                                                                                                                                                                              AN1 DB15HD−7                                                39   PA1 (ADC1)                              PD1 (TXD) 15                                                                                                                                                     2                                                RS232 DTR (DB9 Hembra pin 4)
                                                                                                                                                                                                                                                                                                                                                         R46 4k7
                                                                                                                                                                                                              AN0 DB15HD−6                                                40   PA0 (ADC0)                             PD0 (RXD) 14                                                                                                                                               J1                                                      RS232 GND (DB9 Hembra pin 5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                    jumper, para programar
                                                                                                                                                                                                                                                                                                                                                                                                                             SW DIP−8                                                       R47
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        1   4k7
                                                                                                                                                                                                                                                                          8    PB7 (SCK)                          PC7 (TOSC2) 29
                                                                                                                                                                                                                                                                                                                                                                                                                        8                 9
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         RS232 RTS (DB9 Hembra pin 7)
                                                                                                                                                                                                                                                                          7    PB6 (MISO)                         PC6 (TOSC1) 28                                                                                        7                 10

                                                                                                                                                                                                                                                                          6    PB5 (MOSI)                              PC5 (TDI) 27                                                                                     6                 11                                                                                             RS232 CTS (DB9 Hembra pin 8)
                                                                                                                                                                                                                                                                                                                                                                                                                        5                 12
                                                                                                                                                                                                                                                                          5    PB4 (SS_L)                             PC4 (TDO) 26                                                                                                                                                                          R48      R49      R50
                                                                                                                                                                                                                                                                                                                                                                                                                        4                 13
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             4k7      4k7      4k7
                                                                                                                                                                                                                                                                          4    PB3 (OC0/AIN1)                         PC3 (TMS) 25                                                                                      3                 14
                                                                                                                                                                                                                                                                                                                                                                                                                                                                             Z1
                                                                                                                                                                                                                                                                          3    PB2 (INT2/AIN0)                        PC2 (TCK) 24                                                                                      2                 15
                                                                                                                                                                                                                                                                                                                                                                                                                                                                      1n4733 5.1V
                                                                                                                                                                                                                                                                                                                                                                                                                        1                 16
                                                                                                                                                                                                                    Apagar RF                                             2    PB1 (T1)                               PC1 (SDA) 23                                                                                           U9
                                                                                                                                                                                                                                                                          1    PB0 (XCK/T0)                           PC0 (SCL) 22
                                                                                                                                                                                                                                                  R44 2k2                                                                                      +5V
                                                                                                                                                                                                                              LED1                                        13   XTAL1                                        AVCC 30
                                                                                                                                                                                                                         Frec. Fija
                                                                                                                                                                                                                                                                          12   XTAL2                                        AREF 32
                                                                                                                                                                                                                                                                                                 GND
                                                                                                                                                                                                                                                                                                       GND
                                                                                                                                                                                                                                                                                                                                                1




                                                                                                                                                                                                                                                         X1                                                                             C49
                                                                                                                                                                                                                                                                                                 11
                                                                                                                                                                                                                                                                                                       31




                                                                                                                                                                                                                                                         16MHz                                                                          4u7
                                                                                                                                                                                                                                                                                                                                                2




                                                                                             2011, La kehuelga radio.
                                                                                                                                                                                                                                         C44                             C46
                                                                                                                                                                                                                                         5−30pf                         15pF
2011, La kehuelga radio.


3.2.   PCB




                                    6
2011, La kehuelga radio.


3.2.1.   Tarjeta madre




                                       7
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
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
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
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
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
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
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
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%02Xr", amp);
        };

# Reportar la Amplitud:
    ( [Aa] (’?’) (’r’)) =>
        {
            sprintf((buftx+strlen(buftx)), "A%02Xr", amp);
        };

# Guardar la Amp. en la EEPROM:
    ( [Gg] [Aa] (’r’)) =>
        {
            eeprom_write_byte(&nvamp, amp);
            sprintf((buftx+strlen(buftx)), "GA%02Xr", amp);
        };

# Restaurar la Amp. de la EEPROM:
    ( [Rr] [Aa] (’r’)) =>
        {
            amp = eeprom_read_byte(&nvamp);

                                        15
2011, La kehuelga radio.


              _delay_us(100);
              OCR0 = amp;
              sprintf((buftx+strlen(buftx)), "RA%02Xr", 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)), "IAMr");
        };

# 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)), "IA0r");
        };

# Reportar fuente de la amplitud de inicio:
    ( [Ii] [Aa] (’?’) (’r’) ) =>
        {
            argnum = eeprom_read_byte(&nvai);
            sprintf((buftx+strlen(buftx)), "IA%1cr", (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%04dr", frec);
            } else {
                sprintf((buftx+strlen(buftx)), "ERROR: Frec. MALA!r");
            }
        };

# Reportar la Frecuencia:
    ( [Ff] (’?’) (’r’)) =>
        {
            sprintf((buftx+strlen(buftx)), "F%04dr", frec);

                                          16
2011, La kehuelga radio.


        };

# Guardar la frecuencia seleccionada en la EEPROM:
    ( [Gg] [Ff] (’r’)) =>
        {
            eeprom_write_word(&nvfrec, frec);
            sprintf((buftx+strlen(buftx)), "GF%04dr", 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%04dr", 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)), "IFSr");
        };

# Frecuencia de inicio de la nvram:
    ( [Ii] [Ff] [Mm] (’r’) ) =>
        {
            eeprom_write_byte(&nvfi, 0x01);
            sprintf((buftx+strlen(buftx)), "IFMr");
        };

# Reportar fuente de la frecuencia de inicio:
    ( [Ii] [Ff] (’?’) (’r’) ) =>
        {
            argnum = eeprom_read_byte(&nvfi);
            sprintf((buftx+strlen(buftx)), "IF%1cr", (argnum) ? ’M’ : ’S’);
        };

# Reportar los interruptores:

                                        17
2011, La kehuelga radio.


   ( [Ss] (’?’) (’r’)) =>
       {
           sprintf((buftx+strlen(buftx)), "S%02Xr", 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%1cr", argnum, bitc);
        };

# Reportar un pin de control:
    ( [Pp] ([0-3] @{argnum = *(ts+1) - ’0’;}) (’?’) (’r’) ) =>
        {
            printf((buftx+strlen(buftx)), "P%1X%1cr",
                   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%02Xr", 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%08lXr", argnum32);

                                        18
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%08lXr", 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%08lXr", 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%04dr", argnum);
        };

# Reportar el estado del pll::
    ( [Ee] ’?’ ’r’) =>
        {
            sprintf((buftx+strlen(buftx)), "E%1Xr", estado);
        };

# Cambiar al modo debug:
    ( [Mm] [Dd] ’r’ ) =>
        {
            cli();
            modo_debug();

                                        19
2011, La kehuelga radio.


                  sei();
                  strcat(buftx, "MDr");
            };

# Cambiar al modo pll:
    ( [Mm] [Pp] ’r’ ) =>
        {
            cli();
            modo_pll();
            sei();
            strcat(buftx, "MPr");
        };

      *|;

}%%

%% 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
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
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
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
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
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
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
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
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
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

Manual excitador-vaca

  • 1.
    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
  • 2.
    2011, La kehuelgaradio. El excitador puede ser configurado de dos maneras; con 8 interruptores que están soldados a la tarjeta y mediante un puerto de comunicación serial RS232. Con los interruptores solo es posible seleccionar la frecuencia de operación, mientras que con el puerto serial el excitador puede comunicar información referente a su funcionamiento, como el estado 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 usarla para 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 de su 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 al número binario 0000000 corresponde la frecuencia 87.9 MHz, al número 0000001 la frecuencia 88.0 MHz 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 queremos configurar, podemos usar la siguiente relación: f × 10 − 879 n= (1) 2 Donde, f es la frecuencia en MHz, y n es el número que hay que configurar en el dipswitch; n está 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: 93,5 × 10 − 879 n = 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; puedes conectarlo a un puerto serial de una computadora, necesitarás un programa emulador de terminal que se pueda conectar a un puerto serie, en GNU/Linux puedes usar gtkterm; además debes configurarlo con los siguientes parámetros: 2
  • 3.
    2011, La kehuelgaradio. Velocidad 9600 Bits de datos 8 Bits de paro 1 Paridad 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 el comando. Si la comunicación funciona correctamente, el excitador responderá con la frecuencia de operació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 en megahertz 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 potencia mínima y FF la máxima. El excitador debe responder con: Ahh 3
  • 4.
    2011, La kehuelgaradio. 2.4. Referencia de comandos Hay bastantes comandos para cambiar y conocer el estado del excitador, están resumidos en el siguiente 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- RAhh PROM IAM La potencia de inicio se lee de la EE- IAM PROM IA0 Hace que la potencia de inicio sea 0 IA0 IA? Reporta la fuente de la potencia de IAM, IA0 inicio Fiiii Cambia la frecuencia Fiiii ERROR: Frec. INVALIDA! F? Reporta la frecuencia Fiiii GF Guarda la frecuencia seleccionada en GFiiii la EEPROM IFS La frecuencia de inicio se lee del IFS dipswitch RF Restaura la frecuencia desde la EE- RFiiii ERROR: Frec. INVALIDA! PROM IFM La frecuencia de inicio se lee de la IFM EEPROM IF? Reporta la fuente de la frecuencia de IFM, IFS inicio 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- P[0-3][01] trol V[0-7] Reporta un canal del ADC (conver- V[0-7]hhh tidor analógico digital) 3. Diagramas 3.1. Esquemático 4
  • 5.
    Vcc C35 R37 R38 R40 R42 .1uF 100k 68k 6k8 680 C30 R32 .01uF 4k7 1 R2 +12V +12V 47 R35 1k Q5 U4 2 8 6 C39 C41 T1 C40 2.2uF 1 1 MTP2955 7 .022uF 0.22uF par trensado de cat5, 5 2v, 3/8 in. d.i. 4 C1 C2 C3 C5 C6 R36 2 2 47uF 4u7 .01uF 1000pF 1000pF 12k R41 D2 R17 1k 1n4148 4K7 R39 20k 3 C29 C31 C33 1 Q4 4u7 tant. .1uF 1000pF C42 C42 MPSH10 R1 .01uF .001uF L1 2 100 78L05 U1 C20 +5V AtMega 8v. #18 1/4in d.i. 3 IN OUT 1 100pF R21 470 C37 GND 12pF 2 1 1 R9 C4 4K7 C23 C8 R5 R6 4u7 4K7 220 C14 3 1000pF R27 4u7 L3 2 2 VSS 18 100pF 1 6v. #16 1/4in d.i. Q2 MPSH10 C34 L4 C11 3 1000pF 2 70nH L5 114nH Salida RF Vee 1 470pF Q1 Apagar RF MPSH10 +5V C28 2 R3 330pF 3 3v. #16, 4v. #16, 100 78L05 U2 1/4in. d.i. 1/4in. d.i. 1 Q6 +5V RS232 3 IN OUT 1 R24 2sc1970 R16 C18 R19 C38 C43 C45 GND 4K7 2 R11 470 22 1000pF R33 27pF 56pF 33pF 2 4k7 74HC4040 U6 1 1 220 C7 74AC74 U5 9 C10 R8 Q1 4u7 4u7 12k 2 5 7 2 2 VSS D Q Q2 Q4 5 1 CLR Q 6 Q7 4 Vee 3 4 PRE Q3 6 1 Q3 MPSH10 R25 3 CLK Q8 13 10 CLK 220 2 Q9 12 R4 C17 11 Reset 100 78L05 U3 14 47pF Q10 +5V Contadores C16 3 IN OUT 1 C24 Q11 15 4p7 GND 150pF Q12 1 74AC74 U5 2 1 1 Q6 2 C9 12 D Q 9 C12 Q5 3 4u7 4u7 R14 13 8 2 2 VSS CLR Q 4k7 C19 R22 +5V 33pF 220 R26 10 PRE 4k7 Vee 11 CLK L2 R18 R20 R23 6v. #18 1/4in d.i. 33k 4k7 3k3 R30 C13 R10 4k7 Audio L .0068uF 470 +12V U4 R15 D1 8 2 R34 +5V 1k C22 1 22k R7 MV209 .1uF 3 12k 4 R28 R29 R31 C15 R13 39k 22k 3k3 .0068uF 470 C21 +5V 1 Audio R 220pF +5V C27 C32 C36 1uF 2 .01uF .01uF +5V R12 C25 C26 2 12k .1uF .1uF U7 +5V DB15HD−9 C50 U8 MAX232 10 1 ATmega32 DIP40 1uF C47 AGND DB15HD−10 2 V+ C1+ 1 1 2 1uF 9 RESET_L VCC DGND DB15HD−5 C1− 3 33 PA7 (ADC7) PD7 (OC2) 21 6 V− C2+ 4 AN7 DB15HD−15 R43 4k7 2 34 PA6 (ADC6) PD6 (ICP) 20 C2− 5 2 1 AN6 DB15HD−14 11 14 C51 AN5 DB15HD−13 35 PA5 (ADC5) PD5 (OC1A) 19 P1 DB15HD−1 Tx1 In Tx1 Out 1 C48 1uF 36 PA4 (ADC4) PD4 (OC1B) 18 1uF 12 Rx1 Out Rx1 In 13 AN4 DB15HD−12 P2 DB15HD−2 C52 10 7 100p AN3 DB15HD−11 37 PA3 (ADC3) PD3 (INT1) 17 P3 DB15HD−3 Tx2 In Tx2 Out RS232 RxD (DB9 Hembra pin 2) 38 PA2 (ADC2) PD2 (INT0) 16 9 Rx2 Out Rx2 In 8 AN2 DB15HD−8 P4 DB15HD−4 RS232 TxD (DB9 Hembra pin 3) R45 33k AN1 DB15HD−7 39 PA1 (ADC1) PD1 (TXD) 15 2 RS232 DTR (DB9 Hembra pin 4) R46 4k7 AN0 DB15HD−6 40 PA0 (ADC0) PD0 (RXD) 14 J1 RS232 GND (DB9 Hembra pin 5) jumper, para programar SW DIP−8 R47 1 4k7 8 PB7 (SCK) PC7 (TOSC2) 29 8 9 RS232 RTS (DB9 Hembra pin 7) 7 PB6 (MISO) PC6 (TOSC1) 28 7 10 6 PB5 (MOSI) PC5 (TDI) 27 6 11 RS232 CTS (DB9 Hembra pin 8) 5 12 5 PB4 (SS_L) PC4 (TDO) 26 R48 R49 R50 4 13 4k7 4k7 4k7 4 PB3 (OC0/AIN1) PC3 (TMS) 25 3 14 Z1 3 PB2 (INT2/AIN0) PC2 (TCK) 24 2 15 1n4733 5.1V 1 16 Apagar RF 2 PB1 (T1) PC1 (SDA) 23 U9 1 PB0 (XCK/T0) PC0 (SCL) 22 R44 2k2 +5V LED1 13 XTAL1 AVCC 30 Frec. Fija 12 XTAL2 AREF 32 GND GND 1 X1 C49 11 31 16MHz 4u7 2 2011, La kehuelga radio. C44 C46 5−30pf 15pF
  • 6.
    2011, La kehuelgaradio. 3.2. PCB 6
  • 7.
    2011, La kehuelgaradio. 3.2.1. Tarjeta madre 7
  • 8.
    2011, La kehuelgaradio. 3.2.2. Tarjeta de comunicación serial 3.2.3. Tarjeta del amplificador operacional 3.2.4. Tarjeta de contadores 8
  • 9.
    2011, La kehuelgaradio. 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
  • 10.
    2011, La kehuelgaradio. 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
  • 11.
    2011, La kehuelgaradio. 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
  • 12.
    2011, La kehuelgaradio. } 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
  • 13.
    2011, La kehuelgaradio. 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
  • 14.
    2011, La kehuelgaradio. 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
  • 15.
    2011, La kehuelgaradio. #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%02Xr", amp); }; # Reportar la Amplitud: ( [Aa] (’?’) (’r’)) => { sprintf((buftx+strlen(buftx)), "A%02Xr", amp); }; # Guardar la Amp. en la EEPROM: ( [Gg] [Aa] (’r’)) => { eeprom_write_byte(&nvamp, amp); sprintf((buftx+strlen(buftx)), "GA%02Xr", amp); }; # Restaurar la Amp. de la EEPROM: ( [Rr] [Aa] (’r’)) => { amp = eeprom_read_byte(&nvamp); 15
  • 16.
    2011, La kehuelgaradio. _delay_us(100); OCR0 = amp; sprintf((buftx+strlen(buftx)), "RA%02Xr", 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)), "IAMr"); }; # 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)), "IA0r"); }; # Reportar fuente de la amplitud de inicio: ( [Ii] [Aa] (’?’) (’r’) ) => { argnum = eeprom_read_byte(&nvai); sprintf((buftx+strlen(buftx)), "IA%1cr", (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%04dr", frec); } else { sprintf((buftx+strlen(buftx)), "ERROR: Frec. MALA!r"); } }; # Reportar la Frecuencia: ( [Ff] (’?’) (’r’)) => { sprintf((buftx+strlen(buftx)), "F%04dr", frec); 16
  • 17.
    2011, La kehuelgaradio. }; # Guardar la frecuencia seleccionada en la EEPROM: ( [Gg] [Ff] (’r’)) => { eeprom_write_word(&nvfrec, frec); sprintf((buftx+strlen(buftx)), "GF%04dr", 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%04dr", 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)), "IFSr"); }; # Frecuencia de inicio de la nvram: ( [Ii] [Ff] [Mm] (’r’) ) => { eeprom_write_byte(&nvfi, 0x01); sprintf((buftx+strlen(buftx)), "IFMr"); }; # Reportar fuente de la frecuencia de inicio: ( [Ii] [Ff] (’?’) (’r’) ) => { argnum = eeprom_read_byte(&nvfi); sprintf((buftx+strlen(buftx)), "IF%1cr", (argnum) ? ’M’ : ’S’); }; # Reportar los interruptores: 17
  • 18.
    2011, La kehuelgaradio. ( [Ss] (’?’) (’r’)) => { sprintf((buftx+strlen(buftx)), "S%02Xr", 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%1cr", argnum, bitc); }; # Reportar un pin de control: ( [Pp] ([0-3] @{argnum = *(ts+1) - ’0’;}) (’?’) (’r’) ) => { printf((buftx+strlen(buftx)), "P%1X%1cr", 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%02Xr", 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%08lXr", argnum32); 18
  • 19.
    2011, La kehuelgaradio. }; # 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%08lXr", 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%08lXr", 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%04dr", argnum); }; # Reportar el estado del pll:: ( [Ee] ’?’ ’r’) => { sprintf((buftx+strlen(buftx)), "E%1Xr", estado); }; # Cambiar al modo debug: ( [Mm] [Dd] ’r’ ) => { cli(); modo_debug(); 19
  • 20.
    2011, La kehuelgaradio. sei(); strcat(buftx, "MDr"); }; # Cambiar al modo pll: ( [Mm] [Pp] ’r’ ) => { cli(); modo_pll(); sei(); strcat(buftx, "MPr"); }; *|; }%% %% 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
  • 21.
    2011, La kehuelgaradio. } 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
  • 22.
    2011, La kehuelgaradio. 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
  • 23.
    2011, La kehuelgaradio. #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
  • 24.
    2011, La kehuelgaradio. 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
  • 25.
    2011, La kehuelgaradio. 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
  • 26.
    2011, La kehuelgaradio. #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
  • 27.
    2011, La kehuelgaradio. /* 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
  • 28.
    2011, La kehuelgaradio. # 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
  • 29.
    2011, La kehuelgaradio. 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