/*
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
}
}