Guardar valor del puerto en una cadena

Hola gente, estoy teniendo un problema con la programación. Lo que pretendo hacer es que cuando el puerto a de un 16f877a tome algun valor este sea guardado en una cadena para después ser evaluado en otra función.
Alguien me puede dar alguna idea de como hacerlo.

Lo que se me ocurre es lo siguiente (por favor corriganme lo que este mal):

C:
...while(true){

         if(cl>0){                                                       //Mientras que la variable cl sea mayor a 0                                     
        lcd_gotoxy(1,1);                           
        printf(lcd_putc,"Ingrese %i letras",cl);    //Declaración en el lcd utilizando el valor de la variable cl
                                                  
        l=porta;                                                 //La variable l guarda el valor del puerto
      
        if(a<3){                                                 //Se evalúa el valor de a mientras que sea menor a 38
            letras[a]=l;
             a++;                                                      //Incremento en 1 la posición del array "letras"
             cl--;                                                  //Se resta uno a la variable cl
                                                                    //La posicion del vector sera igual al valor de a,
                                                                    //esto es así para que el vector letras se encarge
                                                                   //del almacenamiento de las letras ingresadas por el usuario
        }
    }
Luego de esto pensaba en usar la instrucción atoi para el array letras y así poder comparar el valor de cada posicion en un switch, pero antes de eso quisiera escuchar sus opiniones

Por cierto estoy usando ccs 5.070

Gracias saludos

Disculpen moderadores si me equivoco al publicar un nuevo tema pero a pesar de buscar y buscar no encontré un tema al respecto
 

D@rkbytes

Moderador
Creo que confundes una cadena con un array. Una cadena es un conjunto de caracteres y un array es una colección de variables.
Si quieres comparar el valor de un puerto, no necesitas usar atoi.
El valor límite de un puerto común es de 8 bits (Un Byte) 0 a 255, así que puedes comparar su valor directamente.

Mejor explica con detalle qué es lo que deseas hacer, porque yo entendí muy poco.
 
Hola Darkbytes. Lo que yo quiero hacer es una impresora braille.
De un teclado leer 38 caracteres y almacenarlos en un array, por cada vez que se ingrese una nueva letra la guardó en una posición del array hasta haber ocupado las 38 posiciones, luego debe evaluar el valor de cada posicion y asi saber que letra se presionó
Es importante mencionar que no se pueden ingresar caracteres mientras que se imprimen los caracteres.
La parte de control de motores la tengo controlada, pero esto que te nombro no.
Por cierto el teclado no es el clásico matricial 4x3 o 4x4 es uno casero de 8x4
 

D@rkbytes

Moderador
Me parece que puedes usar el principio de funcionamiento de la librería kbd.c
Ingresas al arreglo el valor de la tecla cuando --> if(tecla != 0)
Después de comprobar una tecla pulsada incrementas una variable para direccionar el vector.
 

D@rkbytes

Moderador
Disculpa que no te aclare pero estoy usando unos multiplexores en 64:1 inspirado en el aporte de Sr. Domo Codificador para teclado Hexadecimal con un multiplexor.
Me serviría igual esa librería para este teclado?
No lo creo, la librería que mencioné funciona directamente.
Una pregunta más. ¿Cómo puedo hacer para que un pin saqué el valor de una variable en su forma binaria

Por ejemplo:

El pin a quiero que saque 0101101
Cambiándolo de estado con una rutina muy sencilla.

Algo así:
C:
void ByteToBin(int8 value, int16 delay)
{
    for (int8 i = 0; i < 8; ++ i)
    {
        if (value & 0x80)            // Se comprueba si el bit MSB está en 1
            output_high(PIN_XX);    // Si este es 1, la salida será un 1
        else
            output_low(PIN_XX);        // Si este es 0, la salida será un 0
        
        delay_ms(delay);            // Esperar cierto tiempo (delay en milisegundos)
    
        value <<= 1;                 // Ir rotando un bit a la izquierda
    }
}
 
Disculpa Dark pero no entiendo porque ese valor de 0x80 y tampoco entiendo porque usar ese delay con el valor de esa variable y no usar el clasico delay del compilador?
Disculpa por mi ignorancia y por bombardearte con tantas preguntas
 
Ah, mira, yo tuve una idea parecida hace años

delay es una mala practica de programación, pero generalmente los compiladores C usan la función delay para atorar el programa X cantidad de tiempo, que no es muy bueno.

Digamos, delay_ms(10); atoramos el programa 10 ms.

Pero si queremos, podemos meter una variable para cambiar el delay.

variable=20; //vale 20
delay_ms(variable); //atoramos el programa 20 ms

Ahora, no me gusta la idea de usar un teclado como tal. ¿Por qué no usarlo como una impresora tal cual?
Bueno, eso sería si hicieras un programa vía PC que leyera un .txt y lo enviara a la impresora, que sería genial pero ocuparía mucho tiempo hacer 2 programas y que se comunicaran, pero bueno.

Puedes ver un puerto de un PIC que generalmente son de 8 bits, como un registro de memoria de 8 bits.
Es decir, puedes meter lo que hay en el puerto a una localidad de memoria, ya sea FLASH , RAM o EEPROM del PIC.

Una localidad de memoria RAM no es mas que un simple int8 de 8 bits o un simple char.

Para tratar a un dato de un puerto lo usamos de modo unsigned para que podamos ver como se guarda del 0 al 255 y no de 127 a -127

Ejemplo:
C:
unsigned char variable;   //declaro una simple variable si signo.
variable=portb;              //ahora mi variable tiene lo que estaba en el puerto.
Lo que hice fue tratar lo que hay en el puerto como si se tratara de una letra o un carácter y podemos tratar lo que hay en el puerto como si se tratara de texto.

Ahora, queremos hacer una cadena de caracteres o un array de caracteres:
C:
unsigned char variables[10];   //declaro un array.
int i=0;                                     //declaro un incremento en 0
void texto(); //funcion para guardar en el array.
{
    variable=portb; //meto en mi array lo que hay en el puerto B
    i++;                        //incremento el contador
    if(i>=10)  // para no desbordar mi array de 10 lo dejo en el ultimo valor que fue 10
    {
        i=10;   //si no lo quieres frenar puedes mandarlo a 0 es decir reescribes en el array
    }
}
Ahora en el main puedes mandar a llamar la función.

Ejemplo:
C:
void main()
{
    // declaraciones y cosas que debas hacer

    while (1)
    {
        //digamos que cuando pises un boton empiezas a grabar lo que al en el puerto al array
        texto();
        // escribimos en la LCD lo que esta grabado  y asi.
    }
}
 
Última edición por un moderador:

D@rkbytes

Moderador
Disculpa Dark, pero no entiendo. ¿Por qué ese valor de 0x80 y tampoco entiendo por qué usar ese delay con el valor de esa variable y no usar el clásico delay del compilador?
Es sencillo. Como cada vez se va rotando un bit hacia la izquierda, se hace una comparación del bit más significativo y para eso se usa una máscara AND con 0x80
O sea, 0b10000000 , de esa forma se comprueba si el último bit es uno.
El retardo es opcional y se usa el clásico delay_ms() del compilador, pero la rutina también pide un valor para asignarlo.
 
Trilo gracias por la respuesta diste luz a muchas de mis dudas y no puedo creer que hayas entendido mi mala explicacion del principio
Increiblemente el codigo que pusiste es muy parecido a como lo habia pensado en un principio pero crei que no iba a funcionar
Dark hay una sola cosa que no entiendo de lo que me pusiste
Qué es una máscara y para que me sirve?
 
pues mira no es mala onda ni quiero ofender a nadie

pero por que se atreven a hacer programas en microcontroladores sin antes leer algo de programacion en C
bueno me refiero a C para computadoras en general es lo mismo aplicandolo a microcontroladores.

un libro de programacion en C puede orientarte bastante con las dudas.

pero bueno una mascara es una operacion logica es decir tenemos AND , OR, NOT y XOR

un ejemplo de una mascara AND muy util

tenemos el numero binario y queremos solo los ultimos 4 bits

10101001
usando una mascara AND solo dejamos pasar los ultimos 4 bits

10101001
AND
00001111
el resultado es:
00001001

si a eso mismo le aplicamos una NOT quedaria asi:
11110110
si le aplicamos una OR con un binario 11111111
quedaria asi:
11111111


un ejemplo con una AND seria este:

char variable1 = 0b10101001;
char variable2;

variable2= 10101001 & 0b00001111; // le hacemos una AND a la variable de la izq.

ahora la variable2 vale : 00001001
eso es util cuando queremos usar una parte del puerto y otra no, recortar variables de 16 bits y meterla en 2 registros de 8 bits como un int16 meter el dato en una eeprom.

cuando queremos multiplexar , etc.
 
Gracias Darkbytes y TriloByte por toda la ayuda
Disculpen si los moleste
Ya mismo me pondré a repasar todo lo que vi hasta ahora así la próxima vez vez que me surja un problema no me agarra tan desprevenido
Gracias nuevamente y saludos
 
Ejemplo:
C:
unsigned char variable;   //declaro una simple variable si signo.
variable=portb;              //ahora mi variable tiene lo que estaba en el puerto.
Lo que hice fue tratar lo que hay en el puerto como si se tratara de una letra o un carácter y podemos tratar lo que hay en el puerto como si se tratara de texto.

Ahora, queremos hacer una cadena de caracteres o un array de caracteres:
C:
unsigned char variables[10];   //declaro un array.
int i=0;                                     //declaro un incremento en 0
void texto(); //funcion para guardar en el array.
{
    variable=portb; //meto en mi array lo que hay en el puerto B
    i++;                        //incremento el contador
    if(i>=10)  // para no desbordar mi array de 10 lo dejo en el ultimo valor que fue 10
    {
        i=10;   //si no lo quieres frenar puedes mandarlo a 0 es decir reescribes en el array
    }
}
Ahora en el main puedes mandar a llamar la función.

Hola soy yo nuevamente, ya se soy pesado, pero resulta que en la línea donde igualo el array al valor del puerto me da error

C:
unsigned int caracteres[38];

void adl(flag_adllcd){

    if(flag_adllcd==1){

        caracteres=porta;
        
        c++;
        d++;

        if(c>=38){

        c=38;
        }

        if(d==16){

        d=0;
        }
    }
}
El error que me tira es *** Error 167 "Test save data in an array.c" Line 184(14,19): Assignment invalid: lvalue is READ ONLY

A que creen que se debe el error??
 
Mal es que debes tratar de meter en el Arrau lo que hay en el puerto
Ejemplo
unsigned char caracteres[10]; //declaro un Array
de 10

caracteres[i ]=porta;
i++;[/I]

Es decir por cada metida de datos en el Array haces un incremento empiezas en 0 y terminas en dónde acaba el Array.

O si usas un apuntador es igual solo que el apuntador se va a llenar.

Cuando haces un recorrido en el Array acabas hasta donde defines el Array.

Si usas apuntador acabas hasta donde es NULL.[/i]
 

Dr. Zoidberg

Well-known-Papá Pitufo
El error que me tira es *** Error 167 "Test save data in an array.c" Line 184(14,19): Assignment invalid: lvalue is READ ONLY
A que creen que se debe el error??
A que se debe el error??? A que no tenés ni idea del lenguaje C.
Mejor andá a estudiar antes de pedir que te resuelvan un problema que se debe a tu absoluto desconocimiento del tema.
 

Arriba