TODOPIC

Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: johenrod en 30 de Mayo de 2022, 11:16:02

Título: 2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: johenrod en 30 de Mayo de 2022, 11:16:02
cordial saludo,,
tan amables tengo una duda no se si podría implementarse, en este caso tengo un pic16f676 el cual tiene RA0 <>RA5 y RC0<>RC5 requiero hacer una secuencia pero de 8 bits y como a ambos puertos les faltan el 6 y el 7 estoy loco.
se podría implementar una variable y asignarle  a0,a1,a2,a3,a4,a5 y agregar c0,c1 para obtener 8 bits y luego manejarla como si fuera un puerto?.
gracias de antemano.
Título: Re:2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: DominusDRR en 30 de Mayo de 2022, 11:49:38
cordial saludo,,
tan amables tengo una duda no se si podría implementarse, en este caso tengo un pic16f676 el cual tiene RA0 <>RA5 y RC0<>RC5 requiero hacer una secuencia pero de 8 bits y como a ambos puertos les faltan el 6 y el 7 estoy loco.
se podría implementar una variable y asignarle  a0,a1,a2,a3,a4,a5 y agregar c0,c1 para obtener 8 bits y luego manejarla como si fuera un puerto?.
gracias de antemano.

Hay varias maneras, pero este pseudocódigo tal vez lo puedas comprender.

Código: C
  1. void miPuertoDe8bits(unsigned char valor)
  2. {
  3.      unsigned char i;
  4.      PortA = Valor;
  5.      if (valor <= 0x3F) // si valor es menor o igual a un número de 6 bits, equivale a bit 7 y bit 6 de valor están en  0 0
  6.     {
  7.          PortCbits.RC0 = 0;
  8.          PortCbits.RC1 = 0;
  9.          return; // para que no ejecute el if de abajo
  10.     }
  11.     i = valor& 0xC0; // me quedo con los bits 7 y 6 de valor;
  12.  
  13.    if (0x40 == i) // Equivale a que los  bit 7 y bit 6 de valor están en  0 1
  14.    {
  15.          PortCbits.RC0 = 1;
  16.          PortCbits.RC1 = 0;
  17.          return;
  18.    }
  19.    if (0x80 = i) //Equivale a que los  bit 7 y bit 6 de valor están en  1 0
  20.    {
  21.          PortCbits.RC0 = 0;
  22.          PortCbits.RC1 = 1;
  23.    }
  24.    else //Equivale a que los  bit 7 y bit 6 de valor están en  1 1
  25.    {
  26.          PortCbits.RC0 = 1;
  27.          PortCbits.RC1 = 1;
  28.    }
  29. }
Título: Re:2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: johenrod en 30 de Mayo de 2022, 12:21:04
Hay varias maneras, pero este pseudocódigo tal vez lo puedas comprender.
Código: C
  1. void miPuertoDe8bits(unsigned char valor)
  2. {
  3.      unsigned char i;
  4.      PortA = Valor;
  5.      if (valor <= 0x3F) // si valor es menor o igual a un número de 6 bits, equivale a bit 7 y bit 6 de valor están en  0 0
  6.     {.........
Gracias por tu respuesta, aquí seria estar llamando la función cada que envíe un dato como si fuera a un puerto verdad?
las variables podrian ser tipo int?
Título: Re:2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: DominusDRR en 30 de Mayo de 2022, 12:23:33
Hay varias maneras, pero este pseudocódigo tal vez lo puedas comprender.

Código: C
  1. void miPuertoDe8bits(unsigned char valor)
  2. {
  3.      unsigned char i;
  4.      PortA = Valor;
  5.      if (valor <= 0x3F) // si valor es menor o igual a un número de 6 bits, equivale a bit 7 y bit 6 de valor están en  0 0
  6.     {.........
las variables podrian ser tipo int?

Si el dato que deseas escribir en tu puerto virtual (que es uno de 6 bits más dos bits de otro puerto) ¿Por qué necesitas int que es mayor a 8 bits?
Título: Re:2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: DominusDRR en 30 de Mayo de 2022, 12:24:26
Hay varias maneras, pero este pseudocódigo tal vez lo puedas comprender.
Código: C
  1. void miPuertoDe8bits(unsigned char valor)
  2. {
  3.      unsigned char i;
  4.      PortA = Valor;
  5.      if (valor <= 0x3F) // si valor es menor o igual a un número de 6 bits, equivale a bit 7 y bit 6 de valor están en  0 0
  6.     {.........
Gracias por tu respuesta, aquí seria estar llamando la función cada que envíe un dato como si fuera a un puerto verdad?

Sí, cada vez que necesitas escribir en tu puerto virtual, llamas a la función
Título: Re:2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: johenrod en 30 de Mayo de 2022, 12:44:44
Citar
DominusDRR
¿Por qué necesitas int que es mayor a 8 bits?
lo preguntaba porque en ccs uso "int8"
Título: Re:2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: DominusDRR en 30 de Mayo de 2022, 12:47:16
Citar
DominusDRR
¿Por qué necesitas int que es mayor a 8 bits?
lo preguntaba porque en ccs uso "int8"

int8 en CCS es lo mismo que char (8 bits) Héchale una hojeada al manual de usuario del compilador.

int es de 16 bits, (me parece, o tal vez sea de 32)
Título: Re:2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: johenrod en 30 de Mayo de 2022, 13:10:40
Citar
DominusDRR
siiiii, char es igual que int
Código: C++
  1. Especificadores de tipo:
  2.  
  3. unsigned define un número de 8 bits sin signo
  4. unsigned int define un número de 8 bits sin signo
  5. int define un número de 8 bits sin signo
  6. char define un número de 8 bits sin signo
  7. long define un número de 16 bits sin signo
  8. long int define un número de 16 bits sin signo
  9. signed define un número de 8 bits con signo
  10. signed int define un número de 8 bits con signo
  11. signed long define un número de 16 bits con signo
  12. float define un número de 32 bits en punto flotante
  13. short define un bit
  14. short int define un bit
Título: Re:2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: DominusDRR en 30 de Mayo de 2022, 13:15:21
Citar
DominusDRR
siiiii, char es igual que int
Código: C++
  1. Especificadores de tipo:
  2.  
  3. unsigned define un número de 8 bits sin signo
  4. unsigned int define un número de 8 bits sin signo
  5. int define un número de 8 bits sin signo
  6. char define un número de 8 bits sin signo
  7. long define un número de 16 bits sin signo
  8. long int define un número de 16 bits sin signo
  9. signed define un número de 8 bits con signo
  10. signed int define un número de 8 bits con signo
  11. signed long define un número de 16 bits con signo
  12. float define un número de 32 bits en punto flotante
  13. short define un bit
  14. short int define un bit

Si recuerdo que ese compilador no cumple con la norma ISO del lenguaje C
Título: Re:2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: Eduardo2 en 30 de Mayo de 2022, 13:38:18
cordial saludo,,
tan amables tengo una duda no se si podría implementarse, en este caso tengo un pic16f676 el cual tiene RA0 <>RA5 y RC0<>RC5 requiero hacer una secuencia pero de 8 bits y como a ambos puertos les faltan el 6 y el 7 estoy loco.
se podría implementar una variable y asignarle  a0,a1,a2,a3,a4,a5 y agregar c0,c1 para obtener 8 bits y luego manejarla como si fuera un puerto?.
gracias de antemano.

Hay mil maneras de hacerlo, yo usaría un macro.

Si los pines C2...C5  no se usan o están configurados como entradas , entonces definís el macro:
Código: [Seleccionar]
#define output_AC(x) {output_a(x) ; output_c(x>>6) ;}
y para escribir los puertos:
Código: [Seleccionar]
     output_AC(valor8) ;

Pero alguno de C2...C5 se está usando como salida le estarías escribiendo ceros encima, entonces el macro sería:
Código: [Seleccionar]
#define output_AC(x) {output_a(x) ;   \
                       output_c((x>>6) | input_c() ) ;}


Lo mismo que esto último pero mas eficiente, y mas declaraciones :(  :
Código: [Seleccionar]
#byte porta = getenv("SFR:PORTA")
#byte portc = getenv("SFR:PORTC")
struct {int8 l:6 , h:2 ;} valor  ; 
#define output_AC(x) {porta=x   ; \
                       portc&=3  ; \
                       portc|=x.h ;}
y lo llamás:
Código: [Seleccionar]
    valor = 0x55 ;
   .......................................
    output_AC(valor) ;   
Título: Re:2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: johenrod en 02 de Junio de 2022, 13:06:52
Citar
Eduardo2
Lo mismo que esto último pero mas eficiente, y mas declaraciones :(  :
Código: [Seleccionar]
#byte porta = getenv("SFR:PORTA")
#byte portc = getenv("SFR:PORTC")
struct {int8 l:6 , h:2 ;} valor  ;
#define output_AC(x) {porta=x   ; \
                       portc&=3  ; \
                       portc|=x.h ;}
y lo llamás:
Código: [Seleccionar]
    valor = 0x55 ;
   .......................................
    output_AC(valor) ;     
gracias por responderme, podrías enseñarme a entender...

#byte porta = getenv("SFR:PORTA")
#byte portc = getenv("SFR:PORTC")  devolverían la dirección correspondiente a los puertos?

struct {int8 l:6 , h:2 ;} valor  ;                 creo 2 variables tipo int "l" y otra "h"

#define output_AC(x) {porta=x   ; \          como se leería de acá hacia abajo?
                       portc&=3  ; \                    aqui seria hacer and (&)con puerto c para que no modifique los otros bits del puerto? 
                       portc|=x.h ;}

"valor"  y  "x" son variables? de ser así hay que declararlas como int globales?
Título: Re:2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: KILLERJC en 02 de Junio de 2022, 17:10:12
Citar
se podría implementar una variable y asignarle  a0,a1,a2,a3,a4,a5 y agregar c0,c1 para obtener 8 bits y luego manejarla como si fuera un puerto?.
No, una variable no...

Todos los metodos que te entregaron hasta ahora es Macros o funciones.... Personalmente odio las macros. Y en esas macros en realidad son "funciones" por lo que tampoco tiene mucho sentido escaparle a la funcion.

Si queres manejar los 2 puertos con una variable que tuviera bits:  a5,a4,a3,a2,a1,a0,c1,c0. Es decir, pasar una variable de 8 bits y que los primeros 6 salgan por el PORTA y los 2 restantes por el PORTC
Entonces:

Código: C
  1. static inline void output_AC(x) {
  2.     PORTA = (x>>2);
  3.     PORTC = (PORTC & 0xFC ) | (x & 0x3);} // Para no modificar los otros bits del PORTC

Si requeris tomar los datos de los puertos y que te devuelva una variable de 8 bits entonces:

Código: C
  1. static inline int8 input_AC() {
  2.     int8 aux;
  3.     aux = (PORTA << 2);
  4.     aux |= PORTC & 0x3
  5.     return aux;}
Título: Re:2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: DominusDRR en 02 de Junio de 2022, 17:16:03
Citar
se podría implementar una variable y asignarle  a0,a1,a2,a3,a4,a5 y agregar c0,c1 para obtener 8 bits y luego manejarla como si fuera un puerto?.
No, una variable no...

Todos los metodos que te entregaron hasta ahora es Macros o funciones.... Personalmente odio las macros. Y en esas macros en realidad son "funciones" por lo que tampoco tiene mucho sentido escaparle a la funcion.

Si queres manejar los 2 puertos con una variable que tuviera bits:  a5,a4,a3,a2,a1,a0,c1,c0. Es decir, pasar una variable de 8 bits y que los primeros 6 salgan por el PORTA y los 2 restantes por el PORTC
Entonces:

Código: C
  1. static inline void output_AC(x) {
  2.     PORTA = (x>>2);
  3.     PORTC = (PORTC & 0xFC ) | (x & 0x3);} // Para no modificar los otros bits del PORTC

Si requeris tomar los datos de los puertos y que te devuelva una variable de 8 bits entonces:

Código: C
  1. static inline int8 input_AC() {
  2.     int8 aux;
  3.     aux = (PORTA << 2);
  4.     aux |= PORTC & 0x3
  5.     return aux;}

La abstracción de código suele ser difícil de comprender cuando aún eres novato en C. De ahí que le respondí con una función más sencilla, para que analice y comprenda como solucionar el problema. Pero si no es difícil para él, creo que está bien.
Título: Re:2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: Eduardo2 en 02 de Junio de 2022, 22:30:34
....
gracias por responderme, podrías enseñarme a entender...

#byte porta = getenv("SFR:PORTA")
#byte portc = getenv("SFR:PORTC")  devolverían la dirección correspondiente a los puertos?
Correcto,  es cómodo si se trata de una rutina que  vas a compilar para diferentes micros.

Citar
struct {int8 l:6 , h:2 ;} valor  ;                 creo 2 variables tipo int "l" y otra "h"
No exactamente,  la variable "valor" está formada por valor.l (los bits 0..5) y valor.h (los bits 6..7) 
Por ejemplo haciendo  valor = 0x85
en  valor.l  vas a leer  0x05 ;
y en valor.h vas a leer  0x02 ;

Ojo, de esta manera la usé en el ejemplo, pero struct es mucho mas potente.

Citar
#define output_AC(x) {porta=x   ; \          como se leería de acá hacia abajo?
                       portc&=3  ; \                    aqui seria hacer and (&)con puerto c para que no modifique los otros bits del puerto? 
                       portc|=x.h ;}

Es un macro con argumentos (puede tener mas de uno), lo que hace es reemplazar el texto donde aparezca x.
La barra invertida (\)  indica que el macro sigue en la línea siguiente.

Ahora veo que me olvidé una negación (~)  :oops:  , porque la idea es modificar C0 y C1 sin alterar el resto. Eso debió ser:
Código: [Seleccionar]
#define output_AC(x) {porta=x   ; \ 
                      portc&=~3  ; \             
                      portc|=x.h ;}
Que es lo mismo que escribir
Código: [Seleccionar]
#define output_AC(x) {porta=x   ;  portc&=~3  ;  portc|=x.h ;}

Finalmente ,     output_AC(valor) ;
Se expande como
Código: [Seleccionar]
     porta=valor   ;   
     portc&=~3  ;             
     portc|=valor.h ;

Citar
"valor"  y  "x" son variables? de ser así hay que declararlas como int globales?
Para el macro "valor" es un texto que debe reemplazar donde le aparezca "x" .

Lo que hace el macro es insertar un texto dentro del fuente, obviamente con funciones que alegran la vida.
Título: Re:2 puertos de 6 bits, como obtener de ellos 1 de 8 bits?
Publicado por: johenrod en 04 de Junio de 2022, 13:37:22
Excelente, gracias a ambos, si bien el ejemplo de DominusDRR es mas fácil de entender para mi,  quise también ver como trabajaba el código de Eduardo2 ya que la idea es aprender siempre un poco mas.
voy a implementar ambos y les comento, muchas gracias