Cómo eliminar múltiples, si no, para manejar los datos fácilmente [cerrado]

4

Estoy haciendo un proyecto que tiene un tablero hecho a medida basado en PIC32 MCU . Tiene 30 Inputs y 10 Output . Tengo que monitorear las entradas y enviar información a UART. Cada entrada se define un código. Por ejemplo: si la entrada 1 está ACTIVADA, entonces los datos que se enviarán son 11 {'1'--> Input 1, '1' --> ON} . Si la entrada 1 está en OFF, los datos a enviar son 10 {'1'--> Input 1, '0' --> OFF} . De manera similar, la entrada número 24 está activada, luego 241 , si está desactivada, entonces 240 y lo mismo se aplica a todas las entradas.

Ahora los datos finales que se enviarán a través de UART contendrán información sobre todas las entradas:

10 20 30 41 50 61.....271 280 291 300 

Como soy un principiante en programación, lo que he hecho para lograr la sintaxis anterior es que he definido variables para cada entrada.

char input1ON[]  = "11";
char input1OFF[] = "10";
bool input1Stat  =  false;

char input2ON[]  = "21";
char input2OFF[] = "20";
bool input2Stat  = false;

e igual para completar 30 entradas. Ahora en función principal:

if(PORTDbits.RD6 == 1)  // if input1 is high
{
  input1Stat = true; //make input1 status true
}
if(PORTDbits.RD6 == 0) //if input1 is low
{
  input1Stat = false; //make input1 status false
}
if(PORTDbits.RD7 == 1)  // if input2 is high
{
  input2Stat = true; //make input2 status true
}
if(PORTDbits.RD7 == 0) //if input2 is low
{
  input2Stat = false; //make input2 status false
}
/*
* same goes for rest of the inputs
*/

luego de todas las declaraciones if, estoy comprobando si input1stat es verdadero y luego lo escribo, como a continuación:

if(input1Stat == true) //if input 1 status is true
{
  strcat(inputs,input1ON); //concatenate input1ON variable with inputs variable 
}
else
  strcat(inputs,input1OFF); //concatenate input1OFF variable with inputs variable 

if(input2Stat == true) //if input 2 status is true
{
  strcat(inputs,input2ON); //concatenate input2ON variable with inputs variable 
}
else
  strcat(inputs,input2OFF); //concatenate input2OFF variable with inputs variable 

Al final, solo estoy poniendo inputs en UART:

putsUART1(inputs);

de modo que, como resultado, obtengo la cadena de datos anterior en UART. Pero el problema es que hay muchas otras declaraciones en mi código que hacen que el código sea ilegible. Creo que puede haber alguna otra forma de manejar esto. Como soy un principiante, no sé cómo eliminar todas estas afirmaciones si no. Cualquiera puede dar una demostración para eliminar todas las afirmaciones if else. Gracias.

EDIT

La entrada 1 y la entrada 2 no son más que PORTDbits.RD5 & %código%. Usé la entrada 1 y la entrada 2 solo para la demostración. He hecho los cambios.

    
pregunta user007

6 respuestas

4

Cuando trato con un conjunto de entradas que son todos pines individuales que pueden tener asignaciones arbitrarias a pines de chip físico, lo primero que hago es crear una función que se asigna desde el número de entrada lógica al pin físico:

bool pin_read (int n)
{
  switch (n) {
  case 0: return PORTDbits.RD6;
  case 1: return PORTDbits.RD7;
  /* ... etc. */
  }
}

Tenga en cuenta que dicha función normalmente sería una función en un módulo pin compilado por separado que también contiene funciones como pin_write() y pin_direction() . Utilizo una convención de denominación <module>_<method>() para mis funciones de C, que realmente ayuda a hacer un seguimiento de las cosas a medida que el proyecto crece.

Una vez que tenga dicha función, todo lo demás se puede manejar con bucles. Para capturar el estado de todos los pines:

for (i=0; i<N_INPUTS; ++i) {
  inputStat[i] = pin_read(i);
}

Para imprimir el estado capturado anteriormente:

for (i=0; i<N_INPUTS; ++i) {
  sprintf (temp_buffer, " %d%d", i, inputStat[i]);
  putsUART1(temp_buffer);
}
putsUART1("\n");
    
respondido por el Dave Tweed
2

Ni siquiera deberías necesitar declaraciones en absoluto.

input2Stat = input2;

Asignará el valor si es falso (0) o verdadero (cualquier cosa no es 0)

sin embargo, en general, la mayor parte de su desorden es por comentarios redundantes y saltos de línea. No necesita el mismo comentario en cada sección si el código es simple para leer, o el comentario se puede aplicar a todo, simplemente déjelo en claro.

Puede compactar la instrucción if en una línea si solo hay una instrucción que sigue, omitiendo los corchetes. Lo mismo para otra cosa.

 if (input2 == true) input2Stat = true;
 else input2Stat = false;
    
respondido por el Passerby
1

Suponiendo que esté muestreando la entrada y enviándolo al mismo tiempo en un micro pequeño, normalmente no me molestaría en concatenar la cadena de salida, lo enviaría directamente a la UART sobre la marcha. Tal vez podrías escribir una función como esta:

void send_in_state(uint8_t io_number, bool val)
{
    if (io_number >= 10)
        putcUART1(io_number / 10 + '0');
    putcUART1(io_number % 10 + '0');
    if (val)
        putcUART1('1');
    else
        putcUART1('0');
    putcUART1(' ');
}

Acabo de usar putcUART1 como marcador de posición para que la función envíe un solo carácter, probablemente se llame otra cosa. Luego en el código principal tendrías algo como:

send_in_state(1, PORTDbits.RD6);
send_in_state(2, PORTDbits.RD7);
// etc...

Si desea realizar un muestreo en un punto anterior antes de enviarlo, aún podría utilizar la función anterior pero guardar los estados de entrada antes:

bool save_input1 = PORTDbits.RD6;
bool save_input2 = PORTDbits.RD7;
// ...
send_in_state(1, save_input1);
send_in_state(2, save_input2);
    
respondido por el PeterJ
0

Para esta construcción:

if(input1 == true)  // if input1 is high
{
  input1Stat = true; //make input1 status true
}
if(input1 == false) //if input1 is low
{
  input1Stat = false; //make input1 status false
}

Suponiendo que input1 solo puede ser true o false y no un tercer estado, simplemente puede escribir:

input1Stat = input1 ? 1 : 0;
input2Stat = input2 ? 1 : 0;
...

Esto ya es mucho más fácil a la vista, pero probablemente se compile en el mismo código. Más adelante explicaré por qué estoy usando 1/0 en lugar de verdadero / falso.

if(input1Stat == true) //if input 1 status is true
{
  strcat(inputs,input1ON); //concatenate input1ON variable with inputs    variable 
}
else
  strcat(inputs,input1OFF); //concatenate input1OFF variable with inputs variable

De nuevo, solo hay dos estados. Esto puede ser reemplazado con:

const char *input1Stat[2] = { "10", "11" };
const char *input2Stat[2] = { "20", "21" };
....
strcat( inputs, input1msg[input1Stat] );
strcat( inputs, input2msg[input2Stat] );

Dado que input1Stat ahora es 0 o 1, seleccionará una de las dos entradas en la matriz de punteros de cadena.

Como se indicó en un comentario a otra respuesta, en un sistema más grande con punteros "reales" y similares, se implementaría con una matriz de punteros. En un microcontrolador como el PIC, los accesos como este pueden convertirse en una gran cantidad de código, y a menudo me abstengo de ocultar el código demasiado.

Si no quieres repetirte, puedes manejar cada entrada en un lugar, colocarla en una macro y luego escribir la macro tantas veces como sea necesario.

    
respondido por el pipe
0

Crea una palabra codificada en bits a partir de tus entradas. Algo como:

unsigned int encodedinput = input1 ? 1 : 0 +
                            input2 ? 2 : 0 +
                            input3 ? 4 : 0 +
                            input3 ? 8 : 0 + ...etc

Luego puedes usar un bucle para recorrer los bits individuales convirtiéndolos en cadenas

for (i = 0 ; i < nobits ; i++)
{
 sprintf (tempbuffer, "%d", i) ;
 strcat (str, tempbuffer) ;
 sprintf (tempbuffer, "%d", (encodedinput >> i) & 1) ;
 strcat (str, tempbuffer) ;
}

O, simplemente envíe la palabra codificada en bits :-)

    
respondido por el Icy
0

Bueno, en primer lugar esto:

if(input1 == true)  // if input1 is high
{
  input1Stat = true; //make input1 status true
}
if(input1 == false) //if input1 is low
{
  input1Stat = false; //make input1 status false
}

Tiene exactamente el mismo efecto que este:

input1Stat = input1;

Eso te ahorrará algo de espacio. De hecho, es posible que no necesite la variable input1Stat en absoluto. ¿Quizás pueda usar input1 directamente en el otro bloque de código? La única diferencia es exactamente cuando se mide el valor del pin.

En segundo lugar, no necesita códigos separados para cada estado de cada pin. Puedes construirlos automáticamente a partir del número de pin y 0 o 1 para activar o desactivar. Así que puedes hacer algo como

// For pin one
strcat(inputs, "1");
if(input1Stat == true) 
{
  strcat(inputs,ON); 
}
else
{
  strcat(inputs,OFF);
}
strcat(inputs," ");
// and the same for the other pins

Donde has definido ON y OFF como "0" y "1" .

En tercer lugar, en el momento en que esté copiando casi el mismo código para cada pin, estará mejor repitiendo esos pines. Lo único difícil es cambiar el número de pin de un char a una cadena, y al colocar los valores de pin en algún lugar puede acceder a ellos por número. La función sprintf está diseñada para hacer cosas int-to-string y mucho más, pero es una cosa complicada con mucha sobrecarga ... así que tal vez no sea la mejor opción para un PIC. Vea si la función itoa está disponible en su entorno (puede depender de su complaciente). Si lo es, entonces puedes escribir

bool inputStats[] = {input1, input2 ...};

for (char pin=1; pin<30; pin++)
{
    char buffer[3];
    itoa(pin, buffer, 10);
    strcat(inputs, buffer);
    if(inputStats[pin-1] == true) 
    {
      strcat(inputs,ON); 
    }
    else
    {
      strcat(inputs,OFF);
    }
    strcat(inputs," ");
}
    
respondido por el Jack B

Lea otras preguntas en las etiquetas