Autor Tema: TIMER1 No consigo entender que hago mal  (Leído 2760 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
TIMER1 No consigo entender que hago mal
« en: 26 de Noviembre de 2016, 20:17:32 »
Hola llevo ya semanas con lo mismo aunque el "enable" es similar en ambos casos no entiendo porque no funciona en el segundo caso

Timer0 y Timer1 Son para el control de un ascensor

Hay 8 pisos 0 a 7 yo utilizo el 0 como piso B
el 8 significa ninguno
superior a 8 erroneo: varias ubicaciones (ascensor en 2 pisos a la vez) mas de 1 puerta exterior abierta y demas


//LAS PRINCIPALES VARIABLES SON...
//Finales de carreara Fisicos
int8 piso=8;//Finales de carrera para ubicazion de piso de 0 a 7//F.d.c

int8 atea=8;//"atea significa puerta" hace referencia a la puerta.exterior abierta de 0 a 7
//que debe corresponder con el piso donde se encuentra el ascensor

int1 open;//Final de carrera TRUE es puerta.interior hidraulica ABIERTA
int1 itxi;//Final de carrera TRUE es puerta.interior hidraulica CERRADA

//ints1 No fisicas// su estado activa pines correspondientes a tareas especificas
int1 okp=0;//para saber si esta "ocupado" realizando_tarea

//azti[0]=True Ascensor en marcha "activacion"
int1 azti[3]={0,0,0};//azti[1]=False_BAJANDO azti[1]=True_SUBIENDO

int1 hdra[3]={0,0,0};//hdra[0]=TRUE activacion hidraulica puerta.interior
//hdra[1]=TRUE ABRIENDO hidra[1]=FALSE CERRANDO
//(esa puerta.corredera.individual normalmente tienen ascensores en su interior)

int8 llma//"llamada" Pulsadores ya sean de interior o exterior del ascensor interfieren en ella




#INT_TIMER0//Este siempre a de estar activo
void  TIMER0_isr(void){

if(borr<4){  borr++; } else {  borr=0; lcd_putc("\f"); }

lcd_gotoxy(13,4); printf(lcd_putc,"t%utt%u.%u",borr,T1,f);//
lcd_gotoxy(8,1); printf(lcd_putc,"%u,%c,a%u,p%u(%u)",llma,210,atea,piso,okp);//,210);

if(llma!=8){//SE A PEDIDO PISO//si "llamada"=8 hace referencia a no hay llamada
if(llma!=piso){//No se a llegado a el MARCHA
   if(atea==8 && 9>piso){//Normal//Ninguna ateak deberia estar abierta NI estar en varios pisos   
      if(itxi){ //hidraulico deberia estar itxi --
         if(piso!=8){ azti[0]=1; //esta en un piso
         if(llma>piso){  azti[1]=1; }//subir
         else{ azti[1]=0; }//bajar
         } //else{ azti[0]=0; hdra[0]=1; hdra[1]=1; }//llegada PARO & open-hidraulik   
      }else{  azti[0]=0; hdra[0]=1; hdra[1]=0; }//hidraulico  NO!itxi
   }else{ azti[0]=0; }
} else { ///PARO se a llegado
   azti[0]=0;
   if(!open){
   hdra[0]=1; hdra[1]=1;
   } else { hdra[0]=0;
 llma=8; f=1; T1=0;
 //ESTA ENTRADA A Timer1 VA BIEN//////////////////////////////////////////
   clear_interrupt(int_timer1);
   SET_TIMER1(1);
   enable_interrupts(INT_TIMER1);
   }
}   
} //No hay peticion de piso  || OR  se a llegado a su destino
else {  azti[0]=0;
 
 //okp=0;//Para probarlo si pongo aqui okp=0; si entra en Timer_1 siempre que se cumpla el 2º IF
   //pero no puede ser pone siempre el contador T1=0 y nunca sale de su segunda funcion f=2
   
if(!okp){//1º IF//int1 okp se refiere a ocupado
   //2º IF
   if(atea==piso){//Se abre la (puerta exterior corespondiente == al piso donde se encuentra el ascensor)
   okp=1;//Este Ascensor ya esta "okupado=1" <--SOLO SE CUMLE ESTO Y ENTONCES YA NO VUELVE A ENTRAR EN 2º IF
   f=2;//funcion_2º que va a desempeñar Timer_1 //EN ESTE CASO usuario entro se espera cierre atea=8.todas_cerradas
   T1=0;//puesta a 0 de contador de espera
   //ESTA ENTRADA A Timer1 NO SE CUMPLE/////////////////////////////////////////////
   //pero segun el LCD de ambos PICS okp=1 pasa a True pero T1=0; Y f=0 siempre
       clear_interrupt(int_timer1);
       SET_TIMER1(1);
       enable_interrupts(INT_TIMER1); }//delay_ms(2);

 //else{
   }
   //if(!open){ hdra[0]=1; hdra[1]=1; } //hidraulico deberia pasar a open
   //} else { hdra[0]=0; }
   //}
}//PARO no hay peticion
if(!hdra[0]){ ulik=0; } else {
         if(ulik>50){ lcd_gotoxy(3,1); lcd_putc("?"); lcd_gotoxy(6,1);
         if(hdra[1]){ lcd_putc("No_Open!!"); }
         else{ lcd_putc("No_Cierra!!"); } } else { ulik++; }
}
clear_interrupt(int_timer0);
SET_TIMER0(100);
}

#INT_TIMER1  //Este es para realizar labores de espera y cumplido un tiempo normalmente debe desavilitarse a si mismo
void  TIMER1_isr(void){
switch(f){
case 1 ://Tras llegada al piso=llamada se espera que se abra atea=piso
   lcd_gotoxy(1,4); printf(lcd_putc,"%c[%u]%c",127,piso,126);   
   if(atea!=piso){ T1++;//Nadie abre puerta"adecuada" tras llegada
      if(T1>30){
      lcd_gotoxy(1,3); lcd_putc("Nai abre tras llegar");//crt_20
      lcd_gotoxy(1,4); printf(lcd_putc,"?[%u]?No open??      ",piso);//if(T2>X) Tiempo escesivo de espera dar por desocupado al ascensor
         if(T1>60){  T1=0;   f=20; }//"break" desokupar de todas formas
      }else{ if(T1>4){ for(ct=5;T1>ct;ct+=6){ lcd_putc("?"); } } }
   }else{//Apertura de atea en piso=llama=atea
   T1=0;   f=20; }//Ya no es necesario contadorT1 timer1 pasa a 20ºfuncion
break;
case 2 : //si alguien se mete-recientemente se da X opk=1
 lcd_gotoxy(1,3); printf(lcd_putc,"intro%c<%u>",126,piso);
 lcd_gotoxy(1,4); printf(lcd_putc,"%c[%u]%c",126,atea,127); 
T1++; //delay_ms(1000);
if(atea!=8){ //T1++;//Se espera cierre de toda puerta
      lcd_gotoxy(6,4);
      if(T1>30){
      printf(lcd_putc,"se spera %c[%u]%c",126,atea,127);
      }else{ if(T1>4){
      for(ct=5;T1>ct;ct+=6){ lcd_putc("?"); }
      }      }
} else {//se cerro toda ateak
f=3; T1=0;//se spera a k usuario introducido pulse piso"en interior" (nadie del exterior puede llamar)
  clear_interrupt(INT_RB);
enable_interrupts(INT_RB); 
lcd_putc("\f");
}
break;
case 3 :
if(llma!=8){//se spera a k usuario introducido pulse piso"en interior" (nadie del exterior puede llamar)
  lcd_gotoxy(1,3); printf(lcd_putc,"<%c>",211);
      if(T1>30){     
            if(T1<60){
      lcd_putc("?se spera peticion   ");
      lcd_gotoxy(1,3); lcd_putc("Nai pide piso ");//crt_20
            }else{//TIEMPO ESCESIVO desocupar okp=0;
            clear_interrupt(INT_RB);
            disable_interrupts(INT_RB);//ya no se espera peticion interna
            f=20;
            }
      }else{ if(T1>4){ for(ct=5;T1>ct;ct+=6){ lcd_putc("?"); } } }           
} else { f=20; T1=0;  } //REALIZADA PETICION SE SUSPENDE TIMER1
break;
case 20 ://20º funcion
if(atea==8){ //Se espera el cierre de toda ateak//para poder dar como ok.u.p.ado=0 definitivamente
okp=0; llma=8; disable_interrupts(INT_TIMER1); }
break;
default :
okp=1; lcd_gotoxy(1,3);  printf(lcd_putc,"ErroT1.f=%u ",f);
if(T1<70){ T1++; }
else{ T1=0; f=20; }
break;
}//swit(f)
clear_interrupt(int_timer1);
SET_TIMER1(1);
}


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:TIMER1 No consigo entender que hago mal
« Respuesta #1 en: 27 de Noviembre de 2016, 00:08:45 »
Tus problemas son:

- Te falta un ";" en una de las sentencias de las variables, supongo que al momento de copiar y pegar se fue.
- En las rutinas de interrupciones tenes llamadas a las funciones del LCD ( printf y lcd_gotoxy ), Esto no deberias, ya que ocupa tiempo y al estar en una interrupcion hace que no pueda entrar a las otras interrupciones. Perdiendo todo el sentido de tener una base de tiempo que es el Timer.
- Hay un if que nunca se va a ejecutar, preguntas si es distinto de 8 que entre al if, y adentro de ese if pones otro if preguntando si es igual a 8, lo cual nunca lo va a ser, ya que si entro es por que era distinto.


No hice caso a lo comentado, ya que supongo que es lo que iria. Y que la logica es la correcta y de acuerdo a tu programa.

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re:TIMER1 No consigo entender que hago mal
« Respuesta #2 en: 06 de Diciembre de 2016, 17:46:34 »
Si utilizo el LCD para controlar los pasos Es mi unica manera de ver si los datos mostrados son acordes a lo que pretendo aunque muchas de estas variables no tienen porque mostrarse finalizado el programa. Se que se puede utilizar mejor una ventana de msd2 pero no quiero liar con esto. El if no creo que sea pregunto mucho por !8 pero en variables distintas me parece si no me e perdido

De todas gracias por contestar. Dime podrias decirme simplemente como se le pregunta al Timer si esta activo o no de momento esto me serviria para arreglarlo por mi cuenta creo y perdona por no responder, esta pregunta la tengo en otro apartado de este foro pero al igual que aqui se me olvido -notificar

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:TIMER1 No consigo entender que hago mal
« Respuesta #3 en: 06 de Diciembre de 2016, 17:53:24 »
Voy a suponer que estas usando el PIC16F887

Me fijo en el datasheet y el registro T1CON esta en la direccion 0x10 , y el bit de si esta activo o no es el bit 0 o TMR1ON.

Código: C
  1. #BIT TMR1ON = 0x10.0

Luego en el programa lo usas:

Código: C
  1. // Pregunto si esta activo
  2. if (TMR1ON)
  3. {
  4. }
  5.  
  6. //Lo desactivo y activo:
  7. TMR1ON = 0;
  8. TMR1ON = 1;

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re:TIMER1 No consigo entender que hago mal
« Respuesta #4 en: 06 de Diciembre de 2016, 18:03:23 »
Gracias KIllerjc lo mirare if (TMR1ON) en otro momento se me hace tarde, es para un 18f452


Citar
//Lo desactivo y activo:
TMR1ON = 0;
TMR1ON = 1;
Esta manera de "enable/disable" es ensambler no? se puede implementar aunque el resto este escrito en ccs?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:TIMER1 No consigo entender que hago mal
« Respuesta #5 en: 06 de Diciembre de 2016, 22:22:45 »
Citar
Esta manera de "enable/disable" es ensambler no? se puede implementar aunque el resto este escrito en ccs?

No, eso es C. Aplicando la directiva BIT del CCS.

En XC8 estan definidos los registros y no necesitas la directiva BIT, y podes hacer: T1CONbits.TMR1ON = 0;
Pero como CCS no tiene definidos los registros, ya que su objetivo es aislar al usuario del hardware. tenes que recurrir a esas directivas para hacerlo.
Que imagino que si eso se traduce en ASM a un BSF y BCF

Si hubiera querido que fuera ASM, hubiera realizado:

#asm
    BSF #0x10, #0
    BCF #0x10, #0
#endasm

o algo asi... la sintaxis no es muy clara en el manual de CCS

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re:TIMER1 No consigo entender que hago mal
« Respuesta #6 en: 18 de Diciembre de 2016, 19:22:52 »
Hola respecto al tema inicial -preguntar por trm1on- sigo igual me parece entender que si fuese el caso
#BIT indistintoNombre = 0x10.1 //haria mencion a TMR1CS
pero no es el caso, estoy seguro porque el supuesto TMR1ON se mantiene siempre a False, aunque este timer1 este actuando, esto lo verifico simplemente verificando su incremento de contador. E visto en general que es a partir de 10h. No lo creo aqui con este pic18f452 ya creo haber modificado esta posicion reservada manualmente a la vez que utilize el timer1 y no paso nada o seria todo muy casual es esta otra saber que posiciones ni debo tocar segun lo que utilize, yo siempre utilice lasa primeras por defecto a partir de 0x0000 Tengo esta tabla si pero ocurre lo mismo en el Timer1 Timer0 los dos tienen el TRMxON en el bit0 ¿pero a partir de donde? Yo por instinto lo primero que e mirado es en -memory organizacion pero esta en ingles y hay muchos apartados ¿puedes decirme donde debo ir en este caqso?

* Sin título2.jpg
(190.48 kB, 914x716 - visto 348 veces)

Este datasheet es de la familia 18fxx2 aunque tengo otro en castellano especifico a un 18f452 es mas incompleto

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:TIMER1 No consigo entender que hago mal
« Respuesta #7 en: 18 de Diciembre de 2016, 20:07:48 »
Dije que suponia que usabas un 16F887, si usas ese PIC entonces la direccion es: 0xFCD


#BIT TMR1ON = 0xFCD.0
#BIT TMR1CS = 0xFCD.1

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re:TIMER1 No consigo entender que hago mal
« Respuesta #8 en: 18 de Diciembre de 2016, 21:00:40 »
Gracias por la correpcion en el otro dataset ya vi algo de T1CON a partir de FCDh No supe corregirlo, pero ahora siempre marca True, ciertamente este programa esta muy verde y muy liado con lo que escrivi hace meses no e podido dedicarle mucho tiempo pero no entiendo porque inicialmente me da true poniendo solo esto a modo de prueba antes de que se introduzca en el while(1){//principal }
Código: [Seleccionar]
MAIN(){
setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);//|RTCC_8_bit);///PRESCALER 4
clear_interrupt(int_timer1);
SET_TIMER1(1); //okp=0;
 disable_interrupts(INT_TIMER1); 
   enable_interrupts(GLOBAL); delay_ms(2);
lcd_gotoxy(1,3); 
printf(lcd_putc,"T1.%u",TMR1ON);
delay_ms(1000); lcd_putc("\f");

WHILE{
......
.....
}
}
 
Tengo para rato mucho mas que mirar pero a saber porque inicialmente da TMR1ON=1 desde el principio

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:TIMER1 No consigo entender que hago mal
« Respuesta #9 en: 18 de Diciembre de 2016, 21:04:48 »
el setup_timer_1 ya te lo debe activar...

Hace esto...

Crea una programa con una interrupcion por TMR1, en la interrupcion que cambie el estado de una salida cada 0.5s por ejemplo.
Dentro del while, pregunta por un boton  y hace que cambie el bit TMR1ON, si esta en 0 pase a 1, si esta en 1 que pase a 0.

Es muy sencillo de hacer el programa, pero vas a poder probarlo y verificiar que el timer se detiene.

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re:TIMER1 No consigo entender que hago mal
« Respuesta #10 en: 25 de Diciembre de 2016, 09:34:45 »
No creo Esto ya es un problema a parte mis referencias #BIT lo-que-sea No van bien no solo no controlo los registros del Timer tampoco puedo asignar nombres a los pines escepto a A0-5

De todas este caso esta resuelto tiene que ver mas con lo que digiste inicialmente estoy preguntando por if(puerta!=8) 2 veces pero no dentro del timer0. Todo este jaleo se formo por preguntar esto dentro de main() no otras interreupciones

main{
while{
....
if(puerta!=8){ .....//se abrio puerta exterior de 0 a 7 .... o peor varias
} //okp=1; }ESTO ES LO QUE E QUITADO era por cualquier puerta exterior abierta implica ascensor ocupado + inoperable en //subir o bajar
} }

No importa que Timer0 se cumpla solo cada unos 100ms main() es continuo constante y con solo abrir una puerta exterior ya daba ocupado=true ascensor antes de llegar a Timer0 por eso me parece que esto nunca se cumplia
Código: [Seleccionar]
#INT_TIMER0
void  TIMER0_isr(void){
 if(!okp){//1º IF//int1 okp se refiere a ocupado 
   if(puerta==piso){//2º IF //Se abre la (puerta exterior corespondiente == al piso donde se encuentra el ascensor)
   okp=1;//Este Ascensor ya esta "okupado=1" <--SOLO SE CUMLE ESTO Y ENTONCES YA NO VUELVE A ENTRAR EN 2º IF
   f=2;//funcion_2º que va a desempeñar Timer_1 //EN ESTE CASO usuario entro se espera cierre puertas=8.todas_cerradas
   T1=0;//puesta a 0 de contador de espera
  [size=12pt] //ESTA ENTRADA A Timer1 NO SE CUMPLE[/size]
       clear_interrupt(int_timer1);
       SET_TIMER1(1000);
       enable_interrupts(INT_TIMER1); }//delay_ms(2);
   }
}
//ESTA ENTRADA A Timer1 NO SE CUMPLE Me parece que por una chorrada al estilo "efecto mariposa" ya estaba equivocado de antes ni siquiera entraba en el 1º IF(!OCUPADO) como creia desde principio main() ya puso ocupado=True, Ahora esto al menos ya va


 

anything