¿Cómo hacer un contador de ceros y unos?

Estoy tratando de escribir un contador de ceros y unos en ensamblaje con el AVR ATmega328P.

Para elegir entre los unos y los ceros, tengo un interruptor en PC5.

Para la entrada hay 8 interruptores conectados a PORTB y uno a un pin en PORTC.

Los pedacitos son así:

  • PC1 (bit más significativo)
  • PB7
  • ... PB0 (bit menos significativo)

Para la salida, tengo que enviar los ceros o el conteo de unos a una pantalla de 7 segmentos.

Ignorar SW2

Estoy tratando de leer PORTB, use una máscara (ANDI) para obtener el bit menos significativo, compare si es uno o más bajo (cero), agregue uno a un registro dependiendo si es cero o uno a otro registro si es uno, cambie el entrada (LSR) para seguir comprobando y así sucesivamente.

Leer el interruptor de control e imprimir la pantalla no es un problema, pero encontré algunas circunstancias en las que se complica un poco. Por ejemplo, ¿cómo concatenar en un registro el valor de PORTB y el pin en PORTC?

Estoy tratando de usar un ciclo y en algún momento tendría que verificar si ya tengo los 9 bits y enviar el conteo, ¿debería usar un contador?

Investigué formas más fáciles de implementar este problema, pero no encontré información relevante.

Begin:
    IN R23, PINB
Jump:
    ANDI R23, 0x01
    CPI R23,0x01
    BRLO Zero
    BREQ One
Shift:
    IN R23, PINB
    LSR R23
    RJMP Jump
Zero:
    INC R18
    INC R16 //counter??
    RJMP Shift
One:
    INC R17
    INC R16//counter??
    RJMP Shift

La contraidea no está completa, solo un ejemplo donde estaría la actualización. Para el contador (INC R16), también me falta el bit en PC0. Pude leer después de leer PORTB, pero estaba tratando de usar una implementación más elegante. Sé que tengo que comprobar el contador al principio para ver si está hecho y enviar la salida si es así.

Muchas gracias por la ayuda. (:

Respuestas (3)

Examinar el LSB, clasificarlo como 0 o 1, luego cambiar uno a la derecha y pasar al siguiente bit parece una estrategia razonable. No está claro en qué está atascado exactamente, pero su enfoque básico tiene sentido.

Otra forma de hacer esto si la velocidad fuera muy importante es usar los 8 bits como índice en una tabla, que luego te dice explícitamente cuántos 0 y cuántos 1 hay en el byte. En realidad, solo necesita decirte uno de ellos. El otro es el 8-N.

Si uno tiene un valor de byte b, puede contar rápidamente la cantidad de bits que se establecen utilizando la siguiente estrategia:

  1. Comience con b = ((b & 0xAA)>1) + (b & 0xAA);. Los bits 6-7 bahora tendrán un valor de dos bits que contiene el número de bits establecidos en {6,7}; los bits 4-5 indicarán cuántos bits en {4,5} se establecieron, etc.
  2. Entonces realiza b = ((b & 0xCC)>>2) + (b & 0x33);. Los bits 4-7 bahora tendrán un valor de cuatro bits que contiene el número de bits establecidos en {4,5,6,7}, y los bits 0-3 tendrán un valor de cuatro bits que contiene el número de bits establecidos en { 0,1,2,3}.
  3. Finalmente, b = (b >> 4) + (b & 0x0F).Now bcontendrá el número total de bits que se establecieron.

El enfoque también es compatible con cantidades de 16 o 32 bits; con cantidades de 16 bits requerirá cuatro pasos, y con cantidades de 32 bits requerirá cinco.

No tienes suficiente reputación para comentar. Pero, ¿podría simplemente sumar todas las entradas? El resultado será un número de unos.