Tabla de contenido:

Entonces, carga el cargador de arranque STM32duino en su "píldora azul" ¿Y ahora qué ?: 7 pasos
Entonces, carga el cargador de arranque STM32duino en su "píldora azul" ¿Y ahora qué ?: 7 pasos

Video: Entonces, carga el cargador de arranque STM32duino en su "píldora azul" ¿Y ahora qué ?: 7 pasos

Video: Entonces, carga el cargador de arranque STM32duino en su
Video: Mañana de sábado contestando preguntas 2024, Mes de julio
Anonim
Entonces, carga el cargador de arranque STM32duino en su
Entonces, carga el cargador de arranque STM32duino en su
Entonces, carga el cargador de arranque STM32duino en su
Entonces, carga el cargador de arranque STM32duino en su

Si ya leíste mis instrucciones que explican cómo cargar el gestor de arranque STM32duino o cualquier otra documentación similar, intenta cargar el ejemplo de código y … es posible que no suceda nada.

El problema es que muchos, si no todos los ejemplos de STM32 "genérico" no funcionarán de fábrica. Serán necesarios cambios menores para que funcionen en su tablero STM32 "Blue Pill".

Seleccionaré 4 ejemplos de código para explicar qué necesita cambiar y por qué. Los códigos son: "BlinkWithoutDelay", "Fading", "Dimmer" y "AnalogInSerial".

Tenga en cuenta que NO codifiqué nada. Solo publico cambios menores en los códigos creados por:

David A. Mellis y tardíamente modificado por Tom Igoe, Marti Bolivar y algunos casos por Scott Fitzgerald

Tom Igoe y modificado tardíamente por Bryan Newbold

Por lo tanto, prefiero mantener los nombres de los autores incluso en los códigos que modifico, manteniendo el crédito de creación.

Paso 1: Pines y pines … ¿Por qué el código no funciona?

Pines y pines … ¿Por qué el código no funciona?
Pines y pines … ¿Por qué el código no funciona?

Echemos un vistazo en el pin de STM32 "Blue Pill". Tenga en cuenta que los pines se identifican como PA1 o PC2 … algo así.

Si echa un vistazo, por ejemplo, en el ejemplo de código "BlinkWithoutDelay", el pin se declara como "33" … ¿Por qué?

Sospecho que es porque el Sr. Marti Bolivar portó este código para la placa MAPLE.

Creo que no era su intención permitir que el código fuera compatible con los tableros "Blue Pill".

Los pines de la mini placa Maple y Maple se declaran numéricamente, como Arduino, aunque usan números como 33, 24 y algunos como este.

¿Dije que el código no funcionaba? Mi error. El código se compila sin ningún error y se carga correctamente en "Blue Pill", por lo que, en mi opinión, está funcionando, pero usando una salida GPIO no lo esperamos. Puede que ni siquiera esté disponible.

Se necesitan tan pocos cambios en el código para que funcione como se esperaba.

Paso 2: "Definamos" algunos pines…

Vamos
Vamos

Es una buena práctica de código declarar los recursos como variables o constantes de fácil identificación o significado. Le permitirá codificar más fácilmente y solucionar problemas.

Usé declarar pines Arduino como este:

const int ledPin = 13;

…"

Si le agrado, tal vez se esté preguntando: "¿Cómo puedo declarar pines con nombres como PC13?"

La respuesta es: Utilice la instrucción C "#define".

Entonces, de acuerdo con el dibujo de pinout, PC13 es el pin que tenemos a bordo del LED en "BluePill". Para usarlo, declararía así, justo después de la definición de las bibliotecas (# incluir…) y antes que nada:

#define LedPin PC13

…"

Tenga en cuenta que NO hay ";" terminación de línea, asignación NOR "=".

Compare ambos códigos. Uno es el ejemplo original cargado desde IDE. El segundo es el que hice algunos ajustes para trabajar con "BluePill".

Recomiendo encarecidamente declarar todos los pines que pretenda utilizar en el código. Incluso aquellos que pretenden usar como entrada ADC (más sobre esto más adelante).

Esto le facilitará la vida.

Paso 3: PinMode () … Cómo utilizará sus pines …

Antes de continuar, entendamos la función PinMode ().

Al igual que Arduino, los pines STM32 tienen múltiples funciones. La forma más sencilla de seleccionar uno u otro es utilizando la instrucción pinMode ().

Arduino tiene solo 3 modos disponibles, INPUT, OUTPUT o INPUT_PULLUP.

STM32, por otro lado, tiene muchas variantes de pinMode (). Son:

SALIDA -Salida digital básica: cuando el pin está ALTO, el voltaje se mantiene en + 3.3v (Vcc) y cuando es BAJO, se baja a tierra

OUTPUT_OPEN_DRAIN -En el modo de drenaje abierto, el pin indica "bajo" al aceptar el flujo de corriente a tierra y "alto" al proporcionar una mayor impedancia

INPUT_ANALOG -Este es un modo especial para cuando el pin se usará para lecturas analógicas (no digitales). Permite que la conversión de ADC se realice en el voltaje en el pin

INPUT_PULLUP -El estado del pin en este modo se informa de la misma manera que con INPUT, pero el voltaje del pin se "eleva" suavemente hacia + 3.3v

INPUT_PULLDOWN -El estado del pin en este modo se informa de la misma manera que con INPUT, pero el voltaje del pin se "baja" suavemente hacia 0v

INPUT_FLOATING: sinónimo de INPUT

PWM: este es un modo especial para cuando el pin se utilizará para la salida PWM (un caso especial de salida digital)

PWM_OPEN_DRAIN -Como PWM, excepto que en lugar de alternar ciclos de BAJO y ALTO, el voltaje en el pin consiste en ciclos alternos de BAJO y flotante (desconectado)

(nota: extraído de

Acabo de abrir este paréntesis porque cuando comience a crear su propio código, tenga cuidado de usar el pinMode () correcto para sus necesidades.

Paso 4: AnalogWrite () versus PwmWrite ()… Salida analógica en 2 sabores

AnalogWrite () versus PwmWrite ()… Salida analógica en 2 sabores
AnalogWrite () versus PwmWrite ()… Salida analógica en 2 sabores
AnalogWrite () versus PwmWrite ()… Salida analógica en 2 sabores
AnalogWrite () versus PwmWrite ()… Salida analógica en 2 sabores

Antes de utilizar los pines GPIO "Blue Pill" es necesario declarar su comportamiento, es decir, cómo funcionará. Eso es exactamente lo que hace la función pinMode ().

Entonces, enfoquémonos ahora en cuán correcta es la configuración de una salida analógica. Puede declararse como modo SALIDA o modo PWM.

De la misma manera, los valores analógicos se pueden atribuir a GPIO de 2 maneras: analogWrite () o pwmWrite (), PERO, analogWrite () solo funcionará si pinMode () = OUTPUT. Por otro lado, pwmWrite () solo funcionará si pinMode () = PWM.

Tomemos PA0, por ejemplo: es un candidato de salida analógica / pwm.

analogWrite (): esto declara de esta manera:

….

#define ledPin PA0

pinMode (ledPin, SALIDA);

analogWrite (ledPin, <número>);

……"

donde el número debe estar entre 0 y 255, como Arduino. En realidad, es compatible con versiones anteriores de Arduino.

pwmWrite (): declare de esta manera:

#define ledPin PA0

pinMode (ledPin, PWM);

pwmWrite (ledPin, <número.>);

…."

Donde el número debe estar entre 0 ~ 65535, una resolución mucho más alta que Arduino.

En imágenes es posible comparar entre 2 códigos. También puede ver el código original.

Paso 5: Comunicación en serie STM32

Comunicación serial STM32
Comunicación serial STM32

Veamos cómo se organizan las interfaces USART en STM32. Sí, interfaces en plural…..

"Blue Pill" tiene 3 USART (RX / TX 1 ~ 3) y, si está usando un cargador de arranque que le permite usar USB, no está conectado a ninguno de ellos.

Dependiendo de que esté usando o no USB, debe declarar el puerto serie de una forma u otra en su código.

Caso 1: Uso de USB:

De esta forma, los bocetos se descargan directamente a través de USB. No es necesario mover el puente BOOT0 a 1 posición y volver a 0.

En este caso, cada vez que declare "Serie" sin índice, significa comunicación a través de USB.

Entonces, Serial1, significa TX / RX 1 (Pines PA9 y PA10); Serial2, significa TX / RX 2 (pines PA2 y PA3) y Serial 3 significa TX / RX 3 (pines PA10 y PA11).

Esta es la forma en que estamos trabajando. Presentaré cambios en ejemplos para esta forma de codificación.

Otra cosa: "Serial USB" no necesita inicializarse. En otras palabras, "… Serial.begin (15200);" no es necesario.

Es posible llamar a cualquier función serial (Serial.read (), Serial.write (), etc.) sin ninguna inicialización.

Si por alguna razón está presente en el código, el compilador lo ignorará.

Caso 2: Uso del adaptador TTL seria a USB:

De esta manera, el cargador de arranque no admite la comunicación USB STM32 nativa, por lo que necesita un adaptador USB a serie conectado a TX / RX 1 (pin PA9 y PA10) para cargar los bocetos.

En este caso, en cualquier momento "Serial" sin índice es código, significa TX / RX1 (puerto utilizado para cargar el código). Así sucesivamente, Serial1 se refiere a TX / RX 2 (pines PA2 y PA3) y Serial2 se refiere a TX / RX 3 (pines PA10 y PA11). No Serial3 disponible.

Paso 6: pasar un valor al microcontrolador

Pasando un valor al microcontrolador
Pasando un valor al microcontrolador

El ejemplo de atenuador es una forma sencilla de mostrar cómo pasar un valor al microcontrolador.

Se supone que debe pasar un valor de 0 a 255 para controlar el brillo del LED.

NO funcionará como se esperaba en Blue Pill debido a:

  1. Para usar la función pwmWrite (), pinMode () DEBE declararse como modo PWM.
  2. Nunca obtendrá un número completo de 3 dígitos. La función Serial.read () captura solo el contenido del búfer, que es un "BYTE". si escribe "100" y presiona "enter", solo se capturará el último "0" del búfer. Y su valor será "48" (valor ASCII decimal para "0"). Si pretende emitir valor "100", es necesario teclear "d". Entonces, es correcto decir que convertirá un valor decimal de símbolo ASCII en brillo de LED, ¿verdad ?? … Bueno, una especie de …
  3. Problema, asignar valores directamente desde la función Serial.read () es una acción engañosa. Es casi seguro que se obtengan valores inesperados. Un mejor enfoque es el contenido del búfer de almacenamiento en una variable temporal y QUE mapearlo.

Como expliqué antes en el elemento 2, el código que introduzco cambios permitirá ingresar un símbolo ASCII y esto controlará el brillo del LED en función de su valor decimal ASCII … por ejemplo, "espacio" es el valor 32 (en realidad es el carácter imprimible más bajo que puede ingresar) y "}" es posible el más alto (valor 126). Otros caracteres no son imprimibles, por lo que el terminal no los entenderá o es posible que sean compuestos de caracteres (como "~" es una tecla muerta en mi teclado y no funcionará correctamente). Esto significa que este carácter compuesto, cuando ingresa en la terminal, enviará el propio carácter y algo más. Generalmente uno no imprimible. Y es que este último código capturará. Además, tenga en cuenta que su Terminal, en este caso, NO debe enviar ni "Carriage Return" ni "Line Feed". Debe prestar atención a esto para que el código funcione correctamente.

Si te caes es un poco confuso, se pone peor…..

Paso 7: Y si quisiera escribir tres dígitos…. o incluso más?

Y si quisiera escribir tres dígitos…. o incluso más?
Y si quisiera escribir tres dígitos…. o incluso más?

Recibir varios caracteres de una comunicación en serie no es una tarea sencilla.

El búfer de serie es una pila de caracteres FIFO de bytes. Cada vez que se llama a la función Serial.read (), el primer carácter enviado se elimina de la pila y se almacena en algún otro lugar. Por lo general, una variable char en el código. Tenga en cuenta que, dependiendo del hardware, normalmente hay un tiempo de espera para la forma en que el búfer de registro puede conservar la información.

Si tiene la intención de ingresar más de un dígito vía serial, deberá "componer" una cadena carácter por carácter, a medida que ingresan al búfer UART.

Esto significa leer cíclicamente cada carácter del búfer, almacenar en una variable temporal, cargarlo en la primera posición de una matriz de cadenas, pasar a la siguiente posición y empezar de nuevo, hasta que… bueno, depende de la aplicación. Hay 2 formas de finalizar el ciclo:

  1. Utilizando algún carácter de "marca de fin", como "Retorno de carro" o "Salto de línea". Tan pronto como se encuentra el carácter "end Mark", el bucle termina.
  2. Alternativamente, el número de caracteres en la cadena de cadenas puede ser limitado, por lo tanto, el número de ciclos interactivos. Cuando llega al límite, digamos 4, adquiere acabados rutinarios por sí mismo.

Echemos un vistazo a un ejemplo simple de cómo hacer esto:

  • Establezca un carácter "final", como '\ n' (esto significa carácter ASCII de salto de línea).
  • bucle mientras tanto Serial.available () es verdadero
  • almacenar Serial.read () da como resultado una variable char temporal. Recuerde: tan pronto Serial.read () realmente "lee" el búfer, está limpio y el siguiente carácter se carga en él.
  • incrementar una variable de cadena con este carácter
  • Si el último carácter es "fin", salga del bucle.

Por lo general, la rutina para obtener una matriz de caracteres en serie se parece a la imagen.

Se basó en una extensa adaptación del código original del Sr. David A. Mellis.

Siéntase libre de usarlo y probarlo. Recuerde: los valores DEBEN ingresarse en formato de 3 dígitos.

Esto es por ahora. No me extenderé en detalles adicionales de comunicación serial. Es demasiado complejo para cubrirlo aquí y se merece sus propios Intructables.

Espero que te ayude a usar ejemplos en Blue Pill y te ayude a aclarar cómo es el código correcto para este pequeño tablero.

Nos vemos en otro instructable.

Recomendado: