Autor Tema: Mover servo con potenciometro  (Leído 23281 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Mover servo con potenciometro
« en: 30 de Abril de 2007, 21:39:10 »
Hola!
hace unos meses empece con un proyecto de complejidad media, que era mover un servo al compas de un potenciometro, es decir, que el servo imitara los movimientos (manuales) del potenciometro.
esto lo he conseguido hace tiempo, y ahora que tengo un momentito lo posteo para que al que le interese pueda sacarle provecho.

Código: [Seleccionar]
#include <16F88.h>
#device adc=8
#FUSES NOWDT,INTRC_IO,MCLR,PUT,NOBROWNOUT,NOCPD,NOLVP,NOIESO,NODEBUG

//--- Constantes ---
#define SERVO_1   PIN_A0   //linea de control por PWM para el servo
#define ADC_SERVO     1    //canal adc que se usa para el potenciometro
//------------------

#use delay(clock=4000000)
#use standard_io(a)
#use standard_io(b)

//--- Variables ---
int1 flag5RTCC = TRUE;           //indica si se completaron 5 RTCC
int1 flag50mS = FALSE;           //indica si ocurrio interrupcion de timer1
int1 flagPulso_Alto = FALSE;     //indica si esta el pulso en alto
int8 Posicion_Servo = 93;        //donde se posiciona el servo segun la lectura del adc
int8 ContRTCC = 0;               //contador de RTCC
//-----------------

//--- Funciones ---
void Calcular_Posicion(void);
//-----------------

#int_TIMER0
void TIMER0_isr(void){        //timer que cuenta 20mS
//Timer de 8 bits --> 256 = 1 RTCC
//Pescaler de 1:16
//1 tick cada 16 uS = 0.016mS
//1 RTCC cada 4.0mS (256 - 6 Ticks)
//5 RTCC = 20mS

   ContRTCC = ContRTCC + 1;
   set_TIMER0(6);

   if(ContRTCC == 5){
      flag5RTCC = TRUE;
      ContRTCC=0;
   }
}

#int_TIMER1
void TIMER1_isr(void) {       //timer que cuenta 50mS
//Timer de 16 bits --> 65536 = 1 RTCC
//Pescaler de 1:1
//1 tick cada 1 uS
//1 RTCC cada 50mS (65536 - 15536 Ticks)

   set_TIMER1(15535);
   flag50mS = TRUE;
}

void main(void) {
   int8 ValTMR0;

   setup_adc_ports(sAN1|VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
   setup_oscillator(OSC_4MHZ|OSC_INTRC);

   set_adc_channel(ADC_SERVO);
   
do {
//>-----------------------Movimiento del servo--------------------------------->

         //--- Calcula posicion servo segun lectura adc ---
         if(flag50mS == TRUE){
            Calcular_Posicion();
            flag50mS = FALSE;
         }
         //------------------------------------------------

         //--- Dispara pulso PWM cuando se completan 5 RTCC ---
    if(flag5RTCC == TRUE){
    flag5RTCC = FALSE;
            output_high(SERVO_1);
            flagPulso_Alto = TRUE;
    }
         //----------------------------------------------------

         //--- Baja pulso PWM cuando corresponda ---
    valTMR0 = get_TIMER0() - 6;

    if((flagPulso_Alto == TRUE) && (valTMR0 > Posicion_Servo)){  //baja el pulso en el tiempo correspondiente a Posicion
            output_low(SERVO_1);
            flagPulso_Alto = FALSE;
         }
         //-----------------------------------------
//<----------------------------------------------------------------------------<

} while(true);
}

void Calcular_Posicion(void){
   int16 ValorADC;
   ValorADC = read_adc();
   Posicion_Servo = 31 + (int16)((int16)(ValorADC * 124) / 255);
}

lo he comentado lo mas posible para que sea de facil comprension

Citar
Posicion_Servo = 31 + (int16)((int16)(ValorADC * 124) / 255);
esto en concreto no esta comentado, pero es una operacion aritmetica que dado el valor del ADC me devuelve la posicion en que se debe colocar el servo, expresada en ticks de reloj

si se quisiera hacer con mas servos y sus respectivos potenciometros solo hay que repetir el codigo correspondiente... entiendo que si sois capaces de comprender el codigo tambien podreis apañaros con que cosas repetir :roll:
yo lo tengo hecho con 2 servos y funciona bien

la unica pega de esto es que por algun motivo el servo vibra cuando no se esta moviento el potenciometro, mas que una vibracion es como un tick pequñito que le ocurre cada 1 segundo aprox... supongo que sera porque no esta bien calculado el PWM, o porque aunque si este bien calculado, el pic tarda lo suyo en los procesos y termina no siendo exacto... :z)
si alguien tiene solucion a esto es de agradecer, aunque para mis aplicaciones no es algo critico

tengo que aclarar que todo lo referente a servos es una adaptacion de los ejemplitos de RedPic, si necesitais comprender el funcionamiento de los servos es de parada obligatoria sus posts

espero que sea de ayuda esto y le sirva a alguien :mrgreen:
salu2
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado softjad

  • PIC10
  • *
  • Mensajes: 41
Re: Mover servo con potenciometro
« Respuesta #1 en: 04 de Mayo de 2007, 08:36:16 »
Ei, estaba buscando un dispositivo parecido.
Tengo que mover una camara con 2 servos, uno para el eje horizontal e otro para el eje vertical.
Para los controloar tengo 4 switch, dos para cada eje.

El movimiento tiene que ser lento.

Me puedes dar una ayuda?

Utilizo un pic 16F877 con crystal de 4Mhz.

salu2

Desconectado el_legal

  • PIC12
  • **
  • Mensajes: 65
    • LINAP SRL
Re: Mover servo con potenciometro
« Respuesta #2 en: 04 de Mayo de 2007, 09:29:51 »
Hola softjad:
 yo una vez hice una aparato igual para una grua de TV, pero la hice con dos motoreductores (mucho mas barato que un servo  y mayor torque) para el control utilise un CI L293D, un 555 y dos operacionale. el circuito no lo encuentro en la PC pero tengo halgo del PCB
"Si alguno quiere ser el primero, que se haga el último de todos y el servidor de todos."
 Mc 9.35

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re: Mover servo con potenciometro
« Respuesta #3 en: 06 de Mayo de 2007, 11:14:30 »
si no quieres complicarte demasiado puedes optar por algo asi:
http://cgi.ebay.es/USB-MISSILE-ROCKET-LAUNCHER-AIR-DARTS-OFFICE-TOY_W0QQitemZ150118238591QQihZ005QQcategoryZ50197QQrdZ1QQssPageNameZWD2VQQcmdZViewItem
http://cgi.ebay.com/USB-Missile-Rocket-Launcher-Office-Computer-Toy_W0QQitemZ300105790346QQihZ020QQcategoryZ31534QQssPageNameZWDVWQQrdZ1QQcmdZViewItem
pero si quieres hacerlo tu mismo, supongo que podrias modificar un poco el programa que puse yo...
pones una interrupcion que lea los 4 switch cada x milisegundos y segun cual este presionado sume o reste a la posicion actual del servo
lo de conseguir que el movimiento sea despacio... pues  ni idea, pero supongo que si el intervalo de tu interrupcion no es muy corta, el servo ira mas despacio, ya que lo que haces es sumar o restar a la posicion actual, y no un salto brusco de una posicion a la otra, lo que esta haciendo que el servo por todos los puntos intermedios entre el inicio y el fin, y no directamente....
comentanos que tal te esta llendo con esto y cuando tenas algo puedes poner tu codigo aqui... asi tendriamos mas informacion y variantes de esto! :-/
salu2
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado softjad

  • PIC10
  • *
  • Mensajes: 41
Re: Mover servo con potenciometro
« Respuesta #4 en: 07 de Mayo de 2007, 06:57:00 »
Gracias a todos. Lo voy a intentar.

Salu2

Desconectado softjad

  • PIC10
  • *
  • Mensajes: 41
Re: Mover servo con potenciometro
« Respuesta #5 en: 08 de Mayo de 2007, 07:43:35 »
Lo que queria hacer es muy parecido con esto:


Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re: Mover servo con potenciometro
« Respuesta #6 en: 08 de Mayo de 2007, 11:10:00 »
eso no tiene mayor problema
lo puedes hacer perfectamente, lo unico es que ese no iria lento como tu quieres
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado Trev_11

  • PIC10
  • *
  • Mensajes: 44
Re: Mover servo con potenciometro
« Respuesta #7 en: 26 de Septiembre de 2007, 12:30:55 »
Esta bueno lo ke propones :-/,me imagino ke seria algoparecido a un jostick,y poder controlar servos con un jostick estaria bueno,has pensado en eso?por que no encuentro mucho.Chau

Desconectado juanelete

  • PIC12
  • **
  • Mensajes: 74
Re: Mover servo con potenciometro
« Respuesta #8 en: 28 de Septiembre de 2007, 13:29:31 »
Hola a Tod@s

Yo ya he hecho anteriormente alguna cosa con servos, y voy a intentar aportar mi "granito"

En primer lugar quiero insistir en la necesidad de enviar continuamente un pulso cada 20 ms (aprox.), incluso si queremos mantener el servo fijo en la misma posicion, si dejamos de enviar pulsos o los enviamos con mucho retraso, notaremos que el servo va a trompicones y que se queda sin fuerza, como desconectado. Por el contrario, si los servos reciben los pulsos mas rapido de la cuenta (< 15 ms aprox.), la electronica del servo no podra interpretar bien la señal y el movimiento sera erratico.

Mover servos supone por lo tanto un trabajo continuo y agotador para el procesador, por lo tanto deberemos afinar en la programacion e intentar que no haya tiempos muertos.

Para mover un servo hay que enviar un pulso alto de 0,5 a 2,5 ms de duracion (nos determinara la posicion) , bajar el pulso y esperar hasta los 20 ms y empezar de nuevo.

Mover varios servos (hasta 8 o 9) simultaneamente y que al procesador le sobre tiempo para hacer todo lo demas, es algo mas complicado.

Para una mejor compresion del problema vamos a centrarnos solamente el la parte de poner el pulso en alto en cada uno de los servos, olvidandonos por el momento de la parte en que hay que ponerlos en pulso bajo.

Para un solo servo ajustamos el timer para que se desborde cada 20 ms que es cuando tenemos que poner el pulso en alto, si ahora tenemos 4 servos, y ajustamos el timer en 5 ms, y vamos poniendo un pulso alto en cada servo secuencialmente, conseguimos el mismo efecto, osea, poner un pulso en alto en cada servo cada 20 ms, si en vez de 4 son 8 servos, pues ajustaremos el timer en 2,5ms (2,5x8=20ms). Ya tenemos la mitad del problema resuelto.

Vamos ahora a la parte de poner cada uno de los pulsos en bajo en cada servo.

Cada vez que que se desborda el timer y ponemos el pulso en alto del servo que le corresponda, deberemos tambien empezar a contar el tiempo que queremos que ese pulso este en alto, eso se puede hacer con el mismo timer, pero activando otra interrupcion en modo compare, y configurandola para que salte cada vez segun el tiempo requerido, y entonces poner en pulso bajo ese servo, y asi con todos.

Siento el rollazo.  :?

Luego cuando este en casa (ahora estoy en el curro je, je, je) intentare poneros un pequeño ejemplo que sera bastante mas clarificador.   :-)

Saludos a tod@s.   :mrgreen:

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re: Mover servo con potenciometro
« Respuesta #9 en: 28 de Septiembre de 2007, 15:51:26 »
hummm.. interesante
entendi hasta lo de poner el pulso en alto, pero no entendi lo de poner otro timer en modo compare para bajar el pulso... tal vez sea que nunca use un timer de ese modo  :?
podrias explicarlo un poco mejor? esto de los servos me apasiona y todo lo que pueda aprender es bienvenido!
salu2
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado juanelete

  • PIC12
  • **
  • Mensajes: 74
Re: Mover servo con potenciometro
« Respuesta #10 en: 28 de Septiembre de 2007, 17:45:55 »
Hola a Tod@s

Citar
entendi hasta lo de poner el pulso en alto, pero no entendi lo de poner otro timer en modo compare para bajar el pulso... tal vez sea que nunca use un timer de ese modo

Si lees al maestro RedPic en "Generando pulso. 2ª Parte. Onda simétrica con INTCCP modo Compare" lo entenderas todo perfectamente. Pero te adelanto yo un poco.

Utilizando el mismo timer (contador), puedes activar varias interrupciones, la mas habitual es #int_timerx, que se activa cuando el contador llega al limite, y empieza otra vez desde 0 o desde el valor que nos interese, otra interrupcion interesante es #int_ccpx, que se puede configurar en modo capture o en modo compare, en modo compare lo que hace es activarse cuando el timerx que estamos utilizando llegue a un determinado valor, establecido con la variable CCP_x, osea que la puedo utilizar para contar un tiempo cualquiera. Si asigno CCP_x=5000, esto hara que en el momento que el timerx llegue a ese valor activara la interrupcion #int_CCPx, independientemente de que el contador siga su curso normal y tambien active la #int_timerx cuando llegue a su limite.

En tu ejemplo tienes que estar leyendo continuamente el valor del timerx y comparandolo con el valor de la posicion del servo, de esta forma solo tienes que poner en CCP_x el valor que quieres y ya saltara la interrupcion cuando corresponda.

Espero haberme "explicao" un poquito mejor.  :shock:

Como lo prometido es deuda, aqui os pongo un ejemplito  :lol:

Código: [Seleccionar]
////////////////////////////////////////////////////////////////////////////////////
//
// Moviendo 8 servos con un solo timer
//
//     
// Propósito: Mover hasta 8 servos eficientemente
//
// Conectar 8 servos al PORT_B
//
////////////////////////////////////////////////////////////////////////////////////


#include <16f876.h>
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP,NOCPD,NODEBUG,NOWRT

#ORG 0x1F00,0x1FFF {}           //Para 8k Pic 16F876/7 (necesario para bootloader)

#use delay(clock=20000000)      //Cambiar segun el cristal utilizado

////////////////////////////////////////////////////////////////////////////////////
//
// Defines y Constantes
//
////////////////////////////////////////////////////////////////////////////////////

float const uSxTick = 0.2;                  // Microsegundos por Tick de TMR1 a 20 Mhz

#define VAL_TIMER1 53000   // 65536-53000=12536 * 0,0002 = 2,5 milisegundos


////////////////////////////////////////////////////////////////////////////////////
//
// Variables Globales
//
////////////////////////////////////////////////////////////////////////////////////

int8 servo=0;                   // Numero de servo
int1 flag_timer1=FALSE;   

////////////////////////////////////////////////////////////////////////////////////
//
// Interrupción por desbordamiento del timer1
//
////////////////////////////////////////////////////////////////////////////////////

#int_timer1
void handle_timer1_int()  // Se activa cada 2,5 ms
{
    flag_timer1=TRUE;
    set_timer1(VAL_TIMER1);          // 65536-53000=12536*0,0002 = 2,5 ms
}



////////////////////////////////////////////////////////////////////////////////////
//
// Interrupción timer1 modo compare
//
////////////////////////////////////////////////////////////////////////////////////

#int_ccp2
void handle_ccp2_int()
{
    bit_clear(*6,servo);              // igual que output_low(PIN_Bx);  -> *6=PORTB  -> Pone a 0 el bit indicado en servo
}




////////////////////////////////////////////////////////////////////////////////////
//
// PROGRAMA PRINCIPAL
//
////////////////////////////////////////////////////////////////////////////////////

void main()
{
    ////////////////////////////////////////// INICIALIZACIONES GENERALES
    delay_ms(333);                           // Espero a que todo se estabilice e ...
    disable_interrupts(global);              // Inicializo el Micro y ...
    disable_interrupts(int_timer1);          // deshabilitando todo lo no necesario ...
    disable_interrupts(int_rda);
    disable_interrupts(int_ext);
    setup_adc_ports(NO_ANALOGS);
    setup_adc(ADC_OFF);
    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
    setup_timer_2(T2_DISABLED,0,1);

    setup_ccp2(CCP_COMPARE_INT);            // Configura CCP2 en modo COMPARE
    set_timer1(VAL_TIMER1);                      // 65536-53000=12536*0,0002 = 2,5 ms


    // Habilito las interrupciones necesarias
    enable_interrupts(int_timer1);          //Int timer 1
    enable_interrupts(int_ccp2);             // Habilito la interrpción INT_CCP2
    enable_interrupts(global);              //Habilita interrupciones

    do
    {
        if(flag_timer1==TRUE)              // Cuando se activa la int_timer1 -> cada 2,5 ms   
        {
            servo++;
            if (servo>=9) servo=1;       
   
            bit_set(*6,servo);              // igual que output_high(PIN_Bx);  -> *6=PORTB  -> Pone a 1 el bit indicado en servo
   
           
            CCP_2 = VAL_TIMER + pos_servo(servo);         // Calculo posicion servo correspondiente
                                                                                 // La funcion pos_servo() debeis implementarla vosotros

            flag_timer1=FALSE;       
        }

    }
    while (TRUE);
}


Lo he probado y funciona.

No existe la funcion pos_servo(), debereis implementarla vosotros. Yo lo he probado poniendo valores a mano.

He ido probando con un servo en cada pin del puerto B, y el servo se movia, pero a ultima hora al pincharlo en RB0, no hacia nada, no se lo que pasa, pero mi mujer ya ha nombrado la palabra "divorcio" y "trastos" varias veces en varias frases.  :?

Tengo que dejarlo por hoy  :mrgreen:

Saludos a tod@s

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re: Mover servo con potenciometro
« Respuesta #11 en: 28 de Septiembre de 2007, 18:31:50 »
mi mujer ya ha nombrado la palabra "divorcio" y "trastos" varias veces en varias frases.  :?

Tengo que dejarlo por hoy  :mrgreen:

 :D :D :D

gracias por arriesgar tu matrimonio para explicarnos esto!  :)

por cierto, vaya cosa mas interesante la interrupcion ccp!! nunca la habia tenido en cuenta, pense que era para otra cosa... me pondre a trabajar en ello y vere que sale de todo esto
otra vez, gracias por tu aportacion!
salu2
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re: Mover servo con potenciometro
« Respuesta #12 en: 28 de Septiembre de 2007, 21:29:48 »
uff... llevo un rato leyendome los post de redpic de como medir y generar pulsos, pero no consigo comprender como funciona el modulo CCP... mi duda es CUAL ES LA DIFERENCIA ENTRE EL CCP Y INT_EXT? porque ambos se activan a la entrada de un pulso, incluso se pueden configurar para que se activen a la subida o la bajada... el ccp en modo capture es lo mismo que la int_ext? para que sirve exactamente el modo compare?
gracias! y espero que compenses a tu mujer por tener tanta paciencia  :D
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Mover servo con potenciometro
« Respuesta #13 en: 29 de Septiembre de 2007, 02:20:45 »
El modo capture del CCP es como mezclar la interrupción externa con un Timer. Lo que hace es que cuando entras en la interrupción tienes a tu disposición el valor del Timer en una variable, que puedes leer para saber el ancho que ha tenido el pulso.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Mover servo con potenciometro
« Respuesta #14 en: 29 de Septiembre de 2007, 07:10:17 »
uff... llevo un rato leyendome los post de redpic de como medir y generar pulsos, pero no consigo comprender como funciona el modulo CCP... mi duda es CUAL ES LA DIFERENCIA ENTRE EL CCP Y INT_EXT? porque ambos se activan a la entrada de un pulso, incluso se pueden configurar para que se activen a la subida o la bajada... el ccp en modo capture es lo mismo que la int_ext? para que sirve exactamente el modo compare?
gracias! y espero que compenses a tu mujer por tener tanta paciencia  :D

Un poco de teoría descriptiva  :mrgreen: :

El nombre del módulo CCP viene dado por las iniciales del acróstico de Input Capture, Output Compare y Pulse Width Modulation. que desde la negrura de los tiempos ha sido llamado módulo CCP.

El por qué tres funciones aparentemente tan dispares aparecen juntas en un único módulo, y no sólo en los PIC de Microchip sino hasta donde alcanza mi conocimiento es un bloque generalizado entre los distintos fabricantes como Motorola o Atmel, lo ha apuntado muy acertadamente el maestro Nocturno: Su conjunción con un Timer.

Intentaré describir lo mas claro que pueda como funciona este sistema, aunque antes vamos a ver qué ocurre con la mucho mas simple Interrupción Externa por PB0 de un PIC16 (ó PB1 y PB2 en los PIC18) teniendo como objetivo el intento de saber cuanto dura un pulso externo.

La situación a que nos enfrentamos es un pulso que estando en estado lógico bajo cambia a estado lógico alto durante un tiempo y transcurrido éste vuelve a su estado inicial bajo. Es un pulso bajo-alto-bajo y deseamos medir cuánto dura ese estado alto intermedio.

Esto mismo podemos describirlo como el tiempo que tarda en aparecer un flanco de bajada tras haber aparecido un inicial flanco de subida. En la Serie Técnicas en C me dedicaba a mostrar cómo realizarlo de tres formas distintas.

Nuestro problema estriba entonces en implementar un método para realizar lo siguiente:

  • 1.-Esperamos a recibir un flanco de subida
  • 2.-Guardamos estado inicial de un Timer
  • 3.-Esperamos a recibir un flanco de bajada
  • 4.-Guardamos estado final del mismo Timer
  • 5.-Restamos estado inicial del final del Timer y obtenemos tiempo entre flancos.

Si la señal la conectamos al PIN_B0 de un PIC16 (ó PB1 y PB2 en los PIC18) con la Interrupción Externa tenemos solucionados los puntos 1 y 3 de la tarea que nos hemos propuesto, conocer cuando llegan ambos flancos. Las tareas 2 y 4, guardar los valores del Timer tenemos que escribirlo nosotros, habilitar las variables y leer el Timer que deseamos. Es el método descrito en Tiempo en Alto con INTEXT donde en cada cambio de flanco realizamos su correspondiente t1=get_timer1();. Fíjate que el tema está en get_timer().

Si por el contrario en vez de usar la Interrupción Externa usamos el módulo CCP configurado para la función Input Capture tendremos la facilidad de realizar dos tareas al mismo tiempo. Si le decimos al PIC que espere en CCP un Input Capture por flanco de subida cuando éste llegue y se dispare la Interrupción CCP tendremos ya en valor del Timer guardado en su registro CCPRxH:CCPRxL, o sea que las tareas 1 y 2 por un lado y las 3 y 4 de nuestra lista por otro estarán completadas. Es lo que describimos en Tiempo en Alto con INTCCP en donde en lugar del get_timer1() usamos el muchísimo mas directo t1=CCP_2 que es cómo se llama el registro registro CCPRxH:CCPRxL en CCS C.

Como puedes ver el CCP en Input Capture lo que hace realmente es capturar el valor de un Timer cuando se presenta un flanco determinado. Nosotros lo utilizamos en nuestro ejemplo para conmutar el flanco a detectar y medir el ancho del pulso. Otras aplicaciones sólo dependen de la imaginación del artista.

De forma simétrica o complementaria a ésta de recoger el valor del Timer cuando hay un cambio externo es el modo Output Compare del CCP. Este modo de funcionamiento del CCP es justo lo contrario al anterior: Producimos un cambio de estado en el pin del CCP cada vez que el Timer alcanza un valor determinado. O sea que ponemos el registro CCPRx a un valor que nos interese y cuando el Timer llega a ese valor el pin se pone en Alto, en Bajo o conmuta, según programemos su función. Esto lo podéis ver en Onda Simétrica Mediante INTCCP en modo Compare donde utilizamos este método para generar un pulso.

Insisto de nuevo en la idea: Input Capture determina el valor del Timer al cambiar el estado del pin, Output compare cambia el estado del pin cuando el Timer llega a un valor determinado. Son maravillosamente simétricos y complementarios.

Y por fin nos queda el PWM que no es mas que especialización del anterior. Activando ésta función del CCP lo que hacemos es cargar dos valores del Output Compare para generar un ancho de pulso de salida determinado y qué porcentaje del mismo va a estar en alto y cuál en bajo, o sea que modulamos el ancho de pulso. Este PWM es una como un Output Compare sofisticado con el que con muy poco código podemos controlar todos los parámetros del pulso que necesitamos generar.

Bueno y eso es todo por ahora amigos. Espero no haberos aburrido demasiado.  :mrgreen:
 

 


« Última modificación: 29 de Septiembre de 2007, 07:16:16 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania