TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: RaDoN en 11 de Abril de 2006, 10:29:05

Título: Trabajar con "semipuertos"
Publicado por: RaDoN en 11 de Abril de 2006, 10:29:05
Vereis, tengo la necesidad de trabajar con los puertos divididos, como si fuese los MSB un puerto distinto a otro, los LSB. Me explico, por poner un ejemplo, RB7:4 una variable y RB3:0 otra ...

Lo que quiero es un registro int8 el cual empieza por "0000" siempre, por lo tanto con un valor entre 0 y 15, volcarlo cuando lo necesite a la parte alta de un puerto o otras veces a la baja (sin modificar el otro "semipuerto".

No tiene ninguna complicadez trabajando con bits, aunque me parece algo tedioso y queria saber si existe otro modo de hacerlo  :?

En el ejemplo, la parte roja del int8 la vuelvo a la parte roja del puerto B manteniendo el valor que ya tenia la parte azul.

(http://img159.imageshack.us/img159/5504/asd8kv.jpg)
Título: Re: Trabajar con "semipuertos"
Publicado por: elmasvital en 11 de Abril de 2006, 11:49:51
Radon sinceramente no me enterado bien lo que necesitas hacer pero te doy ideas por si va por ahí la cosas.

Has revisado los operadores de desplaza miento << y >> ¿¿¿?? sirven para quedarte con la parte alta o baja e un byte.

si pones por ejemplo << desplazas a la izquierda y >> a la derecha

variable= 0000 1111

variable <<4;

daria como resultado

variable= 1111 0000

mas extenso y seguro mejor explicado en google  operadores desplazamiento

http://pisuerga.inf.ubu.es/lsi/Invest/Java/Tuto/II_3.htm (http://pisuerga.inf.ubu.es/lsi/Invest/Java/Tuto/II_3.htm)
Título: Re: Trabajar con "semipuertos"
Publicado por: RaDoN en 11 de Abril de 2006, 11:57:12
Si elamsvital, los tiros van por ahi, pero en el caso de desplazar no basta, porque si vuelvo el valor al puerto ya estaría modificando la "parte baja", en el ejemplo la parte azul.
Título: Re: Trabajar con "semipuertos"
Publicado por: gONzAO en 11 de Abril de 2006, 12:23:12
Me imagino que la solución q te propongo ya la has tenido en cuenta y quieres algo más directo, de todas formas ahí lo dejo:

ejemplo1 -> vamos a poner un 7 en la parte alta del puerto B

Código: [Seleccionar]
valor = 7;
valor = valor << 4; // es lo mismo que valor = 0x70;
PORTB &= 0x0F; // limpiamos parte alta de puertoB
PORTB |= valor;

ejemplo2 -> tenemos 0xC3 en valor y queremos poner 'C' en "el semipuerto inferior B"

Código: [Seleccionar]
valor >>= 4;
PORTB &= 0xF0; // limpiamos parte baja de puertoB
PORTB |= valor; // añadimos nuestro dato


Así trabajamos a nivel de byte. Con las máscaras forzamos primero ceros y después unos. Si hay algo que no esté claro, no dudes en preguntar

Un saludo

gONzAO
Título: Re: Trabajar con "semipuertos"
Publicado por: RaDoN en 11 de Abril de 2006, 14:34:21
Gracias gONzAO, no se me habia ocurrido tal, lo que no queria es ir bit a bit  :D
Título: Re: Trabajar con "semipuertos"
Publicado por: maunix en 11 de Abril de 2006, 14:42:50
Gracias gONzAO, no se me habia ocurrido tal, lo que no queria es ir bit a bit  :D

RaDoN, te quería advertir que lo que pretendes hacer depende de si usarás tu puerto como todo salida, o como E/S.

Si usas la solución propuesta por gonzao, fijate que tu puerto pasará un ciclo de microcontrolador por el valor 0, precisamente cuando hace PORTB &= 0x0F.  Tal vez esto te sirva, o tal vez no.

Lo que se suele usar en estos casos es usar un registro de 'máscara'  en el cual uno graba lo que quiere guardar en el puerto B.  Entonces siempre trabajas con el registro máscara y en el último paso recien lo sacas por el puerto B.

Por ejemplo

Código: C
  1. unsigned char masB1, mascB2, mascB;
  2.  
  3. mascB1 = 7;  // nibble inferior
  4. mascB2 = 14;   // nibble superior
  5.  
  6. // actualización máscara - pudiera ser una función por separado
  7. mascB = mascB1 | (mascB2 << 4);
  8. PORTB = mascB;

De esta forma siempre trabajas con los mascB1 y mascB2 y puedes mantener en una función separada, la última parte.

Espero te haya servido de utilidad.

Saludos

Título: Re: Trabajar con "semipuertos"
Publicado por: RaDoN en 11 de Abril de 2006, 14:54:36
Me anoto el código ... aunque realmente para el caso que me ocupa no importa que el "semipuerto" este a 0 durante un ciclo de reloj, de hecho estoy multiplexando y hasta que no ocurra el retardo (delay) no será "visible" el cambio por decirlo de alguna forma.
Título: Re: Trabajar con "semipuertos"
Publicado por: Nocturno en 12 de Abril de 2006, 02:13:40
Y si quieres no tienes porque hacerlo pasar por 0, puedes hacerlo todo a la vez:

Código: [Seleccionar]
valor = 7;
PORTB = (valor << 4) | (PORTB & 0x0F);

Por cierto, igual que 8 bits son un Byte y 16 un word, al grupo de 4 bits suele llamársele Nibble.
Título: Re: Trabajar con "semipuertos"
Publicado por: RaDoN en 12 de Abril de 2006, 05:33:23
Gracias manolo (lo de nibble lo conocia... pero 16 bits es un "word"  :shock:), por cierto tu eras de VB no? jejeje ya te daré caló cuando empiece con el soft de control por el puerto serie, espero que no me mandes a tomar por culo  por cansino (en Basic soi pescaito en blanco) :lol:
Título: Re: Trabajar con "semipuertos"
Publicado por: jfh900 en 12 de Abril de 2006, 07:23:24
Otra forma de trabajar con puertos parciales es utilizando las estructuras de "C", por ejemplo:

struct sMedioByte
{
  MedioByte:4;
}

union
{
  struct MedioByte usMedioByte1;
  struct MedioByte usMedioByte2;
  int nByte;
} uByte;     

La forma de utilizarlo es:

uByte.usMedioByte1 = 0b0011;
uByte.usMedioByte2 = 0b1111;

Y para acceder a cualquiera de los bit"s:

uByte.nByte  devolveria todo el byte
uByte.usMedioByte1 devuelve la primera mitad y
uByte.usMedioByte2 devuelve la segunda mitad

Bueno lo escribo de memoria y no se si habria que hacer algun cambio, pero basicamente es así.

Título: Re: Trabajar con "semipuertos"
Publicado por: Nocturno en 12 de Abril de 2006, 07:42:17
¡¡ Pero qué bonito y elegante queda el código con las estructuras !!

Habría que ver, no obstante, si queda igual de optimizado.

Radon, yo a 16 bits siempre les he llamado Word, aunque no sé si estoy en lo correcto. Si algún maestro me puede corregir, encantado.
Y tienes razón, yo ERA de Visual Basic. Ahora SOY de CCS y Delphi.
Pero si te puedo ayudar, será un placer.
Título: Re: Trabajar con "semipuertos"
Publicado por: RaDoN en 12 de Abril de 2006, 08:05:25
Gracias  nocturno :D la verdad esque sinceramente usando estructuras es la primera forma en que se me ocurrió hacerlo, pero nunca las he usado y mi intento fue en vano. Probe a ojo valiendome de la libreria de la LCD donde tb la usa de forma similar.

Pero en fin, esta bien tener distintos recursos que pueden valer para distintas situaciones, de momento para esta me quedo con la que dió gONzAO (en la "versión" jeje de manolo).
Título: Re: Trabajar con "semipuertos"
Publicado por: gONzAO en 12 de Abril de 2006, 08:51:21
Sí, creo q como lo hace manolo es la mejor manera.

No sé porqué dejé así el código. Aunque es por un instante, dejaba el puerto con un valor que no era el que deseabamos.

Puedes estirar su ejemplo en varias lineas:
 Leemos el puerto
 Modificamos los bits que queremos
 Reescribir en el puerto

Pero si se puede hacer todo el una linea, pues mejor :P


En cuanto al nombre de los diferentes grupos de bits, por lo que yo se, WORD es un tipo de datos de 16 bits y DWORD de 32bits.
Pienso que hay un poco de lio entre el nombre que le damos y el tipo de dato que lo representa (que además cada uno le llama como quiere y si no le gusta lo renombra):
8 bits   -> char, byte
16 bits -> int, long, word, short
32 bits -> long, float, dword


Un saludo

gONzAO
Título: Re: Trabajar con "semipuertos"
Publicado por: maunix en 12 de Abril de 2006, 08:51:26
RaDoN si usas C18 lo podrías hacer asi:

Código: C
  1. typedef union Tpuerto {
  2.         unsigned char full;
  3.         struct {
  4.                 unsigned LowerNibble:4;        
  5.                 unsigned UpperNibble:4;
  6.         };
  7. };
  8.  
  9. struct Tpuerto puerto;
  10.  
  11. puerto.LowerNibble = 1;
  12. puerto.UpperNibble = 8;
  13. LATD = puerto.full;

Saludos
Título: Re: Trabajar con "semipuertos"
Publicado por: RaDoN en 12 de Abril de 2006, 09:11:42
Gracias a todos por la ayuda, el codigo ya lo tengo listo, he puesto en el subforo de proyectos este, moviendo los pap del brazo.

Edito: maunix programo en CCS, aunque de todas formas es bastante similar y me vale como ejemplo.
Título: Re: Trabajar con "semipuertos"
Publicado por: jfh900 en 12 de Abril de 2006, 16:41:09
nocturno66, yo también uso Delphi para comunicarme con los PIC.  :D