Asignar una variable a un pin de un puerto

#1
Buenas tardes,

Me estoy volviendo loco y no se como hacer lo siguiente;

Necesito asignar una variable a un pin de salida del puerto B, algo así como

output_high(Pin_B ->(contador) ) Es decir donde contador el pin que sea definido por la variable contador que es de 0 a 7.

Se que se puede hacer porque en mis tiempos de programador lo hacía pero ahora no doy con la formula.

Gracias!
 
#2
¿Podrias meter en un coche de formula 1 a 7 pilotos?. Pues es lo que tu quieres hacer con ese PIN.
Un PIN de un puerto solo acepta un 0 o un 1, igual que el monoplaza, por tanto nunca vas a poder meter un valor de 7 en un PIN.

Saludos.
 

pandacba

Rocker Bear
#3
Porque no explicas mejor que quieres hacer para que necesitas lo que pretendes, tal vez hay una solución pero no como la estas plantenado.

Me parece lo que queres es que cada vez que una salida este alto lo sume a una varible en la que tienes una condición de 7 como máximo
 
#4
Necesito asignar una variable a un pin de salida del puerto B, algo así como:

output_high(Pin_B ->(contador) ) Es decir donde contador el pin que sea definido por la variable contador que es de 0 a 7.
Un pin nada más puede tener el valor 0 o 1, no de 0 a 7.

O sea:
output_high(PIN_XX);
output_low(PIN_XX);

Un puerto sí puede tener un valor de hasta 255. (Todos en 1)
output_b(valor <= 255);
 
#5
Creo si mal no entiendo, lo que el compañero quiere hacer es, que se ponga en "1" el pin del puerto B que la variable contador este apuntando, o sea "contador" puede ser un valor de 0 a 7, si por ejemplo vale 3, entonces quiere que se ponga un 1 en el pin 3 del puerto B, eso es lo que yo interpreto, no que ponga un valor 3 en un pin cualquiera del puerto B, eso es absurdo.
Una forma de hacer eso seria la siguiente: (no es la unica forma)
Código:
switch (contador)
{
    case 0:output_high(PIN_B0);break;
    case 1:output_high(PIN_B1);break;
    case 2:output_high(PIN_B2);break;
    case 3:output_high(PIN_B3);break;
    case 4:output_high(PIN_B4);break;
    case 5:output_high(PIN_B5);break;
    case 6:output_high(PIN_B6);break;
    case 7:output_high(PIN_B7);break;
}
 
Última edición:
#6
¿Y no sale mejor como ...?

Puerto = 0;
output_high(2^PIN_B0);

O mejor para que no haga un flanco, hacerlo a través de un char o un byte:

variable = 2^pin;
puerto = variable;

Probablemente sea mas rápido rotando
variable=1;
variable>>pin;
puerto = variable;

(mas o menos esa sintaxis, en C estoy algo verde)
 
Última edición:
#7
Creo si mal no entiendo, lo que el compañero quiere hacer es, que se ponga en "1" el pin del puerto B que la variable contador este apuntando, o sea "contador" puede ser un valor de 0 a 7, si por ejemplo vale 3, entonces quiere que se ponga un 1 en el pin 3 del puerto B, eso es lo que yo interpreto, no que ponga un valor 3 en un pin cualquiera del puerto B, eso es absurdo.
Si es eso, entonces se puede usar una simple función que devuelva el valor a asignar en el puerto.

Por ejemplo:
PHP:
int8 set_pin (int8 puerto, int8 pin)
{
    if(pin != 0 && pin < 8)
        return puerto |= 1 << pin;
    else
        return 0;
}
Y el puerto, lo declaramos de la siguiente forma...
Por ejemplo, el puerto B:
#byte portb = getenv ("SFR:pORTB")
O así:
#byte portb = 0x06

Y para usar la función:
PHP:
    int8 num_pin = 6;
    
    output_b(set_pin(portb, num_pin));
¿Así, o más fácil? ;)
 
Última edición:
#8
Gracias a todos!

Lo que yo queria hacer es que si en 'contador' hay un 5 se active el puerto rb5.

Quiería hacerlo con la instrucción for.

Quiero hacer un chequeo de leds del puerto rb al iniciar la rutina, se ilumina led en rb0, se apaga y se enciende rb1 y así hasta puerto rb7. Quiero hacerlo de esa manera con instrucción for entonces 'contador' se va incrementando hasta 7 y ese mismo registro tiene que apuntar al num de puerto



también veo interesante lo que pone el compañero juanma
 
Última edición:
#9
Gracias a todos!

Lo que yo queria hacer es que si en 'contador' hay un 5 se active el puerto rb5.

Quiería hacerlo con la instrucción for.

Quiero hacer un chequeo de leds del puerto rb al iniciar la rutina, se ilumina led en rb0, se apaga y se enciende rb1 y así hasta puerto rb7. Quiero hacerlo de esa manera con instrucción for entonces 'contador' se va incrementando hasta 7 y ese mismo registro tiene que apuntar al num de puerto



también veo interesante lo que pone el compañero juanma
Pues coloca lo que yo hice dentro de un for y listo.

 
#11
Pasa lo de siempre, cuesta tanto explicarlo eso de una sola vez en el primer post?
Cuando más amplia y clara sea la información, más pronta, rapida y presisa es la ayuda
Cada uno debe entender que tiene en su mente lo que quiere hacer, de este otro lado tan solo un puñado de palabras, que tal como se ha visto no alcanzaron
 
#12
¡je,je!

Acabo de recordar que hice algo parecido para Arduino (para un curso en francés):
Código:
#define Led1Pin                 PIN4
#define Pous1Pin                PIN2
#define Pous2Pin                PIN3
#define Pous(x)                 ((PIND & (1<<(x))) != 0)
#define Pous1                   Pous(Pous1Pin)
#define Pous2                   Pous(Pous2Pin)
#define Pous1On                 (Pous1 == LOW )
#define Pous1Off                (Pous1 == HIGH)
#define Pous2On                 (Pous2 == LOW )
#define LedOn(x)                (PORTD |=  (1<<(x)))
#define LedOff(x)               (PORTD &= ~(1<<(x)))
#define Led1On                  LedOn    (Led1Pin)
#define Led1Off                 LedOff   (Led1Pin)
Bueno, como se ve, hay un led en el pin 4 y dos botones, en los pines 2 y 3. Consiste en definiciones y definiciones de definiciones, para al final, tener disponible en el código sentencias del tipo Led1On para encender el LED, o Pous2On, para ver el estado del segundo botón.

No es recomendable abusar de esto, pues obliga a acordarse de cómo llamamos a cada cosa (estamos aumentando el vocabulario), y si el programa es largo, puede que nos lie más que ayudarnos. En cambio, si uno es consistente al dar los nombres, puede ayudar a generar un código más limpio.

En el caso de escribir

Código:
Led1On;
es como si hubiéramos escrito cualquiera de las siguientes:
Código:
LedOn (Led1Pin);
(PORTD |= (1<<(Led1Pin)));
(PORTD |= (1<<(PIN4)));
 
#13
Gracias a todos, creo que ya me ha quedado claro, voy a probar todas las maneras, así uno aprende. Después de 8 años sin programar se me había olvidado TODO... ahora estoy tirando de ejemplos y voy diciendo aaaaahhhh vale se hacía así....
 
#14
D@rkbytes si no te importa puedes poner lo que quiere decir los dos codigos que has puesto en el post 7, lo del segundo, mas-menos lo entiendo, pero el primero no, digo esto por que hay veces que a los que no tenemos el conocim¡ciento de vosotros, este es mi caso, si no pones que hace cada instruccion no lo termino de entender, gracias por anticipado, lo mismo digo en el caso de joaquinferrero.
 
#15
Si no pones que hace cada instrucción no lo termino de entender.
:eek: Es que poner explicación sobre lo que hacen esas instrucciones, sería como explicar el funcionamiento de los operadores en C.
Comprenderlos es algo básico en cualquier lenguaje.

Desde el aprendizaje de electrónica digital los hemos usado, pero con compuertas.
Sólo pondré el significado de los operadores usados:
!= Operador de Desigualdad o Diferente a. Lo mismo que <> en Basic.
&& Operador AND Lógico.
< Operador Menor qué.
|= Operador Inclusivo o de asignación de bits.
<< Operador de desplazamiento de bits hacia la izquierda.
 
#16
Mi solución se basa en el trabajo que el preprocesador, mediante la definición de una serie de macros (#define), de tal manera que

Led1On;

se transforma en

(PORTD |= (1<<(PIN4)));

antes de entrar en la fase de compilación.

Lo que hace esa línea es tomar un '1' y desplazarlo a la izquierda de forma binaria tantas veces como indique el valor de PIN4. Si, por ejemplo, PIN4 vale 3, entonces 1<<3 dará 0b00001000.

Luego, viene una operación binaria OR, con el operador '|'. La operación

PORTD |= 0b00001000;

Es la forma corta de escribir

PORTD = PORTD | 0b00001000;

En otras palabras: tomamos el valor actual del puerto D y le aplicamos el operador binario OR con un valor que solo tiene un bit puesto. Lo que está haciendo es poner a '1' un determinado bit del valor actual del puerto D. Y, finalmente, ese nuevo valor se almacena en el propio puerto D.

El resultado final es que hemos activado un único bit del puerto D, correspondiente al valor de PIN4.
 
#17
:eek: Es que poner explicación sobre lo que hacen esas instrucciones, sería como explicar el funcionamiento de los operadores en C.
Comprenderlos es algo básico en cualquier lenguaje.
D@rbytes gracias por anticipado, esta claro lo que dices, lo que quiero decir es que me gusta entender las instrucciones y algunas de ellas me cuesta un poco, por eso lo de si en alguna se acompaña con una pequeña informacion pues mejor, por lo menos para mi.

Se como funcionan los operardores pero no esta mal recordarlo.

Joaquinferrero a eso me referia, gracias por tu explicacion, asi lo entiendo mejor.
 
#18
Una cosa... me parece que hay un error en el código de D@rkbytes. Me parece que no contempla el caso de que pin == 0.

Debería ser algo así:
PHP:
int8 set_pin (int8 puerto, int8 pin) {		// pin [0,7]
    if(pin >= 0 && pin <= 7)
        return puerto |= 1 << pin;			// devolver el nuevo valor asignado
    else
        return 0;							// devolver 0 en caso de error
}
 
#19
Una cosa... me parece que hay un error en el código de D@rkbytes. Me parece que no contempla el caso de que pin == 0.

Debería ser algo así:
PHP:
int8 set_pin (int8 puerto, int8 pin) {        // pin [0,7]
    if(pin >= 0 && pin <= 7)
        return puerto |= 1 << pin;            // devolver el nuevo valor asignado
    else
        return 0;                            // devolver 0 en caso de error
}
Así es y tiempo más tarde lo noté.
 
Arriba