Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

09/07/2010 #1


Duda Módulo CCP
Bueno amigos tengo una duda sobre el módulo ccp de los pic, estoy programando en hitech, y quiero saber si puedo utilizar el oscilador interno de mi pic para usar el puerto ccp para así utilizarlo a 2 MHZ, ya que necesito una frecuencia mas baja, y utilizar un cristal externo corriendo a 20 MHZ para el resto del código del micro. Para así poder tomar decisiones a 20MHZ y nada mas escribir los registros del CCP para tener un PWM con el cristal interno a 4.

Cualquier comentario o sugerencia es bienvenido, gracias.
09/07/2010 #2


Respuesta: Duda Módulo CCP
Hola, no podés hacer eso. Leé un poco de arquitectura de microcontroladores para orientarte. El CCP en modo PWM funciona con el timer2, usa el preescalador de este último para lograr la aplicación que necesitás. Saludos.
09/07/2010 #3


Respuesta: Duda Módulo CCP
gracias por tu respuesta, ahora ya no se que hacer, para usar el ccp y mi programa de control a la vez, a como lo veo tendría que usar dos micros pero me resulta exagerado.
14/07/2010 #4


Respuesta: Duda Módulo CCP
De qué trata tu proyecto?
15/07/2010 #5


Respuesta: Duda Módulo CCP
Sólo tengo que mover un servomotor de acuerdo a ordenes que mande desde otro micro por serial, a la vez que monitorea constantemente 8 entradas digitales y tomar decisiones de acuerdo a las entradas y las ordenes que reciba.
15/07/2010 #6


Respuesta: Duda Módulo CCP
Jorge, no veo para qué querés que el Módulo CCP trabaje con otro reloj, quizá es porque no estás siendo muy preciso o quizá yo esté dormido. Este módulo trabaja con el timer2 para generar la onda PWM (y los registros para el período y el ciclo de trabajo), si usás el preescalador del temporizador vas a obtener una frecuencia menor de salida. Es sólo cuestión de hacer los cálculos y de investigar la hoja de datos...
15/07/2010 #7


Respuesta: Duda Módulo CCP
Pues no se si estoy haciendo mal los cálculos, pero probando a 4 Mhz los cálculos me indican que la frecuencia menor es algo así como 200 o 300 hz, no recuerdo bien, yo necesito para el servo de 50hz, y no me salia para esa frecuencia, pero en un foro leí que si se puede con el ccp pero tiene que ser un cristal menor de por lo menos 2MHz y ahí fue donde vi que si me salen los calculos, el problema es que a esa frecuencia el micro no alcanza a notar varios cambios que hago, igual será porque no programo muy bien jeje.
17/05/2013 #8


Duda sobre periodo del modulo CCP en modo comparación(lenguaje CCS, PIC18f4550)
Hola a todos,
leyendo de este foro he sacado muchas dudas, pero esta no consigo resolverla, a ver si escribiendo alguien me puede ayudar

estoy intentando sacar una señal PWM del PIC para controlar un servo que debe trabajar a 50 Hz, siendo el periodo de nivel alto entre 0,5 y 2,5 ms.
Creia tenerlo todo bastante claro, pero en la realidad la verdad es que la señal no sale todo lo precisa que imaginé, y no sé si es que tengo algo mal, o es un error de precisión del PIC como he podido leer en algun sitio.

Os adjunto el código que he calculado yo con la fórmula T= 4/Fosc * (CCPR1+1) pues no tengo prescaler ni postscaler ninguno configurado.
Código:
#use delay(clock=4000000)
int1 cambio=0;            //Variable de control de cambio

#int_ccp1
void ccp1_int(){          //Función de interrupción
  if(++cambio==1){
    setup_ccp1(CCP_COMPARE_CLR_ON_MATCH); //Modo Comparación, cambio a 0
      set_timer1(0);                          //Borrado de TMR1
  CCP_1 = 1499;
  } else{
    setup_ccp1(CCP_COMPARE_SET_ON_MATCH); //Modo Comparación, cambio a 1
  CCP_1 = 19999;
  }

}
void main() {
disable_interrupts(global);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);    //Configuración TMR1
setup_ccp1(CCP_COMPARE_SET_ON_MATCH); //Configuración inicial modulo CCP
CCP_1 = 18499;                         //Inicialización del registro CCPR1
enable_interrupts(int_ccp1);     //Habilitación interrupción modulo CCP1
enable_interrupts(global);        //Habilitación interrupción general
do {
  } while (TRUE);
 }
Con los 4 MHz de clock, cada cuenta del TMR1 deberia ser 1 uS, con lo cual para conseguir 1500 uS = 1,5 mS, (CCPR1+1)=1500 y CCPR1=1499.
Y dejando correr el timer sin reiniciarlo, al llegar a 19999, por la misma regla habran pasado 20 mS.

El caso es que no consigo que los valores sean exactos simulando en proteus, la frecuencia me va oscilando entre 49 y 50 Hz, y en vez de posicionarseme en 0 grados en servo, se posiciona a 5,13º. Y montado en la protoboard me pasa exactamente lo mismo.

Si alguien ve algun fallo o le ha sucedido lo mismo y tiene alguna ayuda, se lo agradecería.
21/05/2013 #9

Avatar de Meta

Aquí hay un ejemplo.
Código:
/*
Los módulos CCPx.
Modo PWM. Modulación de anchura de pulsos.

Consiste en generar una señal de onda cuadrada por la línea RC2/CCP1 cuyo periodo puede
ser modificado así como la anchura del pulso (Duty Cycle). El periodo se determina según la 
fórmula T=(PR2+1)*4*Tosc*TMR2 preescaler. La duración del pulso o "Duty Cycle" (d) se deter-
mina según d=(CCPR1L:CCP1CON<5:4>)*Tosc*TMR2 preescaler.

El ejemplo emplea al módulo CCP1 con salida de señal por la línea RC2/CCP1. La señal de 
salida tiene un periodo determinado pora la constante "Periodo" y una anchura "Duty" 
determinada por la constante "Duty". Un osciloscopio conectado en RC2/CCP1 puede ayudar
a realizar las oportunas medidas. Nosotros hemos empleado el modelo PoScope Basic 2. */
    
#include <16f886.h>

/* Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades */

#fuses     NOLVP,PUT,NOWDT,EC_IO,NOFCMEN,NOBROWNOUT    //Palabra 1 de configuración
#fuses    NOWRT,BORV40                                //Palabra 2 de configuración

/* Con estas directivas las funciones "input" y "output_bit" no reprograman
el pin de la puerta cada vez que son utilizadas. Si no se indica el
modo fast_io se asume por defecto standard_io el cual reprograma el pin
siempre antes de ser utilizadas estas funciones. */

#use fast_io (C)

int    periodo=250;                            //Periodo de 1000 uS (250 * 4 de preescaler)
int duty=70;                                //Anchura 280 uS (70 * 4 de preescaler)

main()
{  
    SETUP_ADC_PORTS(NO_ANALOGS);            //Puertas A y B digitales
    output_c(0x00);                            //Borra las salidas
    set_tris_c(0xb1111011);                    //RC2 salida

//El módulo CCP1 actúa en el modo PWM con salida de señal por RC2/CCP1

    CCP_1_LOW=duty;            //Carga la anchura del pulso
    setup_ccp1(CCP_PWM);    //Modo PWM para el CCP1
    
/* El TMR2 trabaja con un preescaler 1:4 por lo que con una frecuencia de 4MHz evoluciona
cada 4uS (4*Tosc) */

    setup_timer_2(T2_DIV_BY_4,periodo-1,1);    //Carga el periodo

    while(1)
    {    
    }
}
22/05/2013 #10


Gracias por tu respuesta, pero con el modo PWM se me hace imposible hacer un señal con período de 20 mS.
Por eso uso el modo comparación.
22/05/2013 #11

Avatar de Meta

Sergi dijo: Ver Mensaje
Gracias por tu respuesta, pero con el modo PWM se me hace imposible hacer un señal con período de 20 mS.
Por eso uso el modo comparación.
Dime qué tipo de ejemplo deseas ver:

Modo PWM: Generar una señal PWM con el EECP1.
Modo PWM: Generar una señal PWM variable de anchura.
Modalidad "Pulse Steering" del modo PWM.
Modalidad de semi puente H "Half-Bridge" del modo PWM.
Modalidad de puende de H "Full-Bridge" del modo PWM.
Modalidad de auto desconexión "Auto-Shutdown" del modo PWM.
Modo PWM: Regulando la velocidad de un motor.
Modo PWM: Regular la velocidad y el sentido de giro del motor.
Modo PWM: Control de dos motores.
Modo PWM: Control de movimientos.

Saludo.
22/05/2013 #12


Modo PWM: Generar una señal PWM variable de anchura.

Modo PWM: Control de dos motores.

Controlo 2 servos con PWM variable de DC. Así que estas 2 me irían perfectas.
He intentado utilizar los modulos CCP para ello, pero escucho propuestas
22/05/2013 #13

Avatar de Meta

Ejemplo 1:
Código:
/*
Los módulos CCPx
Modo PWM. Variando la anchura del pulso a partir de una tensión analógica

Los dispositivos PIC16F88X disponen de un convertidor A/D de 10 bits de resolución y 5 u 8 
canales de entrada analógica. La tensión de referencia determina la resolución por bit:
(Res. = Vref/1024). Con Vref=5 --> res.= 4.8 mV/Bit; con Vref=2.5V --> res.= 2.4 mV/Bit

Se propone realizar una modulación de anchura de pulsos (PWM) mediante el módulo CCP1 y con
salida de señal por la línea RC2/CCP1. La anchura se ajusta a partir de una tensión analógica
que se introduce por RA0/AN0. Se establece un periodo fijo de 3200uS

El TMR2 trabajando con un preescaler de 1:16 y a una frecuencia de 4 MHz evoluciona cada 16 uS

Un osciloscopio conectado en RC2/CCP1 permitirá visualizar las variaciones del ancho de pulso 
en la señal salida RC2/CCP1 según la tensión analógica aplicada por RA0/AN0. Nosotros hemos 
empleado el modelo PoScope Basic 2. */
    
#include <16f886.h>

/* Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades */

#fuses     NOLVP,PUT,NOWDT,EC_IO,NOFCMEN,NOBROWNOUT    //Palabra 1 de configuración
#fuses    NOWRT,BORV40                                //Palabra 2 de configuración

/* Con estas directivas las funciones "input" y "output_bit" no reprograman
el pin de la puerta cada vez que son utilizadas. Si no se indica el
modo fast_io se asume por defecto standard_io el cual reprograma el pin
siempre antes de ser utilizadas estas funciones. */

#use fast_io (C)

int    periodo=200;                                //Valor para el periodo de 3200uS (200*Preescaler de 16)
int resultado;                                    //Variable para el resultado de la conversión AD

main()
{      
    set_tris_c(0b11111011);                        //RC2 salida
    setup_adc_ports(sAN0);                        //RA0 entrada analógica

//El TMR2 trabaja con un preescaler 1:16 por lo que con una frecuencia de 4MHz evoluciona
//cada 16uS ((4*Tosc)*16)

    setup_timer_2(T2_DIV_BY_16,periodo-1,1);    //Carga el periodo y TMR2 en ON    

//El módulo CCP1 actúa en el modo PWM con salida de señal por RC2/CCP1

    setup_ccp1(CCP_PWM);                        //Modo PWM para el CCP1
    setup_adc(adc_clock_div_32);                //Ajusta frecuencia de muestreo del ADC

    while(1)
    {    
//Se activa el ADC y se selecciona el canal RA0/AN0.
    
        set_adc_channel(0);                        //Selección del canal 0 (RA0)
        CCP_1_LOW=read_adc();                    //Inicia la conversión y carga la anchura del pulso    
    }
}
Ejemplo 2:
Código:
/*
Modo PWM con "pulse steering". 
Demostración de movimiento. Test de los motores y su control PWM mediante las rutinas
de movimiento contenidas en Motores_PWM.inc. El ejemplo realiza una serie de maniobras activando
los motores M1 y M2 tanto de forma individual como de forma conjunta (diferencial) */

#include <16f886.h>

/* Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades */

#fuses     NOLVP,PUT,NOWDT,EC_IO,NOFCMEN,NOBROWNOUT    //Palabra 1 de configuración
#fuses    NOWRT,BORV40                                //Palabra 2 de configuración

#use delay(clock=4000000)

#include    <Motores_PWM.h>                //Incluir funciones dec ontrol de tracción

//Programa principal
main()
{        
    setup_adc_ports(NO_ANALOGS);        //Puertas A y B digitales
    Mov_Inicio();                        //Inicio del módulo CCP1 en el modo PWM mejorado

//Bucle principal
    while(1)
    {
    Mov_Vel=128;                        //Velocidad del 50%
//Maniobras con motores individuales
    M1_A();                                //M1 avanza
    delay_ms(2000);                        //Temporiza
    M2_R();                                //M2 Retrocede
    delay_ms(2000);                        //Temporiza
    M1_S();                                //Parada de M1
    delay_ms(2000);                        //Temporiza
    M2_S();                                //Parada de M2
    delay_ms(2000);                        //Temporiza
    M1_R();                                //M1 retrocede
    delay_ms(2000);                        //Temporiza
    M2_A();                                //M2 avanza
    delay_ms(2000);                        //Temporiza
    M2_S();                                //Parada de M2
    delay_ms(2000);                        //Temporiza
    M1_S();                                //Parada de M1
    delay_ms(2000);                        //Temporiza

//Maniobras con ambos motores (movimientos diferenciales)
    Mov_Acel=10;                        //Aceleración progresiva para los movimientos diferenciales
    Mov_Vel=80;                            //Velocidad
    Avance();                            //Movimiento combinado de avance
    delay_ms(2000);                        //Temporiza
    Mov_Vel=255;                        //Velocidad progresiva desde 80 hasta 255
    Avance();                            //Movimiento combinado de avance
    delay_ms(2000);                        //Temporiza
    Stop();                                //Parada progresiva    
    delay_ms(2000);                        //Temporiza
    Retroceso();                        //Movimiento combinado de retroceso con velocidad de 255
    delay_ms(2000);                        //Temporiza
    Mov_Vel=80;                            //Velocidad progresiva de 255 a 80
    Retroceso();                        //Movimiento combinado de retroceso
    delay_ms(2000);                        //Temporiza
    Stop();                                //Parada progresiva
    delay_ms(2000);                        //Temporiza

    Mov_Acel=0;                            //Aceleración instantánea para los movimientos diferenciales
    Mov_Vel=255;                        //Velocidad instantánea a 255
    Izquierda();                        //Movimiento combinado de giro a la izda. con velocidad instantánea de 255
    delay_ms(2000);                        //Temporiza
    Stop();                                //Parada instantánea
    delay_ms(2000);                        //Temporiza
    Derecha();                            //Movimiento combinado de giro a la dcha. con velocidad instantánea de 255
    delay_ms(2000);                        //Temporiza
    Stop();                                //Parada instantánea
    delay_ms(2000);                        //Temporiza
    }
}
Librería:
Código:
/*
Conjunto de funciones para implementar todas las tareas de tracción de un sistema móvil basado en 2 motores DC que se
controlan mediante el PWM mejorado del módulo CCP1 de los dispositivos PIC16F88X en general y del PIC16F886 en particular.
Emplean la característica del modo "pulse steering" por la cual la salida de la señal PWM que genera el módulo CCP1
se puede re direccionar a 4 posibles salidas (RC2/CCP1/P1A, RB2/P1B, RB1/P1C y RB4/P1D), consiguiendo así controlar la 
velocidad y el sentido de giro de 2 motores DC conectados a esas líneas mediante los correspondientes drivers.


**************************************** CONEXION DE LOS MOTORES *********************************************
El empleo de estas funciones implica conectar los motores de una forma muy determinada a través de los drivers:

M1     : Terminal + con RC2/CCP1/P1A
    : Terminal - con RB2/P1B
M2     : Terminal + con RB1/P1C
    : Terminal - con RB4/P1D

De no respectar estas conexiones los motores o bien no girarán o bien lo harán en sentido contrario al esperado.

**************************************** VARIABLES DEL SISTEMA ***********************************************

Emplean dos variables fundamentales:

Var_Vel:    Determina la potencia aplicada al motor (velocidad), regulando el ancho del pulso PWM o "duty cycle".
            Varía desde 0x00 (0% de PWM) hasta 0xFF (100% de PWM). En valor de 0x7F representa el 50% de la señal PWM.
            Su contenido se aplica a cualquier movimiento posterior de cualquier motor y hasta que se modifique de nuevo.
Var_Acel:    Determina la aceleración/deceleración empleada para pasar de la velocidad actual a la velocidad deseada. 
            Expresa unidades de 1mS entre 0x00 y 0xFF. El valor 0x00 determina aceleración instantánea. Cualquier otro
            valor expresa los mili segundos que se emplean entre un valor de velocidad y el siguiente hasta alcanzar la deseada
            El control de aceleración sólo se aplica en las funciones que implique el movimiento de ambos motores y no en
            las funciones con motores individuales. Su contenido se aplica a cualquier movimiento posterior de cualquier motor, 
            hasta que se modifique.

************************************** DESCRIPCION DE LAS FUNCIONES *******************************************

Mov_Inicio()     Configura el módulo CCP1 en el modo PWM mejorado con salidas por RC2/P1A y RD5/P1B
                para el motor 1 y RD6/P1C y RD7/P1D para el motor 2

M1_S()             Detiene el motor M1

M1_A()             Activa el motor M1 en movimiento de avance a la velocidad establecida en Mov_Vel. 

M1_R()            Activa el motor M1 en movimiento de retroceso a la velocidad establecida en Mov_Vel

M2_S()            Detiene el motor M2

M2_A()            Activa el motor M2 en movimiento de avance a la velocidad establecida en Mov_Vel

M2_R()            Activa el motor M2 en movimiento de retroceso a la velocidad establecida en Mov_Vel

Stop()             Desactiva motores M1 y M2. Mov_Acel determina la deceleración: 0x00=intantánea 0xXX progresiva

Avance()        Activa motores M1 y M2 en movimiento diferencial de avance a la velocidad establecida en
                Mov_Vel. Mov_Acel determina la aceleración: 0x00=intantánea 0xXX progresiva

Retroceso()        Activa motores M1 y M2 en movimiento diferencial de retroceso a la velocidad establecida
                en Mov_Vel. Mov_Acel determina la aceleración: 0x00=intantánea 0xXX progresiva

Izquierda()        Activa motores M1 y M2 en movimiento diferencial para producir un diro a la izquiuerda.
                La velocidad se establece en Mov_Vel. Mov_Acel determina la aceleración: 0x00=intantánea 0xXX progresiva

Derecha()        Activa motores M1 y M2 en movimiento diferencial para producir un diro a la derecha.
                La velocidad se establece en Mov_Vel. Mov_Acel determina la aceleración: 0x00=intantánea 0xXX progresiva

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

#byte    PSTRCON=0x9d        //Registro de control del modo steering

int    periodo=255;            //Valor para el periodo de 4096uS ((255+1)*Preescaler de 16) de las señal PWM

int    Mov_Vel;                //Contiene la nueva velocidad deseada (anchura de la señal PWM)
int    Mov_Actual;                //Contiene la velocidad actual
int    Mov_Acel;                //Contiene el factor de aceleración. 0x00=aceleración instantánea

/***********************************************************************************************
Velocidad: Realiza una aceleración/deceleración desde la velocidad actual hasta alcanzar la 
nueva velocidad deseada contenida en Mov_Vel. En Mov_Acel se indica el factor de aceleración que 
se expresa en mili segundos */

void Velocidad()
{
    int c;
    if(Mov_Vel==Mov_Actual)                //Si la nueva velocidad igual a la actual ..
        return;
    if(Mov_Vel>Mov_Actual)                //Si la nueva velocidad mayor que la actual ..
        {
        do {
            Mov_Actual++;                //Incrementa velocidad actual
            CCP_1=Mov_Actual;            //Actualiza velocidad
            for(c=0;c<Mov_Acel;c++)        //Temporiza tantos mS como indique Mov_Acel antes de
                delay_ms(1);            //aumentar el siguiente valor de velocidad
            }while(Mov_Vel!=Mov_Actual);
        }
    else
        {
        do {
            Mov_Actual--;                //Decrementa la velocidad actual
            CCP_1=Mov_Actual;            //Actualiza velocidad
            for(c=0;c<Mov_Acel;c++)        //Temporiza tantos mS como indique Mov_Acel antes de
                delay_ms(1);            //aumentar el siguiente valor de velocidad
            }while(Mov_Vel!=Mov_Actual);
        }
}

/***********************************************************************************************
Mov_Inicio(): Configura el módulo CCP1 en el modo PWM mejorado con salidas por RC2/P1A y RB2/P1B
para el motor 1 y RB1/P1C y RB4/P1D para el motor 2 */

void Mov_Inicio()
{
    output_c(0x00);
    output_b(0x00);                        //Desactiva las salidas de los motores

//RC2CCP1/P1A, RB2/P1B, RB1/P1C y RB4/P1D salidas PWM para el modo "PULSE STEERING"
    set_tris_c(0b11111011);
    set_tris_b(0b11101001);

//El TMR2 trabaja con un preescaler 1:16 por lo que con una frecuencia de 4MHz evoluciona
//cada 16uS ((4*Tosc)*16)
    setup_timer_2(T2_DIV_BY_16,periodo-1,1);    //Carga el periodo y TMR2 en ON    
    setup_ccp1(CCP_PWM);
    PSTRCON=0b00010000;                    //Modo PULSE STEERING en OFF
    CCP_1_low=0;                        //PWM=0%
    Mov_Vel=0;
    Mov_Actual=0;                        //Inicia velocidad actual
}

/**************************************************************************************************
M1_S(): Detiene el motor M1 */

void M1_S()
{
    output_c(input_c()&0b11111011);    
    output_b(input_b()&0b11111011);        //Stop M1: RC2/CCP1/P1A=RB2/P1B=0
    bit_clear(PSTRCON,0);
    bit_clear(PSTRCON,1);                //Salida PWM para M1 en OFF
}

/**************************************************************************************************
M1_A(): Activa el motor M1 en movimiento de avance a la velocidad establecida en Mov_Vel.  */
                
void M1_A()
{
    output_b(input_b()&0b11111011);        //RB2/P1B = "0"
    CCP_1_low=Mov_Vel;                    //Ajustar el ciclo útil
    bit_set(PSTRCON,0);                    //Salida PWM por RC2/CCP1/P1A
    bit_clear(PSTRCON,1);                //RB2/P1B salida de nivel "0"            
}

/**************************************************************************************************
M1_R(): Activa el motor M1 en movimiento de retroceso a la velocidad establecida en Mov_Vel.  */
                
void M1_R()
{
    output_c(input_c()&0b11111011);        //RC2/CCP1/P1A = "0"
    CCP_1_low=Mov_Vel;                    //Ajustar el ciclo útil
    bit_set(PSTRCON,1);                    //Salida PWM por RB2/P1B
    bit_clear(PSTRCON,0);                //RC2/CCP1/P1A salida de nivel "0"
}

/**************************************************************************************************
M2_S(): Detiene el motor M2 */

void M2_S()
{
    output_b(input_b()&0b11101101);        //Stop M2: RB1/P1C=RB4/P1D=0
    bit_clear(PSTRCON,2);
    bit_clear(PSTRCON,3);                //Salida PWM para M2 en OFF
}

/**************************************************************************************************
M2_A(): Activa el motor M2 en movimiento de avance a la velocidad establecida en Mov_Vel.  */
                
void M2_A()
{
    output_b(input_b()&0b11111101);        //RB1/P1C = "0"
    CCP_1_low=Mov_Vel;                    //Ajustar el ciclo útil
    bit_set(PSTRCON,3);                    //RB1/P1C salida de nivel "0"
    bit_clear(PSTRCON,2);                //P1C inactivo        
}

/**************************************************************************************************
M2_R(): Activa el motor M2 en movimiento de retroceso a la velocidad establecida en Mov_Vel.  */
                
void M2_R()
{
    output_b(input_b()&0b11101111);        //RB4/P1D ="0"
    CCP_1_low=Mov_Vel;                    //Ajustar el ciclo útil
    bit_set(PSTRCON,2);                    //Salida PWM por RB1/P1C
    bit_clear(PSTRCON,3);                //RB4/P1D salida de nivel "0"                
}

/*******************************************************************************************************
Stop(): Desactiva motores M1 y M2. Mov_Acel determina la deceleración: 0x00=instantánea 0xXX progresiva */

void stop()
{
    int c, vel;
    vel=Mov_Vel;
    if(Mov_Acel!=0)                        //Si no es deceleración instantánea
    {
        do{
            vel--;                        //Decrementa velocidad ...
            CCP_1=vel;                    //Ajusta nueva velocidad
                for(c=0;c<Mov_Acel;c++)    //Temporiza tantos mS como indique Mov_Acel antes de
                    delay_ms(1);        //disminuir el siguiente valor de velocidad
            }while(vel>0);                //... hasta llegar a 0
    }
    output_c(input_c()&0b11111011);        //RC2/CCP1/P1A ="0"
    output_b(input_b()&0b11101001);        //RB2/P1B, RB1/P1C y RB4/P1D ="0"
    PSTRCON=0b00010000;                    //No hay salida PWM
    Mov_Actual=0;
    CCP_1=0;                            //Señal PWM = 0%
}

/**************************************************************************************************
Avance: Activa motores M1 y M2 en movimiento diferencial de avance a la velocidad establecida en
Mov_Vel. Mov_Acel determina la aceleración: 0x00=instantánea 0xXX progresiva */

void Avance()
{
    output_b(input_b()&0b11111001);        //RB2/P1B y RB1/P1C ="0"
    PSTRCON=0b00011001;                    //Salida PWM por RC2/CCP1/P1A y RB4/P1D
    if(Mov_Acel != 0)                    //Aceleración instantánea ??
        Velocidad();                    //No, progresiva
    else                                //Si, instantánea
        {
        Mov_Actual=Mov_Vel;                //Ajusta nueva velocidad actual
        CCP_1_low=Mov_Vel;                //Ajustar el ciclo útil de forma instantánea
        }
}

/**************************************************************************************************
Retroceso: Activa motores M1 y M2 en movimiento diferencial de retroceso a la velocidad establecida en
Mov_Vel. Mov_Acel determina la aceleración: 0x00=instantánea 0xXX progresiva */

void Retroceso()
{
    output_c(input_c()&0b11111011);        //RC2/CCP1/P1A ="0"
    output_b(input_b()&0b11101111);        //RB4/P1D ="0"
    PSTRCON=0b00010110;                    //Salida PWM por RB2/P1B y RB1/P1C
    if(Mov_Acel != 0)                    //Aceleración instantánea ??
        Velocidad();                    //No, progresiva
    else                                //Si, instantánea
        {
        Mov_Actual=Mov_Vel;                //Ajusta nueva velocidad actual
        CCP_1_low=Mov_Vel;                //Ajustar el ciclo útil de forma instantánea
        }
}

/**************************************************************************************************
Izquierda: Activa motores M1 y M2 en movimiento diferencial para producir un giro a la izquierdade.
La velocidad se establece en Mov_Vel. Mov_Acel determina la aceleración: 0x00=instantánea 0xXX progresiva */

void Izquierda()
{
    output_c(input_c()&0b11111011);        //RC2/CCP1/P1A ="0"
    output_b(input_b()&0b11111101);        //RB1/P1C ="0"
    PSTRCON=0b00011010;                    //Salida PWM por RB4/P1D y RB2/P1B
    if(Mov_Acel != 0)                    //Aceleración instantánea ??
        Velocidad();                    //No, progresiva
    else                                //Si, instantánea
        {
        Mov_Actual=Mov_Vel;                //Ajusta nueva velocidad actual
        CCP_1_low=Mov_Vel;                //Ajustar el ciclo útil de forma instantánea
        }
}

/**************************************************************************************************
Derecha: Activa motores M1 y M2 en movimiento diferencial para producir un giro a la derecha.
La velocidad se establece en Mov_Vel. Mov_Acel determina la aceleración: 0x00=instantánea 0xXX progresiva */

void Derecha()
{
    output_b(input_b()&0b11101011);        //RB2/P1B y RB4/P1D ="0"
    PSTRCON=0b00010101;                    //Salida PWM por RC2/CCP1/P1A y RB1/P1C
    if(Mov_Acel != 0)                    //Aceleración instantánea ??
        Velocidad();                    //No, progresiva
    else                                //Si, instantánea
        {
        Mov_Actual=Mov_Vel;                //Ajusta nueva velocidad actual
        CCP_1_low=Mov_Vel;                //Ajustar el ciclo útil de forma instantánea 
        }
}
Esperoque te ayude.

Suerte.
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.