Autor Tema: Ayuda función shiftout  (Leído 2109 veces)

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

Desconectado malea_ittt

  • PIC10
  • *
  • Mensajes: 11
Ayuda función shiftout
« en: 20 de Junio de 2012, 06:42:12 »
Hola, buenos días. Primero me presento. Me llamo Pepe, me acabo de registrar, y espero aprender muchas cosas en este foro. Un saludo a todos.

A ver si me podéis ayudar.

Estoy intentando portar un trozo de código realizado en BASCOM para un micro Atmega, a C para un PIC18f2550.

El principal problema es que no tengo experiencia alguna programando, todo hay que decirlo… Pero me gusta trastear!

El código es muy sencillo. Me imagino que la declaración de variables y las operaciones más básicas que me he encontrado (sumas, restas…), podré realizarlas yo, aún sin tener experiencia. Así que en un principio lo intentaré yo solo antes de preguntar, y si veo que no puedo ya preguntaré. Pero me he encontrado con una función que no sé como portarla. Es ésta:

Shiftout Dat , Clk , Var , 0 , 8 , 50

Supongo que no hay una función equivalente en CSS. Y como no tengo experiencia programando, la verdad que no sé exactamente cómo hacerlo.

He buscado información acerca de la función y por lo que veo, hace esto:

- Dat es el puerto que sirve de salida de datos.
- Clk es el puerto que sirve de salida de la señal de reloj.
- Var es la variable que queremos sacar. En este caso se trataría de un byte.
- 0 significa que queremos sacar primero el bit más significativo (MSB). Y que lo sacamos cuando el reloj está BAJO.
- 8 significa que queremos sacar 8 bits en total (Recordemos que Var es 1byte)
- 50 es un retraso en us.

Bueno, simplemente eso. He buscado información por mi cuenta y tengo bastante claro lo que hace la función, pero no sé cómo escribirlo en C para mi PIC18f2550.

Si alguien me puede echar una mano…

Muchas gracias!!

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Ayuda función shiftout
« Respuesta #1 en: 20 de Junio de 2012, 14:22:50 »
Tal como lo quieres no hay, pero puedes escribirla tu mismo si lo deseas.
Este ejemplo que voy a ponerte a continuacion es de la libreria de un 74HC595, que es un expansor serie a paralelo.

Te va a dar una idea de como hacer una funcion que permita hacer lo que necesitas...

Código: C++
  1. void write_expanded_outputs(BYTE* eo) {
  2.   BYTE i;
  3.  
  4.   output_low(EXP_OUT_CLOCK);
  5.   output_low(EXP_OUT_ENABLE);
  6.  
  7.   for(i=1;i<=NUMBER_OF_74595*8;++i) {  // Clock out bits from the eo array
  8.     if((*(eo+(NUMBER_OF_74595-1))&0x80)==0)
  9.       output_low(EXP_OUT_DO);
  10.     else
  11.       output_high(EXP_OUT_DO);
  12.    shift_left(eo,NUMBER_OF_74595,0);
  13.    output_high(EXP_OUT_CLOCK);
  14.    output_low(EXP_OUT_CLOCK);
  15.   }
  16.   output_high(EXP_OUT_ENABLE);
  17.   output_low(EXP_OUT_ENABLE);
  18.  
  19. }
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado malea_ittt

  • PIC10
  • *
  • Mensajes: 11
Re: Ayuda función shiftout
« Respuesta #2 en: 25 de Junio de 2012, 12:16:02 »
Te agradezco mucho tu respuesta. Pero ando bastante perdido, la verdad. Pensaba que sería algo más intuitivo.

Código: C++
  1. #define LSBFIRST 0
  2. #define CLOCK_LCD   PIN_A0
  3. #define DAT_LCD   PIN_A1
  4.  
  5. void shiftout(byte orden, byte valor)
  6. {
  7.     byte b;
  8.  
  9.     if(orden==LSBFIRST)
  10.     {
  11.         b=1;
  12.     }
  13.     else
  14.     {
  15.         b=128;
  16.     }
  17.    
  18.     while(b) {
  19.         if(valor & b)
  20.             DATA_LCD=1;
  21.         else
  22.             DATA_LCD=0;
  23.             CLK_LCD=1;
  24.             Delay_us(50);
  25.             CLK_LCD=0;
  26.         if(orden == LSBFIRST)    
  27.             b <<= 1;
  28.         else
  29.             b >>= 1;
  30.     }
He encontrado un ejemplo en este mismo foro. Lo he modificado un poco. Lo que no sé es si lo he hecho bien. Para enviar primero el bit más significativo, tendría que hacer shiftout (1, var)??

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Ayuda función shiftout
« Respuesta #3 en: 25 de Junio de 2012, 15:00:05 »
Si, asi seria, pero igual no creo que te funcione.
Para saber cual es el estado del bit a enviar (1 o 0) deberias usar bit_test(), y asignarlo como salga el resultado del examen.
Perdon, lei mal, la funcion hace el & con 1 o 128 segun le asignes, deberia andar OK !!
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado malea_ittt

  • PIC10
  • *
  • Mensajes: 11
Re: Ayuda función shiftout
« Respuesta #4 en: 27 de Junio de 2012, 05:00:28 »
Creo que dentro del while, en el primer if me faltaban cosas. Lo he corregido. Creo que ahora lo tengo bien. Y otra cosa. Si quiero que saque los datos en el flanco de bajada del reloj, me imagino que en lugar de poner CLK a 1 después de guardar el bit en DAT_LCD lo tendré que poner a 0 no? Vamos, invertir todos los CLK que tengo ahora. Donde tengo 0 poner 1 y donde tengo 1 poner 0. Sería así?

Gracias otra vez.

Código: C++
  1. #define LSBFIRST 0
  2. #define CLK_LCD   PIN_A0
  3. #define DAT_LCD   PIN_A1
  4.  
  5. void shiftout(byte orden, byte valor)
  6. {
  7.     byte b;
  8.  
  9.     if(orden==LSBFIRST)
  10.     {
  11.         b=1;
  12.     }
  13.     else
  14.     {
  15.         b=128;
  16.     }
  17.    
  18.     while(b) {
  19.         if(valor & b)
  20.             DATA_LCD=1;
  21.             CLK_LCD=1;
  22.             Delay_us(50);
  23.             CLK_LCD=0;
  24.         else
  25.             DATA_LCD=0;
  26.             CLK_LCD=1;
  27.             Delay_us(50);
  28.             CLK_LCD=0;
  29.         if(orden == LSBFIRST)    
  30.             b <<= 1;
  31.         else
  32.             b >>= 1;
  33.     }

Bueno, para simplificar, como solo voy a utilizar la función para sacar primero el bit más significativo, en el flanco de bajada de reloj y con un retraso de 50us entre cada bit sacado, lo he simplificado así:

Código: [Seleccionar]
#define CLK_LCD   PIN_A0
#define DAT_LCD   PIN_A1

void shiftout (byte valor)
{
    int i;
 
    for (i = 0; i < 8; i++) {
        if(valor & (128 >> i))
            DAT_LCD=1;
        else
            DAT_LCD=0;
        
CLK_LCD=0;
        Delay_us(50);
        CLK_LCD=1;          
    }
}

Estaría bien así? Espero no haberlo hecho mal al simplificarlo. Gracias otra vez!!!
« Última modificación: 27 de Junio de 2012, 05:57:45 por malea_ittt »


 

anything