Autor Tema: Alguien que por fa me explique la lógica de las definiciones enum en este código  (Leído 1909 veces)

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

Desconectado vra

  • PIC10
  • *
  • Mensajes: 27
Hola a todos, cómo están. En esta oportunidad les traigo un código adaptado para filtral el rebote de los botones mediante programa, el mismo está basado en un filtro digital el cual no recuerdo su nombre pero si se que es básicamente una suma ponderada durante aproximadamente unos 200 o 300 ms -depende de quien lo implemente.

El código es el siguiente:

Código: [Seleccionar]
enum btnStat_t{
    high,
    low,
    rising,
    falling,
};

enum btnStat_t doDebounce(uint8_t *state, volatile bool value) {
       uint8_t old  =  *state & 0x7F;
       bool flag = (*state & 0x80)? true : false;
       enum btnStat_t btnStd = (true == flag)? low : high;
 
       // Digital filter part, value = (old * .75) + (new * .25)
       old -= (old >> 2);                     // 1 - (1/4) = .75
       old += value? 0x1F : 0x00;             // if bit set, add .25
 
       // Software schmitt trigger
       // Newly detected rising edge
       if ( (true == flag) && (old > 0x70) ) {
               flag = false;
               btnStd = rising;
       }
       // Newly detected falling edge
       else if ( (false == flag) && (old < 0x07) ){
               flag = true;
               btnStd = falling;
       }
 
       // Update the state variable
       *state = (old & 0x7F) | ((flag & 0x01) << 7);
 
       // Return the state
       return btnStd;
}

La función que más me interesa de las dos es "enum btnStat_t doDebounce(uint8_t *state, volatile bool value)", yo entiendo perfectamente que hacen las funciones de filtro digital, shmitt trigger y casi todo el código interno de la función excepto lo siguiente:

no entiendo por qué definen en la cuarta línea de la segunda función el enumerador de la siguiente forma:

Código: [Seleccionar]
       enum btnStat_t btnStd = (true == flag)? low : high;

y tampoco entiendo por qué la función es definida como un enumerador de la forma en que está con argumento.

Alguien podría explicarme eso por favor?

Muchas gracias de antemano por la ayuda brindada.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
El porque se hizo asi... seguramente sea porque se programó correctamente (para protegerse de cualquier modificación del código).
O Tal ves la idea de separar correctamente lo que es un enum de un bool, ya que normalmente en C++ estan bien diferenciados. Y capaz sea un port de algun codigo en C++.

Lo primero que podrias pensar es...... porque no asigno el valor flag directamente a btnStd? Seria genial ya que high = 0, low = 1, rising = 2, etc.

Y es una conversión directa... Pero que pasaría si algún día alguien se le ocurre agregar un estado mas en el btnStat_t, o cambiar el orden, ejemplo:

Código: C
  1. enum btnStat_t{
  2.     pepe,
  3.     high,
  4.     low,
  5.     rising,
  6.     falling,
  7. };
  8.  
  9. enum btnStat_t{
  10.     rising,
  11.     falling,
  12.     high,
  13.     low,
  14. };

Y ahora tu codigo haria cualquier cosa. Ya que tu codigo que esperaria que ese 0 sea high, es ahora pepe o rising.
Esto hace al codigo complicado de mantener, ya que tenes que recordar que no podes modificar el enum, o tenes que agregarlo al final y hace del codigo altamente dependiente del orden que este el enum.

Pero asi como esta, no hay problema que se cambie todo lo que quiera.

Hacer:

Código: C
  1. enum btnStat_t btnStd = (true == flag)? low : high;

Es simplemente una forma resumida de hacer:

Código: C
  1. enum btnStat_t btnStd;
  2.  if(true == flag) {
  3.      btnStd = low ;}
  4.  else {
  5.      btnStd= high; }

NO ESTA DEFINIENDO EL ENUM! esta definiendo btnStd que ES un ENUM definido como btnStat_t.

Ya que si observas y seguis el codigo, si ningun if se cumple tenes que retornar btnStd... Por lo que si o si necesitas inicializarlo con un valor correcto. Y este valor depende de flag.

Citar
y tampoco entiendo por qué la función es definida como un enumerador de la forma en que está con argumento.

Si te referis a esto:

enum btnStat_t doDebounce(uint8_t *state, volatile bool value)

Es porque estas devolviendo btnStd, que es un enum btnStat_t
La mayoria usa typedef para no escribir todo el enum btnStat_t (lo ves mucho tambien con las estructuras). Es decir podrias haber realizado luego del enum esto:

Código: C
  1. typedef enum btnStat_t btnStat;
(Definiendo un nuevo tipo que se llama btnStat y que es lo mismo que enum btnStat_t
Y luego:

Código: C
  1. btnStat doDebounce(uint8_t *state, volatile bool value)
  2. //y
  3. btnStat btnStd = (true == flag)? low : high;
« Última modificación: 30 de Mayo de 2020, 22:33:51 por KILLERJC »

Desconectado vra

  • PIC10
  • *
  • Mensajes: 27
Disculpen la tardanza pero por alguna razón no me están llegando las notificaciones de correo, en lo que analice y entienda sus respuestas les contesto.


 

anything