Aqui te dejo el codigo, durante este fin de semana ya habia hecho cambios que me has puesto aqui, de todas formas gracias; he hecho mas cambios, aunque no todos los que me has puesto porque sino no funciona correctamente; es decir, como se desea!!
Gracias de nuevo por tu interes y ayuda!!!!
Haber si se puede pulir aun mas!!
*****************************************************
#include <16f873.h>
#device adc=10
#include <stdlib.h>
#fuses XT, NOPROTECT, NOWDT, NOPUT, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8)
#zero_ram
float KP;
float errorKP;
int opcion;
int duty, dutygenerado, dutycorregido;
int16 error;
int16 pulsos;
int16 interrupcion;
int16 velocidad;
int16 recibido;
float dato;
char string[8];
int habilitacionVelo, habilitacionDuty, FueraRango;
int32 tiempoReal;
int32 Tiempo;
lazo_proporcional(){
if(recibido > velocidad)
{
error=recibido-velocidad;
errorKP=error*KP;
dutygenerado=(errorKP*100.0)/3700.0;
dutycorregido=duty+dutygenerado;
if(dutycorregido>100)
{
set_pwm1_duty(100);
duty=100;
dutygenerado=0;
}
if(dutycorregido<20)
{
set_pwm1_duty(20);
duty=20;
dutygenerado=0;
}
if(dutycorregido<=100 && dutycorregido>=20)
{
set_pwm1_duty(dutycorregido);
duty=dutycorregido;
dutycorregido=0;
dutygenerado=0;
}
dutycorregido=0;
}
if(recibido < velocidad)
{
error=velocidad-recibido;
errorKP=error*KP;
dutygenerado=(errorKP*100.0)/3700.0;
dutycorregido=abs(duty-dutygenerado);
if(dutycorregido>100)
{
set_pwm1_duty(100);
duty=100;
dutygenerado=0;
}
if(dutycorregido<20)
{
set_pwm1_duty(20);
duty=20;
dutygenerado=0;
}
if(dutycorregido<=100 && dutycorregido>=20)
{
set_pwm1_duty(dutycorregido);
duty=dutycorregido;
dutygenerado=0;
}
dutycorregido=0;
}
}
Contr_Velocidad(){
habilitacionDuty=0;
gets(string);
recibido=atol(string);
if(recibido==5000 || recibido==5001)
{
reset_cpu();
}
else
{
if(recibido>=800 && recibido<=3700)
{
habilitacionVelo=1;
FueraRango=0;
}
else
{
printf("Rango 800-3700 r.p.m."
;
FueraRango=1;
}
}
}
Contr_duty_cycle(){
habilitacionVelo=0;
gets(string); //recibo la cadena
recibido=atol(string); //la convierto la cadena a entero
if(recibido==5000 || recibido==5001) //si se envia cualquiera de estos dos numeros se resetea el PIC, reset por software
{
reset_cpu();
}
else
{
if(recibido>=20 && recibido<=100)
{
duty=recibido;
set_pwm1_duty(duty); //El caracter ascii recibido pasado a entero
//establecido como ciclo de trabajo
habilitacionDuty=1; //flag pata habilitar el contaje de los pulsos de velocidad del optoacoplador
}
else
{
printf("Rango 20-100 duty cycle"
;
}
}
}
#int_RTCC //se determina la funcion de la interrupcion
RTCC_isr()
{
if(habilitacionVelo==1 || habilitacionDuty==1)
{
tiempoReal++; //se suma a una variable que computa el tiempo transcurrido
pulsos=get_timer1(); //se obtiene el valor del contador timer1
interrupcion++; //se suma en uno el flag de interrupcion
if(interrupcion==100) //cuando se llega a 100, es decir, 1 segundo, 100*10ms=1000ms=1seg; se introduce en la funcion
{
velocidad=pulsos*15; //sacamos la velocidad con una regla de tres
if(habilitacionVelo==1 && FueraRango==0)
{
lazo_proporcional();
}
printf("%lu ",velocidad); //tambien puerto serie
printf("%u ",duty); //imprimo el duty para saber cual nos ha generado
Tiempo=tiempoReal*0.01; //calculo el tiempo en segundos trnascurrido
printf("%lu ", Tiempo); //imprimo el tiempo
interrupcion=0; //se inicializa de nuevo el flag de interrupcion para que vuelva a contar 100 interrupciones
set_timer1(0); //se inicializa tambien el contador
set_rtcc(178); //se introduce de nuevo el valor del temporizador de interrupcion
}
else
{
set_rtcc(178);
set_timer1(pulsos);
}
}
}
main()
{
enable_interrupts(GLOBAL); //se habilitan interrupcion general
enable_interrupts(INT_RTCC); //habilita int. del timer0
setup_timer_0 ( RTCC_INTERNAL | RTCC_DIV_128); //se configura el timer0 como temporizador y una báscula de 128
set_rtcc(178); //10ms -> 10000us -> 10000/128=78 -> 255-78=177 se le inserta el tiempo a contar, se suma uno
duty = 0; //se inicializa el duty en cero
setup_ccp1(CCP_PWM); //Se habilita el pwm 1
setup_timer_2(T2_DIV_BY_16, 99, 1); //Se establece el valor de la frecuencia de 620Hz(1,6 ms el periodo) para el PWM
set_pwm1_duty(duty); //se manda el duty al PWM
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1); //se configura el timer1 como contador, de pulsos externos y de báscula 1
set_timer1(0); //se inicializa el contador en cero
interrupcion=0; //se inicializan los flags
habilitacionVelo=0, habilitacionDuty=0;
tiempoReal=0;
Tiempo=0;
dutygenerado=0;
dutycorregido=0;
error=0;
errorKP=0;
FueraRango=0;
/******************************************* Constante KP************************************************/
KP=1; //la constante del control proporcional
/********************************************************************************************************/
while(true)
{
//el programa principal que estaria haciendo, esperando a la interrupcion del timer0
gets(string);
opcion=atoi(string); //Usa la función ATOI para pasarlo a entero
switch (opcion) { //case para entrar en un codigo u otro
case 1: //recibido duty cycle se controla mediante duty cycle con un rango
while(true)
{
Contr_duty_cycle();
}
break;
case 2: //recibido velocidad se controla mediante velocidad con un rango
while(true)
{
Contr_Velocidad();
}
break;
default:
reset_cpu();
} //fin del "CASE"
}
}