La popularidad de Placa Raspberry Pico con tecnología microcontrolador RP2040 ha hecho que todos los lectores quieran saber más sobre la placa y el chip. Así que hoy hablaremos de las E/S programables del RP2040, una característica que lo hace diferente de la mayoría de las otras placas de microcontroladores.
Los dos bloques PIO o llamémoslos interfaces de hardware en el RP2040 tienen cuatro máquinas de estado cada uno. Estos dos bloques PIO pueden ejecutar simultáneamente programas para manipular GPIO y transferir datos sin procesar. Ahora bien, ¿qué hacen estas máquinas de estado? Bueno, las máquinas de estado PIO ejecutan los programas obtenidos de varias fuentes. A veces, los programas se toman de la biblioteca PIO (UART, SPI o I2C) o del software del usuario.
¿Por qué E/S programable?
Todas las placas generalmente vienen con soporte de hardware para protocolos de comunicaciones digitales como I2C, SPI y UART. Sin embargo, si planea usar más de estas interfaces de las que están disponibles en la placa, puede usar las E / S programables provistas en el microcontrolador RP2040.
Bueno, esto tiene más capacidades de las que uno pueda imaginar. Supongamos que desea generar un video DPI o «comunicarse con un dispositivo en serie que se encuentra en AliExpress» ahora es posible con E/S programable. Como dice el nombre, IO ‘programable’ deja en claro que se puede programar directamente para admitir varias interfaces, incluida la interfaz de tarjeta SD, salida VGA y transferencia de datos de mayor velocidad. ¡Aférrate! Tenemos la parte más emocionante del artículo: «Cómo programar estas E / S programables para facilitar su trabajo».
¿Cómo empiezo con la programación PIO del RP2040?
El Pico SDK (Software Development Kit) proporciona los encabezados, las bibliotecas y el sistema de compilación necesarios para escribir programas para dispositivos basados en RP2040, como Raspberry Pi Pico en lenguaje ensamblador C, C ++ o Arm
Si planea usar Python para codificar, solo necesita un editor adecuado (digamos Thonny) y MicroPython instalado en la placa de desarrollo. Pero en el caso de C / C ++, necesita un archivo CMake que le diga al Pico SDK cómo convertir el archivo C en una aplicación binaria para una placa de microcontrolador basada en RP2040, como se explica en nuestro reciente Tutorial de MicroPython y C para Raspberry Pi Pico .
El PIO Assembler analiza un archivo fuente PIO y genera la versión ensamblada lista para su inclusión en una aplicación RP2040. Esto incluye las aplicaciones C y C ++ creadas con el SDK de Pico y los programas de Python que se ejecutan en el puerto RP2040 MicroPython.
Para comenzar a programar la máquina de estado para su aplicación PIO, hay tres componentes para el programa basado en C / C ++.
- Un programa PIO
- Software basado en lenguaje C para ejecutar el programa
- Un archivo CMake que describe cómo estos dos se combinan en una imagen de programa para cargar en una placa de desarrollo basada en RP2040.
Instrucciones de montaje de PIO
Ahora, cuando se trata de programar estas interfaces IO, hay nueve instrucciones de ensamblaje «JMP, WAIT, IN, OUT, PUSH, PULL, MOV, IRQ y SET». Aunque la mayoría de la gente puede estar interesada en programar las interfaces PIO con lenguaje C / C ++ o Python, echemos un vistazo a algunas de las instrucciones del lenguaje ensamblador utilizadas para las interfaces IO.
- JMP: esta instrucción de ‘salto’ puede ser una instrucción condicional o no condicional. En esto, transfiere el flujo de ejecución cambiando el registro de puntero de instrucción. En palabras simples, con la declaración ‘jmp’ el flujo de ejecución va a otra parte del código.
- WAIT: Esta instrucción detiene la ejecución del código. Cada instrucción toma un ciclo a menos que se detenga (usando las instrucciones WAIT).
- OUT: Esta instrucción cambia los datos del registro de desplazamiento de salida a otros destinos, 1 … 32 bits a la vez.
- PULL: Esta instrucción muestra palabras de 32 bits de TX FIFO en el registro de desplazamiento de salida.
- IN: Esta instrucción cambia 1 … 32 bits a la vez en el registro.
- PUSH: esta instrucción para escribir el contenido de ISR en el RX FIFO.
Más información sobre las instrucciones en lenguaje ensamblador está disponiblecapaz en la hoja de datos RP2040 .
Ejemplo de programación RP2040 PIO en C / C ++ y MicroPython
Para hacerlo más fácil, examinaremos el programa de hello_world que parpadea el LED integrado utilizando los IO programables y los datos de 32 bits de TX FIFO (instrucciones PULL).
El programa en C / C ++ se parece a esto:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# include "pico / stdlib.h" #include "hardware / pio.h" // Nuestro programa ensamblado: #include "hello.pio.h" int main () { // Elija qué instancia de PIO usar (hay dos instancias) PIO pio = pio0; // Nuestro programa ensamblado debe cargarse en la instrucción de este PIO // memoria. Esta función SDK encontrará una ubicación (desplazamiento) en el // memoria de instrucciones donde hay suficiente espacio para nuestro programa. Nosotros necesitamos // ¡para recordar esta ubicación! uint offset = pio_add_program (pio, & amp;hello_program); // Encuentra una máquina de estado libre en nuestro PIO elegido (error si hay // ninguna). Configúrelo para ejecutar nuestro programa, e inícielo, usando el // función auxiliar que incluimos en nuestro archivo .pio. uint sm = pio_claim_unused_sm (pio, true); hello_program_init (pio, sm, offset, PICO_DEFAULT_LED_PIN); // La máquina de estado ahora está funcionando. Cualquier valor que empujemos a su TX FIFO será // aparece en el pin LED. while (true) { // Parpadeo pio_sm_put_blocking (pio, sm, 1); sleep_ms (500); // Rubio pio_sm_put_blocking (pio, sm, 0); sleep_ms (500); } } |
El código C/C ++ anterior hace parpadear el LED con un ciclo completo de 1 segundo. El LED está programado de tal manera que estará encendido durante 500 ms seguido de apagado durante 500 ms. Pero, antes de que las máquinas de estado puedan ejecutar el programa, necesitamos cargar el programa en esta memoria de instrucciones. «La función pio_add_program () encuentra espacio libre para nuestro programa en la memoria de instrucciones de un PIO dado y lo carga». Con esto, configuramos la máquina de estado para enviar sus datos al LED integrado.
El código ensamblador para el archivo .pio que se muestra a continuación tiene todas las funciones auxiliares de C para configurar el código C / C ++.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
. program hella loop: pull out pins, 1 jmp loop % c-sdk { static inline void hello_program_init (PIO pio, uint sm, uint offset, uint pin) { pio_sm_config c = hello_program_get_default_config (offset); // Asigna el grupo de pines OUT de la máquina de estado a un pin, es decir, el `pin` // parámetro de esta función. sm_config_set_out_pins (&c, pin, 1); // Configura la función GPIO de este pin (conecta PIO al pad) pio_gpio_init (pio, pin); // Establece la dirección del pin para la salida en el PIO pio_sm_set_consecutive_pindirs (pio, sm, pin, 1, true); // Carga nuestra configuración y salta al inicio del programa pio_sm_init (pio, sm, offset, &c); // Establecer la máquina de estado en funcionamiento pio_sm_set_enabled (pio, sm, true); } %} |
Aparte de estos, también necesita un archivo CMake que describa cómo los archivos .pio y .c se integran en un binario adecuado para cargar en su placa de desarrollo Raspberry Pi Pico.
No hay una muestra equivalente escrita con MicroPython, pero podemos ver un código PIO MicroPython más simple utilizado para hacer parpadear el LED integrado:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
tiempo de importación desde rp2 import PIO, asm_pio del Pin de importación de la máquina # Defina el programa de parpadeo. Tiene un GPIO para enlazar en la instrucción establecida, que es un pin de salida. # Utilice muchos retrasos para que el parpadeo sea visible a simple vista. @asm_pio (set_init = rp2.PIO.OUT_LOW) def blink (): wrap_target () set (pin, 1) [31] nop () [31] nop () [31] nop () [31] nop () [31] set (pin, 0) [31] nop () [31] nop () [31] nop () [31] nop () [31] wrap() # Cree una instancia de una máquina de estado con el programa de parpadeo, a 1000Hz, con el conjunto vinculado al Pin (25) (LED en la placa rp2) sm = rp2.StateMachine (0, blink, freq=1000, set_base=Pin(25)) # Ejecute la máquina de estado durante 3 segundos. El LED debería parpadear. sm.active(1) time.sleep(3) sm.active (0) |
En este caso, no hay un archivo .pio separado, y tanto MicroPython como el código ensamblador se colocan en el archivo .py.
Tenga en cuenta que a pesar de que PIO se puede programar con MicroPython, la documentación del SDK de Python dice que actualmente es inestable / trabajo en progreso, por lo que se recomienda C/C ++.
Puede haber muchas modificaciones en el código agregando el color que desea mostrar con la ayuda del formato hexadecimal en RGB. Sin embargo, hay muchos ejemplos de la vida real como PWM, UART o incluso interactuar con NeoPixels. Para aquellos interesados, pueden encontrar muchos ejemplos de programación PIO en los repositorios de GitHub para C y Muestras de MicroPython .
Conclusión
Las E/S programables RP2040 tienen la capacidad de ejecutar programas simultáneamente para admitir interfaces como salida VGA y transferencia de datos a mayor velocidad. Puede consultar el Capítulo 3 en la documentación del SDK para C/C ++ y Python para obtener más información sobre las E/S programables RP2040.
Traducido del artículo en inglés A closer look at Raspberry Pi RP2040 Programmable IOs (PIO)
Publicaciones traducidas automáticamente
3 respuestas a «Una mirada más cercana a Raspberry Pi RP2040 E/S Programmable (PIO)»