TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: daltonico82 en 25 de Mayo de 2011, 18:33:38

Título: XOR en CCS
Publicado por: daltonico82 en 25 de Mayo de 2011, 18:33:38
Hola a todos:

Intento realizar una O-exclusiva con la intención de cambiar el estado (de 0 a 1, o de 1 a 0) del pin 0 del puerto D. No compila:

 if (valor[0]>S0Y1)
         {
         PORTD=(PORTD)ˆˆ(0X01);
         }

Gracias
Título: Re: XOR en CCS
Publicado por: bmb en 25 de Mayo de 2011, 18:46:59
Hola daltonico82, para el XOR utiliza un solo signo ^

PORTD=(PORTD)^(0X01);

o así:

PORTD^=(0X01);


Saludos!

Edito: No son necesarios los paréntesis en ninguno de los dos casos...
Título: Re: XOR en CCS
Publicado por: daltonico82 en 25 de Mayo de 2011, 19:14:50
Gracias por responder!!!

No me sirvió para lo que quiero. Explico: pretendo cambiar el estado del D0 sin modificar los demás pines del puerto. He definido el puerto D del siguiente modo:

#use fast_io(D)
........
........
#byte PORTD = 0X08
........
........
#bit D0=PORTD.0
#bit D1=PORTD.1
#bit D2=PORTD.2

Con el consejo de bmb ya me compila pero no va. Devería funcionar ya que por un lado D0 al hacer una XOR con 1: D0=0 XOR 1==>1     y      D0=1 XOR 1==>0

También se me ocurre hacerlo:

output_toggle(D0);

pero tampoco funciona.....

Título: Re: XOR en CCS
Publicado por: Cryn en 25 de Mayo de 2011, 19:23:14
o puedes hacer también:

D0^=1;

aunque la funcion toggle debería funcionar
Título: Re: XOR en CCS
Publicado por: maunix en 25 de Mayo de 2011, 19:46:56
Gracias por responder!!!

No me sirvió para lo que quiero. Explico: pretendo cambiar el estado del D0 sin modificar los demás pines del puerto. He definido el puerto D del siguiente modo:

#use fast_io(D)
........
........
#byte PORTD = 0X08
........
........
#bit D0=PORTD.0
#bit D1=PORTD.1
#bit D2=PORTD.2

Con el consejo de bmb ya me compila pero no va. Devería funcionar ya que por un lado D0 al hacer una XOR con 1: D0=0 XOR 1==>1     y      D0=1 XOR 1==>0

También se me ocurre hacerlo:

output_toggle(D0);

pero tampoco funciona.....



Cuando hablas de que no te funciona... te referis a:

1. no te compila
2. compila pero en el simulador no anda
3. compila, en el simulador anda pero en el hard no
4. probas directo en el hard y no anda

Título: Re: XOR en CCS
Publicado por: daltonico82 en 26 de Mayo de 2011, 05:21:54
Hola.

Utilizo CCS y compila bien. No anda en el hard ya que lo pruebo directamente en la placa de desarrollo. Voy a revisar unas cuantas  cosas y la parte del programa en que lo utilizo ya que realice un programa sencillo donde en un while(1) hacia parpadear un led por este método y sí funciono. Ahora estoy en el trabajo.... cuando salga pruebo y si sigo sin hacerlo funcionar lo cuelgo...

Saludos
Título: Re: XOR en CCS
Publicado por: maunix en 26 de Mayo de 2011, 08:30:12
Hola.

Utilizo CCS y compila bien. No anda en el hard ya que lo pruebo directamente en la placa de desarrollo. Voy a revisar unas cuantas  cosas y la parte del programa en que lo utilizo ya que realice un programa sencillo donde en un while(1) hacia parpadear un led por este método y sí funciono. Ahora estoy en el trabajo.... cuando salga pruebo y si sigo sin hacerlo funcionar lo cuelgo...

Saludos

¿Probaste simularlo en el MPLAB?
¿Para que pic lo estas haciendo?
¿Pones algún retardo como para poder 'ver' el parpadeo? Si no hay retardo entre xors, el parpadeo será tan rápido que tu ojo no lo podrá ver

Título: Re: XOR en CCS
Publicado por: daltonico82 en 26 de Mayo de 2011, 08:54:10
Nunca utilicé MPLAB. Quizás vaya siendo hora...
Empleo un 16f877.
Lo del parpadeo lo hice con otro programa y sí pongo un retardo de 500 ms.
Título: Re: XOR en CCS
Publicado por: maunix en 26 de Mayo de 2011, 09:27:45
Nunca utilicé MPLAB. Quizás vaya siendo hora...
Empleo un 16f877.
Lo del parpadeo lo hice con otro programa y sí pongo un retardo de 500 ms.

Podes subir el código completo?
En lo poco que escribiste veo qeu utilizas el puerto D. ¿Tenés desactivado el PSP (Parallel Slave Port) ?
Título: Re: XOR en CCS
Publicado por: daltonico82 en 26 de Mayo de 2011, 10:34:05
Hola de nuevo, gracias por ser tan atento.

Este es el código dónde intento hacer la XOR:

Código: [Seleccionar]
#include <16f877.h>
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP,NOCPD,NOWRT
#use delay(clock=20000000)
#use RS232 (baud=38400, bits=8,parity=N, xmit=PIN_C6, rcv=PIN_C7)

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)                   
#use fast_io(D)                   
#use fast_io(E)                   

#byte PORTA = 0X05
#byte PORTB = 0X06
#byte PORTC = 0X07                     
#byte PORTD = 0X08
#byte PORTE = 0X09

#bit D0=PORTD.0
#bit D1=PORTD.1
#bit D2=PORTD.2

int SX1=0X2B;//coordenadas max y min: X
int SX2=0X61;

int S0Y1=0X26;//coordenadas max y min: y TECLA S0
int S0Y2=0x3C;

int S1Y1=0X40;//coordenadas max y min: y TECLA S1
int S1Y2=0x59;

int S2Y1=0X5B;//coordenadas max y min: y TECLA S2
int S2Y2=0x73;

int1 Xok=0;
int caso=0;
int lectura=0;
int valor[4];
int i=0;
int1 flag=0;

#int_rda
void RDA_isr()
{
           
      if(kbhit())
      {
        lectura=getc();
        valor[i]=lectura;
        i++;
         if(i==4)
         {
              flag=1;
              i=0;
         }
      }
}



 

void main()
{
   delay_ms(50);
   SET_TRIS_A (0xFF);
   SET_TRIS_B (0x0F);
   SET_TRIS_C (0x80);
   SET_TRIS_D (0X00);
   /*for(i=0;i<4;i++)
      {
         valor[i]=0;   
      }*/
   //flag=0;
   //lectura=0x00;
   PORTD=0X00;
   //int e=0;
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   //delay_ms(300);
   
   while(true)
      {
        //delay_ms(500);
        //D0^=1;
         if(flag==1)
         {
     
  if (valor[2]<(SX2))//las X
  {
  if (valor[2]>(SX1))
  {
  Xok=1;
  }
  }
 
  if (Xok==1)
         {
         if (valor[0]<S0Y2)
         {
         if (valor[0]>S0Y1)
         {
         //PORTD=(PORTD)^(0x01);
         D0^=1;
        //output_toggle(D0);
         }
         }
         }

if (Xok==1)
         {
         if (valor[0]<S1Y2)
         {
         if (valor[0]>S1Y1)
         {
         //output_toggle(D1);
         PORTD=0X02;
         delay_ms(1000);
         PORTD=0X00;
         }
         }
         }

if (Xok==1)
         {
         if (valor[0]<S2Y2)
         {
         if (valor[0]>S2Y1)
         {
         //output_toggle(D2);
         PORTD=0X04;
         delay_ms(1000);
         PORTD=0X00;
         }
         }
         }


       
       
       
      }
}
}
Título: Re: XOR en CCS
Publicado por: maunix en 26 de Mayo de 2011, 10:53:28
Suponiendo que le envias la info correcta por la usart y que el baudeaje este bien ,etc.

Te sugiero usar una variable intermedia, no el portd directamente.

Por ej. 

MIPORTD ^= 1;  (esto invierte todo el puerto por supuesto).
PORTD = MIPORTD;

y siempre trabaja con MIPORTD y fijate si así te funciona.

Lo mismo podría ser MIPORTD una variable de bit y que se la asignes al pin D0.

Fijate y luego me comentas

Título: Re: XOR en CCS
Publicado por: bmb en 26 de Mayo de 2011, 11:30:19
... cambiar el estado (de 0 a 1, o de 1 a 0) del pin 0 del puerto D...

Si la intención es cambiar de estado un pin del puerto D en CCS, esto: output_toggle(D0); no te va a funcionar ya que output_toggle() es una macro interna de CCS y solo te va a funcionar si pones allí uno de los pines declarados en el archivo .h, por ejemplo output_toggle(PIN_D1).  Para invertir el estado de un pin en CCS, también puedes usar por ejemplo:

Código: C
  1. if (valor[0]>S0Y1)
  2.   {
  3.       if(bit_test(PORTD,1))
  4.          bit_clear(PORTD,1);
  5.       else
  6.          bit_set(PORTD,1);
  7.   }

O ya que tienes declarados los pines del puerto D, puedes también:

Código: C
  1. if (valor[0]>S0Y1)
  2.   {
  3.       if(D1)
  4.          D1 = 0;
  5.       else
  6.          D1 = 1;
  7.   }

Saludos!

EDITO: Cambio por un error en bit_test...
Título: Re: XOR en CCS
Publicado por: Suky en 26 de Mayo de 2011, 11:44:49
Estoy de acuerdo que aproveche la función implementada, pero igualmente sirve entender que se puede utilizar la otra forma, que dependiendo de la arquitectura es lo mismo.

Dado que en un 16F, realizar output_toggle(PIN_A2) lleva a que el compilador genere las mismas instrucciones que PORTA^=0x04;  Ahora en un 18F no es lo mismo, ya que output_toggle(PIN_A2) utiliza la instrucción BTG de assembler, y en "C" lo correcto sería LATA=LATA^0x04; que genera lo mismo que en un 16F :)


Saludos!
Título: Re: XOR en CCS
Publicado por: maunix en 26 de Mayo de 2011, 11:53:57
Estoy de acuerdo que aproveche la función implementada, pero igualmente sirve entender que se puede utilizar la otra forma, que dependiendo de la arquitectura es lo mismo.

Dado que en un 16F, realizar output_toggle(PIN_A2) lleva a que el compilador genere las mismas instrucciones que PORTA^=0x04;  Ahora en un 18F no es lo mismo, ya que output_toggle(PIN_A2) utiliza la instrucción BTG de assembler, y en "C" lo correcto sería LATA=PORTA^0x04; que genera lo mismo que en un 16F :)

En realidad mas allá de la función embebida que vaya uno a saber qué hace jaja, mi pregunta iba justamente a que no es lo mismo querer que la salida cambie a hacer un toggle de lo que leemos del puerto y luego cambiarlo...si lo que queremos es que lo que cambie sea la salida

Por ej suky, tu código puede ser erróneo en un 18F, ya que la salida del latch puede ser diferente a la entrada, lo mismo en pic16.  Por eso le sugerí que use una variable auxiliar o "shadow registers" como le dicen los yankies a esta operatoria.

Ademas leer un solo "bit", internamente es igual a leer el puerto completo, por ello hay que tener cuidado cuando trabajamos con puertos de E/S.  

Justamente el portA que para la mayoría de los pics tiene puerto analógico, leerlo digitalmente nos traerá todos ceros, entonces si queremos modificarlo de esa forma, solo lograremos que siempre esté el mismo valor en la salida

En los 18F, el toggle de una salida se debe realizar sobre la misma salida, sobre el registro LATCHx, no sobre PORTx.  

Ni hablar si el toggle debe ser rápido, ahi entran en juego aspectos de la impedancia de lo que hay conectado por fuera del pin, etc.  Por ello existen los LATx , para justamente evitar este enorme problema que tenian los 16F


Título: Re: XOR en CCS
Publicado por: Suky en 26 de Mayo de 2011, 12:08:53
 :D En el caso del 16F, CCS hace exactamente eso al realizar output_toggle  ;-)
Título: Re: XOR en CCS
Publicado por: maunix en 26 de Mayo de 2011, 12:18:25
:D En el caso del 16F, CCS hace exactamente eso al realizar output_toggle  ;-)

Bueno, está mal ji... otra razón más para no usarlo jajajaja
 :afro:
Título: Re: XOR en CCS
Publicado por: daltonico82 en 26 de Mayo de 2011, 18:36:05
Gracias colegas!!! Entre vuestras respuestas magistrales, seguro está la solución ó más de una solución.

Sigue sin funcionar bien. He dudado del trabajo anterior pero las coordenas que testeo llegan bien, lo comprobe con el programa que os dejo, en este activo el pin uno cuando me llegan unas coordenadas, el pin 2 con otras y así con el pin 3 del puerto D...... sólo que yo lo quiero activar y desactivar una salida del puerto al llegarme unas coordenadas concretas.... un interruptor

Código: [Seleccionar]
if (Xok==1)
         {
         if (valor[0]<S0Y2)
         {
         if (valor[0]>S0Y1)
         {
         //PORTD=(PORTD)^(0x01);
         //D0^=1;
        //output_toggle(D1);
        //MIPORTD^=1;
        //D0=MIPORTD;
        /*if(D1)
        D1 = 0;
        else
        D1 = 1;*/
        /*if(cansado==0)
        {
        PORTD=0X01;
        cansado=1;
        }
        else
        {
        PORTD=0X00;
        cansado=0;
        }*/
       
      PORTD=0X01;
     


         }
         }
         }
       
         

if (Xok==1)
         {
         if (valor[0]<S1Y2)
         {
         if (valor[0]>S1Y1)
         {
         //output_toggle(D1);
         PORTD=0X02;
         
         }
         }
         }
         
         
if (Xok==1)
         {
         if (valor[0]<S2Y2)
         {
         if (valor[0]>S2Y1)
         {
         //output_toggle(D2);
         PORTD=0X04;
       
         }
         }
         }
Título: Re: XOR en CCS
Publicado por: maunix en 26 de Mayo de 2011, 22:10:04
Sigue sin funcionar bien. He dudado del trabajo anterior pero las coordenas que testeo llegan bien, lo comprobe con el programa que os dejo, en este activo el pin uno cuando me llegan unas coordenadas, el pin 2 con otras y así con el pin 3 del puerto D...... sólo que yo lo quiero activar y desactivar una salida del puerto al llegarme unas coordenadas concretas.... un interruptor


Y cuando te llegan esas coordenadas concretas, la salida cambia ahora al valor esperado q pusiste ahora? mas allá que no haga el toggle...

otra consulta, entre coordenada y coordenada hay un tiempo prudente? podes ver el cambio o es muy rápido?

probaste hacer uso de una variable auxiliar como te dije?
Título: Re: XOR en CCS
Publicado por: daltonico82 en 27 de Mayo de 2011, 08:06:07
Ahora con este programa.... el puerto cambia de 0x01 a 0x02 o a 0x04 sin problemas cuado recibo las distintas coordenadas.

Probé con la variable intermedia pero no funcionó.... sigo dádole vueltas

Título: Re: XOR en CCS
Publicado por: maunix en 27 de Mayo de 2011, 08:32:54
Ahora con este programa.... el puerto cambia de 0x01 a 0x02 o a 0x04 sin problemas cuado recibo las distintas coordenadas.

Probé con la variable intermedia pero no funcionó.... sigo dádole vueltas


Mostrame el código donde usas la variable intermedia así lo vemos en conjunto; si no te anda el toggle pero si te muestra el led fijo cuando recibe las coordenadas entonces o bien recibis muchas veces la info (o el codigo la interpreta muchas veces) y hace el toggle más de una vez  o bien estas haciendo mal el toggle

Título: Re: XOR en CCS
Publicado por: Suky en 27 de Mayo de 2011, 10:57:44
Algunas cosas a mejorar, si tienes valores que van ser constantes y no van a ser modificados conviene definirlos mediante la directiva #define o colocarle const como atibuto:

Código: [Seleccionar]
#define SX1 0X2B
const int SX1=0X2B;

Luego, cuando ocurre la interrupción por recepción de datos, significa que ha llegado el bit stop, así que preguntar si hay datos es redundante, el if(kbhit()) es innecesario.

Se puede reorganizar los if de la siguiente manera:
Código: [Seleccionar]
  while(true){
         if(flag==1)
{    
flag=0;
if((valor[2]<(SX2))&&(valor[2]>(SX1)))//las X
{
Xok=1;
}
  
if (Xok==1)
{
if((valor[0]<S0Y2)&&(valor[0]>S0Y1))
{
output_toggle(D0);
//delay_ms(500);
}

if((valor[0]<S1Y2)&&(valor[0]>S1Y1))
{
PORTD=0X02;
delay_ms(1000);
PORTD=0X00;
}

if((valor[0]<S2Y2)&&(valor[0]>S2Y1))
{
PORTD=0X04;
delay_ms(1000);
PORTD=0X00;
}
Xok=1;
}
        }
}


Lo más importante, te falta resetear las banderas que ya han sido tratadas, sino salta nuevamente sin ocurrir ningun evento.


Saludos!

Título: Re: XOR en CCS
Publicado por: daltonico82 en 27 de Mayo de 2011, 13:48:38
HOLA!!! :oops: :oops: :oops:

Empleo las mejoras o necesarias que me indicas Suky.... pero si coloco el flag=0; lo que me pasa es lo siguiente:

Si pulso tecla 0 por ejemplo no pasa nada. Si a continuación pulso tecla 0 de nuevo se activa D0. Si la segunda vez pulso tecla 1 por ejemplo se activa D0, luego en la proxima pulsación sea cual sea la tecla se activaría D1(que correspondia con la pulsación de tecla 1) y asi sucesivamente....es decir hace lo deseado una pulsación después.

Sigo con esto, ahora y lo del toggle... El código está asi:

Código: [Seleccionar]
#include <16f877.h>
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP,NOCPD,NOWRT
#use delay(clock=20000000)
#use RS232 (baud=38400, bits=8, parity=N, xmit=PIN_C6, rcv=PIN_C7)

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)                   
#use fast_io(D)                   
#use fast_io(E)                   

#byte PORTA = 0X05
#byte PORTB = 0X06
#byte PORTC = 0X07                     
#byte PORTD = 0X08
#byte PORTE = 0X09

#bit D0=PORTD.0
#bit D1=PORTD.1
#bit D2=PORTD.2

const int SX1=0X2B;//coordenadas max y min: X
const int SX2=0X61;

const int S0Y1=0X26;//coordenadas max y min: Y_TECLA S0
const int S0Y2=0x3C;

const int S1Y1=0X40;//coordenadas max y min: Y_TECLA S1
const int S1Y2=0x59;

const int S2Y1=0X5B;//coordenadas max y min: Y_TECLA S2
const int S2Y2=0x73;

int1 Xok=0;
int lectura=0;
int valor[4];
int i=0;
int1 flag=0;

#int_rda
void RDA_isr()
{
           
        lectura=getc();
        valor[i]=lectura;
        i++;
         if(i==4)
         {
              flag=1;
              i=0;
         }
     
}

void main()
{
   
   delay_ms(50);//incialización controlador
   SET_TRIS_A (0xFF);
   SET_TRIS_B (0x0F);
   SET_TRIS_C (0x80);
   SET_TRIS_D (0X00);
   /*for(i=0;i<4;i++)
      {
         valor[i]=0;   
      }*/
   //flag=0;
   //lectura=0x00;
   PORTD=0X00;
   int1 contador=0;
   int1 MIPORTD=0;
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   
   
    while(true){
         if(flag==1)
      {     
         //flag=0;
         
         if((valor[2]<(SX2))&&(valor[2]>(SX1)))//las X; las 3 teclas en este caso están alineadas verticalmente==>mismas coordenadas X
         {
            Xok=1;
         }
         
         if (Xok==1)
         {
            if((valor[0]<S0Y2)&&(valor[0]>S0Y1))
            {
               //output_toggle(D0);
               //delay_ms(500);
               PORTD=0X01;
             
            }
           
           
            if((valor[0]<S1Y2)&&(valor[0]>S1Y1))
            {
               PORTD=0X02;
               
            }
           
           
            if((valor[0]<S2Y2)&&(valor[0]>S2Y1))
            {
               PORTD=0X04;
               
            }
           
            Xok=0;
         }
       
     
   }
   
}//while(1)
}//main()
Título: Re: XOR en CCS
Publicado por: Suky en 27 de Mayo de 2011, 13:56:26
Estas seguro que te envía 4 bytes por tecla pulsada? No tengo idea de donde provienen esos datos, por eso la pregunta
Título: Re: XOR en CCS
Publicado por: maunix en 27 de Mayo de 2011, 14:23:34
Sigo con esto, ahora y lo del toggle... El código está asi:

Pero salvo que esté leyendo muy apuradamente pero no veo que hayas un toggle en ese código.

Porque no haces lo siguiente

1. Inicia una variable uqe se llame toggle con 0 --> toggle=0
2. Cuando recibis la coordenada que esperas [1] para hacer el toggle, tomá una variable que se llame toggle y hacela modificarse así toggle ^= 1 o si queres podrias hacer toggle = ~toggle o como se te ocurra, hay muchas formas de hacer que cambie
3. PIN de SALIDA = toggle ; donde pin de salida es el que queres que se active/desactive.  O bien algo más sencillo sería

Código: [Seleccionar]
if (toggle) PINSALIDA=1; else PINSALIDA=0;
Espero te sirva de ayuda




Nota
 [1] En este punto coincido con suky que no sabemos bien que recibís porque hablas de 1 sola tecla pero en el código esperas 4 bytes
Título: Re: XOR en CCS
Publicado por: daltonico82 en 27 de Mayo de 2011, 19:17:18
Bien, os pido disculpas por no haber explicado bien: el controlador  envía 4 bytes. Trabajo con el valor[0] y valor[2] que son las coordenadas X e Y. Esto funciona bien pues soy capaz de comprobar si estoy o no pulsando una zona del panel táctil y en consecuencia, por ejemplo poner PORTD=0XFF;

Hice esto, y pasa algo raro: si pulso el boton 1 (donde puse el toggle para probar) se activa D0, pero si vuelvo a pulsar el boton 1 no hace nada. Si pulso muchas veces en alguna ocasión se desactiva:

Código: [Seleccionar]
[/covoid main()
{
   
   delay_ms(50);//incialización controlador
   SET_TRIS_A (0xFF);
   SET_TRIS_B (0x0F);
   SET_TRIS_C (0x80);
   SET_TRIS_D (0X00);
   /*for(i=0;i<4;i++)
      {
         valor[i]=0;   
      }*/
   //flag=0;
   //lectura=0x00;
   PORTD=0X00;
   int1 contador=0;
   int1 MIPORTD=0;
   int1 toggle=0;
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   
   
    while(true)
    {
         if(flag==1)
      {     
         //flag=0;
         
         if((valor[2]<(SX2))&&(valor[2]>(SX1)))//las X; las 3 teclas en este caso están alineadas verticalmente==>mismas coordenadas X
         {
            Xok=1;
         }
         
         if (Xok==1)
         {
            if((valor[0]<S0Y2)&&(valor[0]>S0Y1))//pulso boton 1
            {
               //output_toggle(D0);
               //delay_ms(500);
               toggle ^= 1;
               D0=toggle;
             
            }
           
           
            if((valor[0]<S1Y2)&&(valor[0]>S1Y1))//pulso boton 2
            {
               PORTD=0X02;
               
            }
           
           
            if((valor[0]<S2Y2)&&(valor[0]>S2Y1))//pulso boton 3
            {
               PORTD=0X04;
               
            }
           
            Xok=0;
         }
       
     
   }
   
}//while(1)
}//main()
de]
Título: Re: XOR en CCS
Publicado por: Suky en 27 de Mayo de 2011, 19:32:09
Lo que estoy seguro es que necesitas resetear flag a 0 después de tratar los datos. De esa manera distingues entre las distintas tramas, sino desde la primera vez que pulses ingresará a trabajar con los datos en valor[] y puede que estés recibiendo otros...

Lo que se puede realizar por si se reciben muchos datos a la vez es:

Código: [Seleccionar]
void RDA_isr()
{
           
        lectura=getc();
        if(flag==0){
        valor[i]=lectura;
        i++;
         if(i==4)
         {
              flag=1;
              i=0;
         }
     }     
}

Y colocar flag a 0 al final del if() del bucle principal. Entonces, si estas trabajando con los datos recibidos anteriormente no existe la posibilidad de irlos reemplazando antes de tratarlos.


Saludos!
Título: Re: XOR en CCS
Publicado por: daltonico82 en 31 de Mayo de 2011, 15:44:58
HOLA A TODOS!!!

Gracias por su ayuda. Creo que en este hilo se muestran unas cuantas formas de alternar de uno a cero el pin de un puerto. Al final todas o casi todas la formas que me habeis comentado han funcionado, por lo tanto... mi programa es el que daba problema.

A parte de que me ayudasteis a extructurarlo, me llevasteis a hacer pruebas que no habia tenido en cuenta, me recordasteis la importancia de rsetear banderas y variables.... logré hacerlo funcionar.... poniendo un retardo de 50 ms.

Coloco aquí varias formas en las que funciono el "toggle_pin" o la "XOR del puerto" :

 if ((Xok==1)&&(valor[0]<S0Y2)&&(valor[0]>S0Y1))//opcion 1
         {
         Xok=0;
         D0^=1;
         }

if ((Xok==1)&&(valor[0]<S0Y2)&&(valor[0]>S0Y1))//opcion2
         {
         Xok=0;
         PORTD^=(0X01);
         }

if ((Xok==1)&&(valor[0]<S0Y2)&&(valor[0]>S0Y1))//opcion 3
         {
         Xok=0;
         output_toggle(PIN_D0);
         }

if ((Xok==1)&&(valor[0]<S1Y2)&&(valor[0]>S1Y1))//opcion 4
         {
         Xok=0;
         toggle1 = ~toggle1;
         D1=toggle1;
         }

 if ((Xok==1)&&(valor[0]<S0Y2)&&(valor[0]>S0Y1))//opcion 5
         {
         Xok=0;
         toggle = ~toggle;
         if(toggle) D0=1;
         else D0=0;
         }
         
     
Ahora os dejo el código como lo tengo en estos momentos.Lo extructuraré  más pero ahora el siguiente paso es controlar la comunicación rs232 pero para enviar datos y conseguir emitir un "pitido" para una pulsación válida en la touch. Sobre este tema preguntaré en el hilo "mil vueltas sobre una secilla comunicacion serie", nos vemos por alli. Gracias por la estimable gran ayuda!!! :mrgreen: :D :g) ;-)

Código:
Código: [Seleccionar]
#include <16f877.h>
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP,NOCPD,NOWRT
#use delay(clock=20000000)
#use RS232 (baud=38400, bits=8, parity=N, xmit=PIN_C6, rcv=PIN_C7)
//#use RS232 (baud=38400, xmit=PIN_C6, rcv=PIN_C7)

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)                   
#use fast_io(D)                   
#use fast_io(E)                   

#byte PORTA = 0X05
#byte PORTB = 0X06
#byte PORTC = 0X07                     
#byte PORTD = 0X08
#byte PORTE = 0X09

#bit D0=PORTD.0
#bit D1=PORTD.1
#bit D2=PORTD.2

const int SX1=0X2B;//coordenadas max y min: X
const int SX2=0X61;

const int S0Y1=0X26;//coordenadas max y min: Y_TECLA S0
const int S0Y2=0x3C;

const int S1Y1=0X40;//coordenadas max y min: Y_TECLA S1
const int S1Y2=0x59;

const int S2Y1=0X5B;//coordenadas max y min: Y_TECLA S2
const int S2Y2=0x73;

int1 Xok=0;
int lectura=0;
int valor[4];
int i=0;
int1 flag=0;

#int_rda

void RDA_isr()
{
           
        lectura=getc();
        valor[i]=lectura;
        i++;
         if(i==4)
         {
              flag=1;
              i=0;
         }
     
}

/*void RDA_isr()
{
         
         lectura=getc();
         if(flag==0){
           valor[i]=lectura;
           i++;
            if(i==4)
            {
                 flag=1;
                 i=0;
            }
        }     
} */


void main()
{
   
   delay_ms(50);//incialización controlador
   SET_TRIS_A (0xFF);
   SET_TRIS_B (0x00);
   SET_TRIS_C (0x80);
   SET_TRIS_D (0X00);
 
   setup_adc(ADC_OFF);
   setup_spi(FALSE);
   setup_psp(PSP_DISABLED);
   /*for(i=0;i<4;i++)
      {
         valor[i]=0;   
      }*/
   //flag=0;
   //lectura=0x00;
   PORTD=0X00;
   PORTB=0X00;
   
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   
   
    while(true)
    {
         if(flag==1)
      {   
     
     delay_ms(50);
         flag=0;
         
         if((valor[2]<(SX2))&&(valor[2]>(SX1)))//las X; las 3 teclas en este caso están alineadas verticalmente==>mismas coordenadas X
         {
            Xok=1;
         }
         
         if ((Xok==1)&&(valor[0]<S0Y2)&&(valor[0]>S0Y1))
         {
         Xok=0;
         output_toggle(PIN_D0);
         }
         
         if ((Xok==1)&&(valor[0]<S1Y2)&&(valor[0]>S1Y1))
         {
         Xok=0;
         output_toggle(PIN_D1);
         }
   
         if ((Xok==1)&&(valor[0]<S2Y2)&&(valor[0]>S2Y1))
         {
         Xok=0;
         output_toggle(PIN_D2);
         }

         
   
      }//flag==1
     
   
}//while(1)
}//main()