Sommario:

Quindi, carichi il bootloader STM32duino nella tua "Pillola blu" E adesso?: 7 passaggi
Quindi, carichi il bootloader STM32duino nella tua "Pillola blu" E adesso?: 7 passaggi

Video: Quindi, carichi il bootloader STM32duino nella tua "Pillola blu" E adesso?: 7 passaggi

Video: Quindi, carichi il bootloader STM32duino nella tua
Video: Всё про прошивку Xiaomi 2024, Dicembre
Anonim
Quindi, carichi STM32duino Bootloader nel tuo
Quindi, carichi STM32duino Bootloader nel tuo
Quindi, carichi STM32duino Bootloader nel tuo
Quindi, carichi STM32duino Bootloader nel tuo

Se hai già letto le mie istruzioni che spiegano come caricare il bootloader STM32duino o qualsiasi altra documentazione simile, prova a caricare l'esempio del codice e … potrebbe non succedere nulla.

Il problema è che molti, se non tutti, gli esempi per STM32 "generico" non funzioneranno immediatamente. Saranno necessarie piccole modifiche per far funzionare la tua scheda STM32 "Blue Pill".

Selezionerò 4 esempi di codice per spiegare cosa deve cambiare e perché. I codici sono: "BlinkWithoutDelay", "Fading", "Dimmer" e "AnalogInSerial".

Nota che NON ho codificato nulla. Emetto solo piccole modifiche ai codici creati da:

David A. Mellis e successivamente modificato da Tom Igoe, Marti Bolivar e alcuni casi da Scott Fitzgerald

Tom Igoe e successivamente modificato da Bryan Newbold

Quindi, preferisco mantenere i nomi degli autori anche nei codici che modifico, mantenendo il credito di creazione.

Passaggio 1: Pin e Pin… Perché il codice non funziona?

Pin e Pin… Perché il codice non funziona?
Pin e Pin… Perché il codice non funziona?

Diamo un'occhiata al pin out di STM32 "Blue Pill". Nota i pin sono identificati come PA1 o PC2 …. qualcosa del genere.

Se dai un'occhiata, ad esempio, all'esempio di codice "BlinkWithoutDelay", il pin viene dichiarato come "33"… Perché?

Sospetto che sia perché il signor Marti Bolivar ha portato questo codice per la scheda MAPLE.

Penso che non fosse sua intenzione far sì che il codice fosse compatibile con le schede "Blue Pill".

I pin della mini scheda Maple e Maple sono dichiarati numericamente, come Arduino, sebbene utilizzino numeri come 33, 24 e alcuni come questo.

Ho detto che il codice non funziona? Errore mio. Il codice viene compilato senza errori e caricato correttamente su "Blue Pill", quindi, secondo me, funziona davvero, ma non ci aspettiamo che utilizzi un output GPIO. Potrebbe non essere nemmeno disponibile.

Quindi sono necessarie piccole modifiche al codice per farlo funzionare come previsto.

Passaggio 2: "definiamo" alcuni Pin…

andiamo
andiamo

È una buona pratica del codice dichiarare le risorse come variabili o costanti di facile identificazione o significato. Ti consentirà di codificare più facilmente e di risolvere i problemi.

Ho usato dichiarare i pin Arduino in questo modo:

const int ledPin =13;

…"

Se ti piaccio, forse ti starai chiedendo: "Come posso dichiarare pin con nomi come PC13???"

La risposta è: utilizzare l'istruzione C "#define".

Quindi, in base al pinout draw, PC13 è il pin che abbiamo a bordo del LED in "BluePill". Per usarlo dichiarerei così, subito dopo la definizione delle librerie (#include…) e prima di ogni altra cosa:

#define LedPin PC13

…"

Nota che NON c'è ";" terminazione di linea, NOR "=" assegnazione.

Confronta entrambi i codici. Uno è l'esempio originale caricato da IDE. Il secondo è quello che ho adattato per lavorare con "BluePill".

Consiglio vivamente di dichiarare tutti i pin che intendi utilizzare nel codice. Anche quelli che intendono utilizzare come input ADC (ne parleremo più avanti).

Questo ti semplificherà la vita.

Passaggio 3: PinMode()…Come utilizzerai i tuoi Pin…

Prima di continuare, cerchiamo di capire la funzione PinMode().

Come Arduino, i pin STM32 hanno molteplici funzioni. Il modo più semplice per selezionare l'uno o l'altro è utilizzare l'istruzione pinMode().

Arduino ha solo 3 modalità disponibili, INPUT, OUTPUT o INPUT_PULLUP.

STM32, d'altra parte, ha molti tipi di pinMode(). Loro sono:

USCITA -Uscita digitale di base: quando il pin è ALTO, la tensione è mantenuta a +3,3v (Vcc) e quando è BASSA, viene portata a massa

OUTPUT_OPEN_DRAIN -In modalità scarico aperto, il pin indica "basso" accettando il flusso di corrente a terra e "alto" fornendo una maggiore impedenza

INPUT_ANALOG -Questa è una modalità speciale per quando il pin verrà utilizzato per letture analogiche (non digitali). Consente di eseguire la conversione ADC sulla tensione al pin

INPUT_PULLUP -Lo stato del pin in questa modalità viene riportato allo stesso modo di INPUT, ma la tensione del pin viene "tirata su" delicatamente verso +3.3v

INPUT_PULLDOWN -Lo stato del pin in questa modalità viene riportato allo stesso modo di INPUT, ma la tensione del pin viene "tirata verso il basso" delicatamente verso 0v

INPUT_FLOATING - Sinonimo di INPUT

PWM -Questa è una modalità speciale per quando il pin verrà utilizzato per l'uscita PWM (un caso speciale di uscita digitale)

PWM_OPEN_DRAIN -Come PWM, tranne per il fatto che invece di cicli alternati di BASSO e ALTO, la tensione sul pin consiste in cicli alternati di BASSO e flottante (scollegato)

(nota: estratto da

Apro solo questa parentesi perché quando inizi a creare il tuo codice, fai attenzione a usare pinMode() corretto per le tue necessità.

Passaggio 4: AnalogWrite() Versus PwmWrite()… Uscita analogica in 2 gusti

AnalogWrite() contro PwmWrite()…uscita analogica in 2 gusti
AnalogWrite() contro PwmWrite()…uscita analogica in 2 gusti
AnalogWrite() contro PwmWrite()…uscita analogica in 2 gusti
AnalogWrite() contro PwmWrite()…uscita analogica in 2 gusti

Prima di utilizzare i pin GPIO "Blue Pill" è necessario dichiarare il suo comportamento, ovvero come funzionerà. Questo è esattamente ciò che fa la funzione pinMode().

Quindi, concentriamoci ora su come impostare correttamente un'uscita analogica. Può essere dichiarato sia come modalità OUTPUT che come modalità PWM.

Allo stesso modo, i valori analogici possono essere attribuiti a GPIO in 2 modi: analogWrite() o pwmWrite(), MA, analogWrite() FUNZIONERÀ solo se pinMode()= OUTPUT. D'altra parte, pwmWrite() FUNZIONERÀ solo se pinMode()=PWM.

Prendiamo PA0, per esempio: è un candidato per l'uscita analogica/pwm.

analogWrite(): questo dichiara in questo modo:

….

#define ledPin PA0

pinMode(ledPin, OUTPUT);

analogWrite(ledPin, < numero >);

……"

dove numero deve essere compreso tra 0 e 255, come Arduino. In realtà, è retrocompatibile con Arduino.

pwmWrite(): dichiara in questo modo:

#define ledPin PA0

pinMode(ledPin, PWM);

pwmWrite(ledPin, <numero.>);

…."

Dove il numero deve essere compreso tra 0~65535, una risoluzione molto più alta di Arduino.

Nelle immagini è possibile confrontare tra 2 codici. Puoi anche vedere il codice originale.

Passaggio 5: comunicazione seriale STM32

Comunicazione seriale STM32
Comunicazione seriale STM32

Vediamo come sono disposte le interfacce USART in STM32. Sì, interfacce al plurale…..

"Blue Pill" ha 3 USART (RX/TX 1~3) e, se si utilizza un bootloader che consente di utilizzare l'USB, non è collegato a nessuno di questi.

A seconda che tu stia utilizzando o meno USB, devi dichiarare la porta seriale in un modo o nell'altro nel tuo codice.

Caso 1: utilizzo dell'USB:

In questo modo, gli sketch vengono scaricati direttamente tramite USB. Non è necessario spostare il ponticello BOOT0 in posizione 1 e di nuovo in 0.

In questo caso, ogni volta che dichiari "Seriale" senza indice, significa comunicazione via USB.

Quindi, Serial1, significa TX/ RX 1 (Pin PA9 e PA10); Serial2, significa TX/ RX 2 (pin PA2 e PA3) e Serial 3 significa TX/ RX 3 (pin PA10 e PA11).

Questo è il modo in cui stiamo lavorando. Presenterò le modifiche negli esempi per questo modo di codificare.

Un'altra cosa: "Serial USB" non ha bisogno di essere inizializzato. In altre parole, "…Serial.begin(15200);" non è necessario.

È possibile chiamare qualsiasi funzione Serial (Serial.read(), Serial.write(), ecc.) senza alcuna inizializzazione.

Se per qualche motivo è presente nel codice, il compilatore lo ignorerà.

Caso 2: utilizzo dell'adattatore da seriale TTL a USB:

In questo modo, il bootloader non supporta la comunicazione USB STM32 nativa, quindi è necessario un adattatore da USB a seriale collegato a TX/RX 1 (pin PA9 e PA10) per caricare gli sketch.

In questo caso, ogni volta che "Seriale" senza indice è codice, significa TX/RX1 (porta utilizzata per caricare il codice). Quindi, Serial1 si riferisce a TX/ RX 2 (pin PA2 e PA3) e Serial2 si riferisce a TX/ RX 3 (pin PA10 e PA11). Nessun Serial3 disponibile.

Passaggio 6: passare un valore al microcontrollore

Passare un valore al microcontrollore
Passare un valore al microcontrollore

L'esempio dimmer è un modo semplice per mostrare come passare un valore al microcontrollore.

Si suppone di passare un valore da 0 a 255 per controllare la luminosità del LED.

NON funzionerà come previsto in Blue Pill a causa:

  1. Per utilizzare la funzione pwmWrite(), pinMode() DEVE essere dichiarato come modalità PWM.
  2. Non otterrai mai un numero intero di 3 cifre. La funzione Serial.read() acquisisce solo il contenuto del buffer, che è un "BYTE". se si digita "100" e si preme "invio", solo l'ultimo "0" verrà acquisito dal buffer. E il suo valore sarà "48" (valore ASCII decimale per "0"). Se si intende emettere il valore "100", è necessario digitare "d". Quindi, è corretto dire che convertirà un valore decimale di un simbolo ASCII in luminosità del LED, giusto??…. Beh, una sorta di…
  3. Problema, mappare i valori direttamente dalla funzione Serial.read() è un'azione di trucco. È quasi certo di ottenere valori inaspettati. Un approccio migliore è il contenuto del buffer di archiviazione in una variabile temporanea e THAN mapparlo.

Come spiegato prima nell'articolo 2, il codice che introduco modifiche consentirà di inserire un simbolo ASCII e questo controllerà la luminosità del LED in base al suo valore decimale ASCII … ad esempio, "spazio" è il valore 32 (in realtà è il carattere stampabile più basso che puoi inserire) e "}" è possibile quello più alto (valore 126). Gli altri caratteri non sono stampabili, quindi il terminale non capirà o è possibile un composto di caratteri (come "~" è un tasto morto nella mia tastiera e non funzionerà correttamente). Ciò significa che questo carattere composto, quando viene inserito nel terminale, invierà il carattere stesso e qualcos'altro. Di solito non stampabile. Ed è quest'ultimo che il codice catturerà. Inoltre, tieni presente che il tuo terminale, in questo caso, NON dovrebbe inviare né "Ritorno a capo" né "Avanti riga". È necessario prestare attenzione a questo per il corretto funzionamento del codice.

Se cadi è poco confuso, peggiora…..

Passaggio 7: e se volessi digitare tre cifre… o anche di più??

E se volessi digitare tre cifre… o anche di più??
E se volessi digitare tre cifre… o anche di più??

Ricevere più caratteri da una comunicazione seriale non è un compito semplice.

Il buffer seriale è una pila di caratteri FIFO byte. Ogni volta che la funzione Serial.read() viene chiamata, il primo carattere inviato viene rimosso dalla pila e memorizzato in qualche altro posto. Di solito una variabile char nel codice. Nota, dipende dall'hardware, di solito c'è un timeout per il modo in cui il buffer di registro può conservare le informazioni.

Se intendi inserire più di una cifra via seriale, dovrai "comporre" una stringa carattere per carattere, man mano che entrano nel buffer UART.

Ciò significa leggere in ciclo ogni carattere del buffer, archiviarlo in una variabile temporanea, caricarlo nella prima posizione di un array di stringhe, spostarsi nella posizione successiva e ricominciare da capo, finché… beh, dipende dall'applicazione. Ci sono 2 modi per terminare il ciclo:

  1. Usando un carattere "segno di fine", come "ritorno a capo" o "avanzamento riga". Non appena viene trovato il carattere "end Mark", il loop finisce.
  2. In alternativa, il numero di caratteri nella catena di stringhe può essere limitato, così come il numero di cicli interattivi. Quando raggiunge il limite, diciamo, 4, l'acquisizione di routine finisce da sola.

Diamo un'occhiata in un semplice esempio come farlo:

  • Imposta un carattere di "fine", come '\n' (questo significa carattere ASCII di avanzamento riga).
  • loop nel frattempo Serial.available() è vero
  • la memorizzazione di Serial.read() risulta in una variabile char temporanea. Ricorda: non appena Serial.read() "legge" effettivamente il buffer, è pulito e viene caricato il carattere successivo.
  • incrementa una variabile stringa con questo carattere
  • Se l'ultimo carattere è "end" esci dal ciclo.

Di solito, la routine per ottenere l'array di caratteri seriali assomiglia a un'immagine.

Era basato su un ampio adattamento del codice originale di Mr. David A. Mellis.

Sentiti libero di usarlo e testarlo. Ricorda: i valori DEVONO essere inseriti nel formato a 3 cifre.

Questo è tutto per ora. Non mi dilungherò in ulteriori dettagli sulla comunicazione seriale. È troppo complesso da trattare qui e merita proprio Intructables.

Spero che ti aiuti a usare esempi in Blue Pill e ti dia un po' di chiarezza sul codice corretto per questa piccola scheda.

Ci vediamo in giro in altro istruibile.

Consigliato: