Autor Tema: OUTPUT_B sin modificar B0 y B1  (Leído 1834 veces)

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

Desconectado facuver

  • PIC10
  • *
  • Mensajes: 14
OUTPUT_B sin modificar B0 y B1
« en: 22 de Octubre de 2013, 11:50:22 »
Hola,que tal.

 Tengo una duda de como poder mediante un OUTPUT_B() conservar los valores que ya estaban en B0 y B1.

Tengo un motor paso a paso conectados a B2...B5 y utilizo esta función que anda bien. Pero el problemas es que la función también me modifica B0 y B1.
Código: [Seleccionar]
int16 n,i,t;
int t0,p;
const int pasos[4]={0b00000100,0b00001000,0b00010000,0b00100000};

void Derecha(n)
{
    for (i=0;i!=n;i++)
  {
   OUTPUT_B(pasos[p]);
   Delay_ms(t);
   OUTPUT_B(0);
   Delay_us(t0);
   
   p++;
   
   if(p>3)
   {
      p=0;
   }
 
}
}

alguien sabe como puedo evitar esto, estoy utilizando CCS 4.104 y un pic 18f2550.

Muchas Gracias!


Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: OUTPUT_B sin modificar B0 y B1
« Respuesta #1 en: 22 de Octubre de 2013, 12:30:25 »
Se me ocurren varias opciones, una podría ser hacer una subrutina:

Código: C#
  1. inline void writePortBPins(uint8_t newValue, uint8_t mask)
  2. {
  3.         output_b(((input_b() ^ newValue) & mask) ^ input_b());
  4. }
En tu caso serían:

writePortBPins(pasos[p], 0xFC);
y
writePortBPins(0, 0xFC);

respectivamente.

He elegido mostrar esta solución porque originariamente la hice para ASM:

Código: ASM
  1. movf PORTB,W
  2. xorwf newValue,W
  3. andwf mask,W
  4. xorwf PORTB,F

y como verás, se puede realizar en tan sólo 4 instrucciones.

Hay otras soluciones también, obviamente.

Saludos!
« Última modificación: 22 de Octubre de 2013, 15:08:55 por BrunoF »
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado facuver

  • PIC10
  • *
  • Mensajes: 14
Re: OUTPUT_B sin modificar B0 y B1
« Respuesta #2 en: 22 de Octubre de 2013, 14:22:02 »
Muchas Gracias por tu respuesta, tuve que acomodarla un poco para que compile, el ultimo XOR no es con INPUT_B(), es con newValue.
Quedo algo asi:
Código: [Seleccionar]
inline void writePortBPins(int newValue , int mask)
{
       output_b(((input_b() ^ newValue) & mask) ^ newValue);
}

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: OUTPUT_B sin modificar B0 y B1
« Respuesta #3 en: 22 de Octubre de 2013, 14:27:51 »
Hola!

Primero, es una buena costumbre utilizar tipos comunes entre compiladores.
Agregando #include <stdint.h> podrías haber usado la función que te pasé tranquilamente.

Por otro lado, debería ser con input_b(). Si lo haces con newValue te va a dar mal.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: OUTPUT_B sin modificar B0 y B1
« Respuesta #4 en: 22 de Octubre de 2013, 14:34:59 »
Un contraejemplo para que veas que si usas newValue el resultado no es siempre el correcto:

Asumamos PORTB actualmente = 0x3, el newValue deseado es 0x1 y mask = 0x3:

PORTB XOR newValue AND mask XOR newValue = valor final del PORTB
PORTB XOR newValue = 0x2 AND mask = 0x2 XOR newValue = 0x3. El valor deseado era 0x1, NO 0x3.

Cabe destacar que esto funciona siempre y cuando no se produzcan interrupciones que puedan afectar a los bits del puerto. Sino hay que cambiar el algoritmo por otro más seguro o deshabilitar temporalmente las interrupciones durante la ejecución de la subrutina propuesta.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado facuver

  • PIC10
  • *
  • Mensajes: 14
Re: OUTPUT_B sin modificar B0 y B1
« Respuesta #5 en: 22 de Octubre de 2013, 15:00:12 »
Lo probe en el protoboar y con Xor a newValue y anda, ahi que tener en cuenta que los 2 bist menos significativos de newValue son siempre 0.

Cuando pruebo la funcion con Xor a INPUT el motor no se mueve y los puertos si inicialmente estaban prendidos se apagan.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: OUTPUT_B sin modificar B0 y B1
« Respuesta #6 en: 22 de Octubre de 2013, 15:07:14 »
Es que yo confundí la máscara. Creeme que si usás XOR newValue te está funcionando sólo porque justo los pasos del motor son siempre distintos y se cancelan mediante, pero es una mera casualidad. Debería usar:

writePortBPins(pasos[p], 0xFC);
y
writePortBPins(0, 0xFC);

Modifico también mi post anterior para que no genere confusión.

Saludos
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado facuver

  • PIC10
  • *
  • Mensajes: 14
Re: OUTPUT_B sin modificar B0 y B1
« Respuesta #7 en: 22 de Octubre de 2013, 15:11:54 »
Ahora si, muchas gracias por todo. Saludos


 

anything