Usando interruptores instalados a través de los pines en el AVR

0

Tengo el siguiente diseño, los switches forman parte de una pieza de hardware existente que me gustaría reutilizar.

Me gustaría poder detectar las pulsaciones de los botones vol + y vol-. El plan era monitorear activamente sus estados mediante el uso de pull ups internos y el cambio de estados de pin individuales. Por ejemplo, para sondear el volumen, configuré PB0 como salida, estado bajo y PB4 como entrada con activación activa, esperaba leer un 0 cuando se presiona el interruptor.

Me gustaría saber si este es el enfoque correcto. Hasta ahora he estado luchando con esto y no funciona.

Esta es la función de sondeo que escribí:

uint8_t  read_button_volm(){
//VOLM
DDRB |=_BV(PB0);
PORTB &=~_BV(PB0);
DDRB &=~_BV(PB4);
PORTB |=_BV(PB4);
return ((PINB & (1<<PB4)) == 0);}

A modo de comparación, obtengo un comportamiento perfecto con el botón de silencio, usando el siguiente método:

uint8_t read_button_mute(){
DDRB &=~_BV(PB2);
PORTB |=_BV(PB2);
return ( (PINB & _BV(PB2)) == 0 );}

Como consideración adicional, los interruptores tienen una resistencia muy alta cuando se presionan, pero no parece ser un problema con el botón de silencio.

    
pregunta Polyphil

2 respuestas

0

Parece que tienes algo más aquí.

Si los interruptores están cableados como se muestra y la resistencia de un interruptor cerrado es inferior a 10K ohmios, entonces su read_button_volm() debería funcionar.

Empezaría por reducir las posibilidades.

  • ¿Devuelve la función 1 si corta manualmente PB4 a tierra con un puente?
  • ¿La función devuelve 1 si cortas el PB0 a tierra manualmente y presionas el botón?
  • ¿Qué voltaje ve en el pin PB4 con un voltímetro cuando se presiona el botón? Arriba?

Tenga en cuenta que la recuperación interna del ATTINY12 puede ser tan alta como 122K ohm ...

..yelvoltajedebeserinferiora0.1*VccenunodelospinesIOdigitalesquetambiéntienenlafunciónXTAL(PB4&PB3)...

Esto significa que para detectar de manera confiable un 0 en PB4 cuando tiene el pull-up conectado, necesita que la resistencia entre PB4 y masa sea menor que ...

122K / x < 0.1 
x < 12K 

Por lo tanto, su interruptor debe ser inferior a 12Kohm para funcionar de manera confiable en este pin de este chip con el pull-up habilitado.

Solutions

Si absolutamente debe obtener este diseño con estas partes para trabajar, hay algunos trucos que puede probar.

El primero que viene a la mente es usar el tiempo y la capacidad para detectar el interruptor cerrado.

Lo que harías en tu código es básicamente ...

  1. Habilitar el pull-up en PB0
  2. Establezca PB4 en salida, nivel BAJO.
  3. Establezca PB4 en ENTRADA, sin extracción.
  4. Calcule cuánto tiempo le tomará a la entrada del PB4 cambiar a ALTO con el botón presionado.

Básicamente, ha hecho un circuito RC a partir de PB0, el interruptor y la capacitancia del pin PB4 y está tratando de medir la R del interruptor midiendo la constante de tiempo de este RC.

Obtenga un montón de lecturas para este recuento de tiempo. Este es el tiempo que tarda la capacitancia en el PB4 en drenar por debajo del umbral de voltaje de 0 bits.

Ahora es posible que pueda comprobar si se presiona el botón repitiendo los pasos anteriores, pero utilizando los tiempos que recolectó para un interruptor cerrado para establecer un tiempo de espera. Si el pin se eleva antes del tiempo, entonces se presiona el botón, si no lo hace, entonces no se presiona.

Tenga en cuenta que este enfoque tiene algunas limitaciones ...

  1. Es muy sensible a otras rutas que podrían descargar el pin PB4 incluso cuando no se presiona el interruptor. Por ejemplo, un dedo húmedo o incluso algo de suciedad a lo largo de las trazas podría descargar fácilmente la capacitancia tan rápido como su interruptor cerrado, por lo que necesita mantener la placa limpia.

  2. Esto toma mucho más tiempo que solo verificar un valor de bit en un registro de PIN, por lo que no es eficiente en el tiempo.

  3. Realmente no puede establecer una interrupción de pin en el botón presionando debido a la secuencia involucrada. Hay maneras de evitar esto usando el perro guardián, pero son más complicados y menos eficientes en cuanto a energía que una interrupción de cambio de pin directo.

¡Avísanos si este enfoque te funciona!

    
respondido por el bigjosh
0
  

Hasta ahora he estado luchando con esto y no funciona.

el enfoque se basa en permitir que el débil levantamiento de los pines funcione.

Una vez configurado, puedes simplemente leer PORTB para detectar los pines. Una macro haría.

  BTN_DDR &=~(BTN_MUTE | BTN_VOLP | BTN_VOLM); //set the pins as input
  BTN_PORT |= (BTN_MUTE | BTN_VOLP | BTN_VOLM); //enable pull-up.

  ...

  tmp = (~BTN_PORTIN) & (BTN_MUTE | BTN_VOLP | BTN_VOLM); //read the pins, active low
    
respondido por el dannyf

Lea otras preguntas en las etiquetas