¿Qué es golpear un poco

26

Soy nuevo en la programación de microcontroladores. Estoy usando el controlador ATmega32-A y el compilador CodeVisionAVR. Estoy usando el generador de forma de onda (AD9833) para generar una señal sinusoidal utilizando la comunicación SPI. Soy capaz de generar la onda sinusoidal con éxito. Ahora estoy pasando esa señal al sensor. La salida del sensor se selecciona a través del multiplexor y se envía al ADC. Ahora quiero leer los valores de ADC usando la comunicación SPI. He intentado mucho configurar los registros de ADC. Aún así no está funcionando. Para ver el código de comunicación SPI, eche un vistazo a mi publicación anterior Configuración de registros ADC mediante comunicación spi . Estoy usando la comunicación USART (RS232) para imprimir valores en la PC (PuTTY).

Alguien me aconsejó que usara golpes de bits. Soy nuevo en ese concepto. ¿Alguien puede proporcionarme un código de ejemplo de bits de comunicación SPI? ¿Cómo comenzar ese procedimiento? ¿Alguien puede proporcionarme un buen material? ¿Necesito algún hardware externo?

He escrito esto, incluidas las conexiones de pin:

#define ADC_CS PORTB.3
#define MOSI PORTB.5
#define MISO PINB.6
#define SCK PORTB.7

void send_8bit_serial_data(unsigned char data)
{
    int i;  
    ADC_CS=0;
    for (i = 0; i < 8; i++)
    {
        // consider leftmost bit
        // set line high if bit is 1, low if bit is 0
        if (data & 0x80)
            output_high(PORTB.5);
        else
            output_low(PORTB.5);

        // pulse clock to indicate that bit value should be read
        output_low(PORTB.7);
        output_high(PORTB.7);

        // shift byte left so next bit will be leftmost
        data <<= 1;
    }

    // deselect device
    ADC_CS=1;
}
verendra
fuente
Su código se ve bien, aparte de que la salida de reloj baja debe estar antes de la configuración de bits y el retraso. Necesita un par de demoras para arreglar el tiempo (por lo tanto, el reloj bajo / alto es aproximadamente el mismo período) Eche un vistazo al código de Steven nuevamente. Si desea leer también, deberá agregar el código para eso también.
Oli Glaser
@OliGlaser ¿Puedo usar directamente este código en lugar del código SPI normal para configurar los registros?
verendra
@verendra: no estoy seguro de qué quiere decir con "código SPI normal". Si quiere decir SPI en lugar de hardware, entonces al ADC no le importa cómo se generan los pulsos siempre que estén de acuerdo con el protocolo y el tiempo.
Oli Glaser

Respuestas:

25

El golpeteo de bits es crear toda la serie de pulsos en el software, en lugar de depender de una pieza de hardware dentro del microcontrolador.

Muchos microcontroladores tienen un SPI de hardware, y todo lo que tiene que hacer es escribir un byte en el registro de salida, y el controlador SPI desplazará los datos y, al mismo tiempo, recibirá datos del esclavo. Puede obtener una interrupción cuando se completa la transferencia y luego leer los datos recibidos.

Pero algunos microcontroladores no tienen el hardware SPI a bordo y luego tiene que simularlo haciendo todo manualmente. SPI tiene varios modos diferentes, usaré este diagrama de pulso como ejemplo:

ingrese la descripción de la imagen aquí

Entonces, si bien un controlador SPI dedicado se encarga de todos los pulsos, el cambio de datos y el tiempo, al realizar un bit-banging, debe tomar todas las medidas usted mismo:

Make Slave Select low  
Short delay
Do 8 times
  Make the SCK (Serial Clock) pin low 
  Make the MOSI (Master-Out-Slave-In) pin high or low depending on bit 7 of the data  
  Add brief delay  
  Make the SCK output high
  Read MISO (Master-In-Slave-Out) pin
  Shift received data left, and shift the bit just read in as bit 0   
  Add brief delay  
  Shift the data byte 1 bit left
Make Slave Select high again  

El SPI de bit-banging es relativamente simple, el código para I2C de bit-banging, por ejemplo, será más complejo, y necesitará un temporizador de alguna manera si desea golpear el protocolo UART.

stevenvh
fuente
2
¿Puede proporcionar un código c de muestra?
verendra
1
@verendra - Agregué un ejemplo de pseudocódigo, que deberías poder traducir fácilmente a C.
stevenvh
Estoy generando con éxito Wavefrom usando la comunicación SPI. Tengo un problema con la lectura de valores ADC usando solo SPI. Tengo que usar bit banging para ambos o solo para leer los valores de ADC. ¿Puedes echar un vistazo a mi código para enviar 8 bits, es escribir? pero estoy confundiendo cómo usarlo. ¿Puedo colocar este código directamente en lugar de mi código SPI para configurar el registro?
verendra
@Steven: el diagrama que muestra es MSB primero, por lo que debe desplazarse hacia la izquierda desde 7 y hacia la izquierda desde 0. Sé que no hay un estándar, por lo que puede ser LSB primero, pero creo que la mayoría de los periféricos SPI lo hacen de esta manera .
Oli Glaser
2
@Oli - buen punto, me perdí eso. Lo arreglaré, gracias por los comentarios. La razón por la que no hay un estándar es que no importa siempre que el número de bits transferidos sea igual a la longitud del registro de desplazamiento. Recientemente, algunos microcontroladores (como NXP Cortec-M3) tienen un registro de desplazamiento de longitud variable, y luego la dirección puede ser importante. IIRC en el AVR puede seleccionar MSB primero o LSB primero.
stevenvh
6

Bit-banging se refiere al concepto de que las señales que salen o entran en un dispositivo sean generadas / muestreadas por software en lugar de hardware. Obviamente, se requiere un poco de hardware, pero cuando se utiliza el bit-banging, el único hardware para cada salida es un pestillo que el software puede establecer o borrar explícitamente, y el único hardware para cada entrada es una interfaz para permitir que el software pruebe si es alto o bajo (y normalmente ejecuta una rama condicional para un estado pero no para el otro).

La velocidad máxima que se puede lograr con bit-banging generalmente será una fracción de lo que se podría lograr con hardware especialmente diseñado, pero fuera de las limitaciones impuestas por la velocidad del procesador, bit-banging es mucho más versátil y puede usarse en circunstancias donde el hardware de uso general no es del todo adecuado y el hardware de uso especial no sería rentable.

Por ejemplo, muchos controladores tienen un puerto "estilo SPI" que se comporta esencialmente de la siguiente manera: cuando se escribe un byte en un determinado registro, el hardware generará una cierta cantidad de pulsos de reloj (normalmente ocho), registrando un bit de datos en el borde delantero de cada pulso de reloj y muestreo de un bit de datos entrantes en el borde posterior. En general, los puertos de estilo SPI de los controladores permitirán configurar una variedad de características, pero en algunos casos puede ser necesario interconectar un procesador con un dispositivo que hace algo inusual. Un dispositivo puede requerir que los bits de datos se procesen en múltiplos que no sean ocho, o puede requerir que los datos se emitan y muestreen en el mismo borde del reloj, o puede tener algún otro requisito inusual. Si el hardware particular en el controlador que uno está usando puede soportar los requisitos precisos de uno, genial (algunos proporcionan números configurables de bits, temporización de transmisión y recepción configurable por separado, etc.) Si no, el golpeteo de bits puede ser útil. Dependiendo del controlador, los golpes de bits de una interfaz SPI-ish a menudo demorarán entre 2 y 10 veces más que dejar que el hardware lo maneje, pero si los requisitos no se ajustan al hardware que uno tiene, el intercambio de datos más lento puede ser mejor que no poder hacerlo en absoluto.

Una cosa importante a tener en cuenta con los diseños de bit-banged es que son más simples y robustos en circunstancias en las que los dispositivos con los que se comunican están esperando que el controlador de bit bitging genere todos sus tiempos, o donde el controlador podrá espere, sin distracciones, a que llegue un evento, y donde podrá hacer todo lo que necesita hacer con ese evento antes de que llegue cualquier otro evento sobre el que deba actuar. Son mucho menos robustos en circunstancias en las que un dispositivo necesitará poder reaccionar a estímulos externos dentro de un período de tiempo relativamente corto, pero no puede usar el 100% de su energía para observar dichos estímulos.

Por ejemplo, supongamos que uno desea que un procesador transmita datos de estilo UART en serie a una velocidad muy alta en relación con su velocidad de reloj (por ejemplo, un PIC que ejecuta 8.192 instrucciones por segundo desea emitir datos a 1200 bps). Si no hay interrupciones habilitadas, dicha transmisión no es difícil (reloj un bit cada siete ciclos de instrucción). Si un PIC no estuviera haciendo nada más que esperar un byte de datos entrante de 1200bps, podría ejecutar un ciclo de 3 ciclos esperando el bit de inicio, y luego proceder a registrar los datos a intervalos de siete ciclos. De hecho, si un PIC tenía un byte de datos listo para enviar cuando llegó un byte de datos entrante, siete ciclos por bit serían suficiente tiempo para que el PIC envíe su byte de datos simultáneamente con la lectura del byte entrante. Igualmente,si tal respuesta hubiera fijado el tiempo relativo a la transmisión original . Por otro lado, los PIC no tendrían forma de manejar las comunicaciones bit-bang de tal manera que se permitiera a cualquiera de los dispositivos transmitir en cualquier momento que lo considerara conveniente (en lugar de tener un dispositivo que pudiera transmitir cuando viera encajar y hacer lo que quiera cuando no esté transmitiendo, y un dispositivo que tendría que pasar la mayor parte de su tiempo haciendo nada más que esperar las transmisiones del primer dispositivo).

Super gato
fuente