Cómo cambiar 16 bits rápidamente en la placa arduino

7

Estoy codificando un sistema que necesita cambiar 16 bits rápidamente desde una variable uint16_t a dos registros de desplazamiento 74HC595 emparejados. Estoy ejecutando el código en un Arduino (atmega328 @ 16Mhz) y el shiftOut en el Arduino es demasiado lento. La función digitalWrite de las bibliotecas también es lenta.

La mejor idea que se me ocurrió es un bucle for que recorre todos los 16 bits de la variable y escribe 1/0 en el pin de datos, establece el bit de reloj lo más corto posible y luego pasa al siguiente bit de la variable.

¿Es esta la solución más rápida y, de ser así, cómo hago un bucle a través de los bits de las variables uint16_t en c ++?

    
pregunta tirithen

4 respuestas

8

Esto es lo suficientemente simple con la biblioteca SPI.

Conecte su entrada de registro de desplazamiento al pin MOSI (Master Out, Slave In) - Digital pin 11 - y tendrá buenas transferencias rápidas.

Habrá un retraso muy leve entre los 8 bits superior e inferior de cada palabra transmitida.

Por ejemplo:

#include <SPI.h>

void begin()
{
    SPI.begin();
}

void loop()
{
    unsigned int val;

    val = rand()%0xFFFF; // Generate a random 16 bit number

    SPI.transfer(val >> 8);  // Output the MSB first
    SPI.transder(val & 0xFF); // Followed by the LSB

    delay(1000);  // Wait a sec...
}
    
respondido por el Majenko
8

Si desea utilizar una transferencia de datos de software, no desea utilizar las funciones digitalWrite. Son muy lentos, esto se debe a que necesitan traducir el número de pin a través de una tabla a un registro real (PORTx), enmascarar el bit correcto y cambiarlo. Todos los pines en arduino están asignados a números, mientras que debajo pueden pertenecer al puerto A, B, C, e incluso más en la versión MEGA del Arduino.

Es mucho más rápido modificar directamente los registros AVR. Como PORTB y a-like. De hecho necesitas pasar por cada bit. Me gustaría crear un bucle for de 0 a 15 y hacer un poco de cambio y enmascaramiento.

Como no sé, no puedo dar un ejemplo exacto. Sin embargo, probablemente se verá muy cerca de esto. Con 'muy cerca' quiero decir que esto no está probado. %pr_e%

// paso del bit 0 al 15  para (UI08_t i = 0; i < 15; i ++)  {   // Verificar el contenido de este bit de datos.   // Desplazar datos para que este bit sea LSB, y enmascararlo con 1 para que solo veamos este bit.   if ((datos > > i) & 0x1 == 1)   {     // establecer el pin de datos alto, como PORTB | = 1 < < 4;     // cuando el pin 4 de portB es tu pin de datos     // Hacer un OR hará que el pin B4 siempre sea alto   }   más   {     // establece el pin de datos bajo, como PORTB & = ~ (1 < < 4);     // Hacer un AND con el inverso significa que todos los pines, excepto B4, se mantendrán sin cambios   }

// Generar clk para 'transferir' el bit:   // Es probable que esto se pueda hacer usando PORTB ^ = 1 < < 5; (pin B5 en este ejemplo)   // ^ = alternar   // Haz esto DOS VECES, entonces CLK va alto / bajo  }

// como está utilizando un registro de desplazamiento, es posible que también desee alternar el pin LATCH .. } Para averiguar qué número de pin de hardware (¡no asumas que el pin 4 es el pin B4 o A4!) Necesitas mirar el esquema de Arduino.

He ejecutado un código similar en un PIC32 (funciona a 80MHz). El PIC32 pudo hacer esto a aproximadamente 1,5 MHz, pero se ejecutaron algunas líneas de código adicionales en main () para calcular una nueva salida. Sin embargo, se puede hacer muy rápidamente.

    
respondido por el Hans
5

Necesita usar el periférico SPI en lugar de hacer el cambio de software. Nunca he utilizado un Arduino, pero la referencia en línea sugiere que hay un biblioteca SPI que puede utilizar. Si eso no se ajusta a sus necesidades, puede buscar el periférico SPI en la hoja de datos de ATMega. Los periféricos SPI suelen ser bastante fáciles de configurar y usar.

    
respondido por el markrages
1

Soy de la vieja escuela, he estado codificando desde procesadores de 100 kHz. Use el código en línea para la manipulación de bits directamente al puerto, en lugar de un bucle. Loop requiere gastos generales, la línea es más rápida aunque requiere más espacio en el programa. Consulte AVR035: Codificación C eficiente para AVR para la manipulación de bits de los puertos.

    
respondido por el tomL

Lea otras preguntas en las etiquetas

Comentarios Recientes

mcclain 102 214 2911 https://plasticspin.blogspot.co.uk/2018/07/the-simplest-way-to-trim-en.html Aunque las reglas (se desplazan 16 bits más rápidos) son importantes, la realidad es que todo lo que necesita hacer es necesitar un poco de PCM. Y poner valores de 16 bits en este formato es bastante fácil y un poco más elegante que hacerlo en el formato mucho más fácil: 26Bit% 46Light% 68% 16Bit% 561212% 000048% 16Bit% 3567325% 4 2BITS -------- -------------------------------------------------- - Película rápida... Lees verder